Developer & API Guide

Complete integration reference for OMNYTH Payment Hub. Covers authentication, all REST endpoints, request/response examples, webhooks, error handling, and the Experience API layer.

Base URL: https://api.omnyth.com/api/v1
All requests require a bearer token unless noted. All dates are ISO 8601 UTC. All amounts are decimal strings to avoid floating-point drift.

Authentication

OMNYTH uses OAuth 2.0 client credentials flow (Keycloak). Obtain a token by posting to the token endpoint with your client_id and client_secret.

POST /realms/omnyth/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=your-client-id
&client_secret=your-client-secret
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Include the token as Authorization: Bearer <token> on every subsequent request. Tokens expire after 3600 seconds by default. Your integration should refresh before expiry.

For local development environments where Keycloak is not configured, authentication is bypassed. All requests are accepted without a token in local profile.

Integration Lifecycle

  1. Create a Consumer — register your application as a Consumer in the Developer Portal. Choose type: BANK, FINTECH, CORPORATE, or MARKETPLACE.
  2. Generate an API Key — from the Portal, generate a key scoped to the products you subscribe to.
  3. Subscribe to a Product — each product exposes an Experience API endpoint. Subscribe to activate access.
  4. Configure your Flow — platform operators create and publish flows for your payment types. You don't configure flows; you select the right payment type in your request.
  5. Test with Simulation — use the /experience/{slug}/simulate endpoint to test flow execution without submitting real transactions.
  6. Go Live — switch to production credentials. Use production consumer_id.

Experience API

The Experience API is the primary integration point. It wraps internal flow complexity behind a clean, product-specific interface. Each product exposes its own slug endpoint.

Operators configure Experience APIs in the platform (Experience Library). The API definition specifies which fields are exposed, which are masked, and what validation applies — without requiring code changes.

Execute a Payment

POST /experience/{slug}/execute
Authorization: Bearer <token>
X-Consumer-Id: your-consumer-id
Content-Type: application/json
{
  "payment_type": "DOMESTIC_TRANSFER",
  "source_country": "JO",
  "currency": "JOD",
  "amount": "500.00",
  "debtor": {
    "account_number": "12345678",
    "bank_code": "BOJOJO"
  },
  "creditor": {
    "account_number": "87654321",
    "bank_code": "ARABJO"
  },
  "reference": "INV-2026-001",
  "metadata": {
    "customer_ref": "CUST-991"
  }
}
{
  "payment_id": "PAY-20260604-00001",
  "status": "RECEIVED",
  "created_at": "2026-06-04T10:00:00Z",
  "reference": "INV-2026-001"
}

Simulate a Payment

POST /experience/{slug}/simulate
Authorization: Bearer <token>

Same request body as execute. Returns simulated flow execution with step-by-step trace. No real funds move. Use for integration testing and flow validation.

{
  "simulation_id": "SIM-001",
  "status": "COMPLETED",
  "steps": [
    { "step_type": "VALIDATION", "result": "PASS", "duration_ms": 12 },
    { "step_type": "SCREENING", "result": "CLEAR", "duration_ms": 45 },
    { "step_type": "ROUTING_DECISION", "result": "ACH", "duration_ms": 8 },
    { "step_type": "GATEWAY_SUBMISSION", "result": "ACCEPTED", "duration_ms": 234 }
  ]
}

Get Experience API Documentation

GET /experience/{slug}/documentation

Returns the auto-generated OpenAPI spec and Postman collection for this product.

Payments API

Create a Payment

POST /payments
Authorization: Bearer <token>

Creates a payment in RECEIVED state. Does not start processing.

Submit a Payment

POST /payments/{id}/submit

Triggers flow execution. Payment moves from RECEIVED to PROCESSING.

Get Payment Status

GET /payments/{id}
{
  "payment_id": "PAY-20260604-00001",
  "status": "COMPLETED",
  "payment_type": "DOMESTIC_TRANSFER",
  "amount": "500.00",
  "currency": "JOD",
  "rail": "ACH",
  "created_at": "2026-06-04T10:00:00Z",
  "completed_at": "2026-06-04T10:00:04Z",
  "reference": "INV-2026-001"
}

List Payments

GET /payments?status=COMPLETED&payment_type=DOMESTIC_TRANSFER&page=0&size=20

Returns newest-first. Supports filtering by status, payment_type, rail, date_from, date_to.

Payment Status Values

StatusMeaning
RECEIVEDCreated, not yet submitted
PROCESSINGFlow execution in progress
PENDING_APPROVALAwaiting human approval (APPROVAL_WORKFLOW step)
PENDING_REPAIRFailed, queued for auto repair
COMPLETEDSuccessfully settled
FAILEDTerminal failure, not retryable
REVERSEDPayment reversed after settlement

Approvals API

List Pending Approvals

GET /approvals?status=PENDING

Approve or Reject

POST /approvals/{id}/approve
POST /approvals/{id}/reject
{
  "comment": "Approved per policy CFO-2026-04"
}

Reconciliation API

Reconciliation matches internal payment records against external statements.

Start a Reconciliation Session

POST /reconciliation/sessions
{
  "session_name": "June 12 EOD",
  "recon_date": "2026-06-12",
  "source": "INTERNAL"
}

List Recon Items

GET /reconciliation/sessions/{id}/items?status=UNMATCHED

Resolve an Item

POST /reconciliation/items/{id}/resolve
{
  "resolution": "MANUAL_MATCH",
  "notes": "Matched to statement line 42"
}

Settlement API

List Settlement Batches

GET /settlement/batches?status=PENDING

Get Batch Detail

GET /settlement/batches/{id}
GET /settlement/batches/{id}/items

Confirm a Batch

POST /settlement/batches/{id}/confirm

Compliance API

The Compliance Console surfaces cases generated by the Fraud Detection and Sanctions Screening observers. Cases are created automatically during payment processing.

List Compliance Cases

GET /compliance/cases?type=FRAUD&status=OPEN

Filter by type: FRAUD, SANCTIONS, AML. Filter by status: OPEN, UNDER_REVIEW, RESOLVED, ESCALATED.

Get a Case

GET /compliance/cases/{id}
{
  "case_id": "CASE-001",
  "case_type": "FRAUD",
  "payment_id": "PAY-20260612-00042",
  "risk_score": 87,
  "alert_reason": "Velocity threshold exceeded",
  "status": "OPEN",
  "created_at": "2026-06-12T09:15:00Z",
  "assigned_to": null
}

Update Case Status

POST /compliance/cases/{id}/review
{
  "action": "ESCALATE",
  "notes": "Referred to senior compliance officer"
}

Actions: REVIEW, RESOLVE, ESCALATE, CLEAR.

Compliance Dashboard

GET /compliance/dashboard
{
  "open_fraud_cases": 3,
  "open_sanctions_hits": 1,
  "resolved_today": 7,
  "avg_resolution_hours": 2.4,
  "high_risk_payments_today": 12
}

ISO 20022 Messaging API

The Messaging Engine transforms payments to and from ISO 20022 XML formats. Schemas, transformation profiles, and type mappings are all configurable.

List Message Schemas

GET /messaging/schemas

Validate a Message

POST /messaging/validate
Content-Type: application/xml

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
  ...
</Document>
{
  "valid": true,
  "schema": "pain.001.001.09",
  "errors": []
}

Transform a Message

POST /messaging/transform
{
  "source_format": "INTERNAL",
  "target_format": "pain.001.001.09",
  "payment_id": "PAY-20260612-00001"
}

Send a Test Message

POST /messaging/test
{
  "schema_code": "pain.001",
  "message_xml": "..."
}

Treasury & Liquidity API

List Nostro Accounts

GET /liquidity/nostro-accounts

Get Account Balance

GET /liquidity/nostro-accounts/{id}/balance
{
  "account_id": "NOSTRO-SWIFT-JOD",
  "currency": "JOD",
  "current_balance": "2500000.00",
  "available_balance": "2200000.00",
  "threshold_low": "500000.00",
  "threshold_high": "5000000.00"
}

Intraday Liquidity Report

GET /liquidity/intraday?date=2026-06-12

Funding Instructions

POST /liquidity/funding-instructions
{
  "nostro_account_id": "NOSTRO-SWIFT-JOD",
  "amount": "1000000.00",
  "value_date": "2026-06-13"
}

CAMT Statement Ingest API

Upload ISO 20022 CAMT.053 (end-of-day) or CAMT.054 (credit/debit notification) statements. OMNYTH parses and seeds reconciliation items automatically.

Upload a Statement

POST /camt/upload
Content-Type: multipart/form-data

file: <camt053.xml>
account_id: NOSTRO-SWIFT-JOD
{
  "ingestion_id": "CAMT-2026-001",
  "statement_type": "CAMT053",
  "transactions_parsed": 142,
  "recon_items_created": 142,
  "status": "PROCESSED"
}

List Ingested Statements

GET /camt/statements?account_id=NOSTRO-SWIFT-JOD&date=2026-06-12

Get Statement Detail

GET /camt/statements/{id}

Auto Repair API

The Auto Repair Engine automatically detects and attempts to fix failed payments. You can query the repair queue and trigger manual repair runs.

List Repair Queue

GET /repair/queue?status=PENDING

Get Repair Item

GET /repair/queue/{id}
{
  "repair_id": "RPR-001",
  "payment_id": "PAY-20260612-00033",
  "failure_pattern": "TIMEOUT",
  "playbook": "RETRY_WITH_BACKOFF",
  "attempt_count": 2,
  "next_attempt_at": "2026-06-12T10:30:00Z",
  "status": "PENDING"
}

Trigger Manual Repair

POST /repair/queue/{id}/trigger

Repair Playbooks

GET /repair/playbooks

Monitoring & Metrics API

Payment Metrics

GET /metrics/payments?from=2026-06-12T00:00:00Z&to=2026-06-12T23:59:59Z
{
  "total": 1842,
  "completed": 1820,
  "failed": 14,
  "pending": 8,
  "success_rate": 0.9924,
  "avg_processing_ms": 340
}

SLA Status

GET /metrics/sla

Active Alerts

GET /metrics/alerts?severity=HIGH&status=ACTIVE

Webhooks

Register webhook endpoints to receive real-time payment state change notifications. Webhooks are configured per Consumer in the Developer Portal.

Register a Webhook

POST /portal/webhooks
{
  "endpoint_url": "https://your-app.example.com/omnyth-webhooks",
  "secret": "your-hmac-secret",
  "events": ["PAYMENT_COMPLETED", "PAYMENT_FAILED", "APPROVAL_REQUIRED"]
}

Webhook Payload

POST https://your-app.example.com/omnyth-webhooks
X-OMNYTH-Signature: sha256=<hmac>
Content-Type: application/json

{
  "event": "PAYMENT_COMPLETED",
  "payment_id": "PAY-20260612-00001",
  "status": "COMPLETED",
  "timestamp": "2026-06-12T10:05:00Z",
  "metadata": {}
}

Verify Webhook Signatures

Compute HMAC-SHA256 over the raw request body using your webhook secret. Compare to the X-OMNYTH-Signature header value after the sha256= prefix.

// Node.js example
const crypto = require('crypto');
const sig = crypto
  .createHmac('sha256', webhookSecret)
  .update(rawBody)
  .digest('hex');
if (sig !== receivedSig) throw new Error('Invalid signature');

Webhook Event Types

EventTriggered when
PAYMENT_RECEIVEDPayment created
PAYMENT_PROCESSINGFlow execution started
PAYMENT_COMPLETEDPayment settled successfully
PAYMENT_FAILEDPayment failed (terminal)
APPROVAL_REQUIREDPayment paused at approval step
APPROVAL_COMPLETEDApproval decision made
REPAIR_TRIGGEREDAuto repair started
COMPLIANCE_ALERTFraud or sanctions case opened
STATEMENT_INGESTEDCAMT statement processed

Error Model

All errors follow a consistent envelope:

{
  "error": "VALIDATION_FAILED",
  "message": "Amount exceeds daily limit for payment type DOMESTIC_TRANSFER",
  "payment_id": "PAY-20260612-00099",
  "status": "FAILED",
  "timestamp": "2026-06-12T10:05:00Z"
}
Error CodeHTTPMeaningRetryable
VALIDATION_FAILED400Request field validation errorNo
LIMIT_EXCEEDED400Amount or count exceeds limitNo
SCREENING_BLOCKED403Sanctions screening blocked paymentNo
FRAUD_BLOCKED403Fraud detection blocked paymentNo
ROUTING_FAILED422No matching route foundMaybe
PROVIDER_ERROR502Provider transient errorYes
PROVIDER_DECLINED422Provider declined the transactionNo
NO_ACTIVE_FLOW422No published flow for payment typeNo
UNAUTHORIZED401Invalid or expired tokenAfter re-auth
FORBIDDEN403Consumer not subscribed to productNo

Rate Limits

Consumer TypeRequests / minuteConcurrent executions
BANK10,000500
FINTECH2,000100
CORPORATE50050
MARKETPLACE5,000200

Rate limit headers are returned on every response: X-RateLimit-Limit,X-RateLimit-Remaining, X-RateLimit-Reset. When exceeded, the API returns HTTP 429 with a Retry-After header.

Idempotency

Submit a unique Idempotency-Key header on all POST requests to safely retry without creating duplicate payments. The key must be unique per request and is scoped to your consumer. The same key returns the original response for 24 hours.

POST /payments
Idempotency-Key: INV-2026-001-retry-1

Security Concepts

OMNYTH supports field-level encryption, payload signing, and HMAC verification — all configurable via security policies in the platform without code changes.

  • Encryption — AES-GCM or AES-CBC encryption for specific fields or full payloads. Keys are managed via keystores or HSM references (never stored in database).
  • Signing — JWS RS256 signatures on outbound provider requests, verifiable by providers using the published public key.
  • HMAC — HMAC-SHA256 integrity verification on inbound webhooks and callbacks.
  • IP Allowlisting — restrict consumer API calls to a set of known source IP ranges.
  • Output Masking — sensitive fields (account numbers, national IDs) are masked in API responses per security policy configuration.

API Keys (Developer Portal)

For consumer self-service integrations, API keys are an alternative to OAuth2 tokens. Generate a key from the Portal dashboard. Include it as:

X-API-Key: your-portal-api-key

API keys are scoped to the products you are subscribed to and respect your consumer's rate limits. Rotate keys from the Portal without downtime — old key remains valid for 60 seconds after rotation.