Webhooks#
Webhooks let Sokin push real-time notifications to your systems when events happen in your account — an instruction is created, a payment settles, funds arrive at a Corporate Currency Account, and so on. Instead of polling our API, you register a URL and we POST to it as things happen.Webhooks are the recommended way to track the lifecycle of payments and corporate status changes.How delivery works#
When a subscribed event occurs, Sokin sends an HTTP POST to the URL you registered. The request looks like this:POST https://your-app.example.com/webhooks/sokin
Content-Type: application/json
User-Agent: WebhookConductor/1.0
X-Idempotency-Key: 3f1a9b2c-88ae-4e1b-9a0a-2a7c2e8b4f90
x-api-key: <your auth key, if configured>
{
"notificationType": "instruction.instructions.processed",
...
}
Authentication#
When you create a subscription, you may supply an authKey. If set, Sokin includes it on every delivery as the x-api-key header. Your receiver should reject any request that doesn't present the expected value.If you don't set an authKey, the header is omitted. We recommend always configuring one.Idempotency#
Every delivery carries a unique X-Idempotency-Key header. If your endpoint returns a non-2xx response, Sokin retries the same key — so your receiver should treat the key as a dedupe token and ignore duplicate deliveries of the same key.Retries#
If your endpoint returns anything outside the 2xx range, or the request times out, Sokin retries. Two parameters on the subscription control the behaviour:| Field | Default | Range | Meaning |
|---|
maxRetries | 3 | 0–10 | Number of retry attempts after the initial send |
retryDelayMinutes | 5 | 1–60 | Delay between attempts |
A notification that exhausts all retries is marked failed and no further delivery is attempted automatically. You can inspect delivery history and manually retry via the Webhook API (see API reference).Ordering#
Deliveries are not guaranteed to arrive in the order events happened. Use the fields in each payload (externalReference, timestamps on the underlying resource) to reconcile state rather than relying on arrival order.Managing subscriptions#
Subscriptions are managed through the Webhook API:POST /webhooks/subscriptions — create
GET /webhooks/subscriptions?subscriptionId=... — read
PUT /webhooks/subscriptions?subscriptionId=... — update (the eventTypes array is a full replacement — events not present are unsubscribed)
PATCH /webhooks/subscriptions/status?subscriptionId=... — enable/disable
DELETE /webhooks/subscriptions?subscriptionId=... — delete
See the API reference for the request/response schemas.Available events#
| Event type | Fires when |
|---|
corporate.status.activated | A corporate is activated and ready to transact |
instruction.instruction-requests.rejected | An instruction request is rejected before becoming an instruction |
instruction.instructions.created | A new instruction is created from a valid instruction request |
instruction.instructions.processed | An instruction has been fully processed and funds have been dispatched |
instruction.instructions.failed | An instruction has failed |
accounting.corporateCurrencyAccount.funded | Funds have arrived into a Corporate Currency Account |
Payload envelope#
Every webhook body is JSON and always includes a notificationType field identifying the event. Beyond that, each event type has its own fields (documented below). Unknown fields may be added in the future — treat payloads as forward-compatible and ignore fields you don't recognise.Payload reference#
corporate.status.activated#
Dispatched when a corporate moves into the active state.{
"notificationType": "corporate.status.activated",
"corporateExternalReference": "corp_abc123",
"resellerExternalReference": "res_xyz789",
"activatedBy": "user_operator_42",
"activatedAt": "2026-04-21T10:15:30.123456+00:00"
}
| Field | Type | Description |
|---|
corporateExternalReference | string | External reference of the activated corporate |
resellerExternalReference | string | External reference of the reseller that owns the corporate |
activatedBy | string | Identifier of the principal who activated the corporate |
activatedAt | string (ISO-8601) | Activation timestamp |
instruction.instructions.created#
Dispatched when an instruction is created from a valid instruction request.{
"notificationType": "instruction.instructions.created",
"externalReference": "INSTR-9c2b1a",
"instructionType": "Payment",
"corporate": "corp_abc123",
"corporateCurrencyAccount": "CA-corp_abc123-GBP-1",
"quoteId": null,
"amount": "1000.00",
"beneficiaryReference": "BENE-7d1e",
"senderReference": "INV-2026-0421-001",
"instructionRequestReference": "IR-Payment-3a8f",
"paymentPurpose": "Supplier payment",
"sourceCurrency": "GBP",
"destinationCurrency": "GBP",
"paymentReference": "INV-2026-0421-001"
}
| Field | Type | Description |
|---|
externalReference | string | Instruction reference |
instructionType | string | Type of instruction (e.g. Payment, UnfundedFXPayment) |
corporate | string | Corporate external reference |
corporateCurrencyAccount | string | Source CCA reference |
quoteId | string | null | FX quote ID, if applicable |
amount | string (decimal) | Instruction amount |
beneficiaryReference | string | null | Beneficiary reference |
senderReference | string | null | Text readable by the receiver of the payment |
instructionRequestReference | string | Upstream instruction request reference |
paymentPurpose | string | null | Purpose of the payment |
sourceCurrency | string | ISO 4217 source currency |
destinationCurrency | string | ISO 4217 destination currency |
paymentReference | string | null | Reference expected to be used for the payment |
instruction.instructions.processed#
Dispatched when an instruction is fully processed.{
"notificationType": "instruction.instructions.processed",
"externalReference": "INSTR-9c2b1a",
"instructionType": "Payment",
"corporate": "corp_abc123",
"corporateCurrencyAccount": "CA-corp_abc123-GBP-1",
"quoteId": null,
"amount": "1000.00",
"beneficiaryReference": "BENE-7d1e",
"senderReference": "INV-2026-0421-001",
"paymentPurpose": "Supplier payment",
"sourceCurrency": "GBP",
"destinationCurrency": "GBP",
"paymentReference": "INV-2026-0421-001"
}
Field definitions are identical to instruction.instructions.created, except instructionRequestReference is not included.
instruction.instructions.failed#
Dispatched when an instruction transitions to a failed state.{
"notificationType": "instruction.instructions.failed",
"externalReference": "INSTR-9c2b1a",
"instructionType": "Payment",
"corporate": "corp_abc123",
"corporateCurrencyAccount": "CA-corp_abc123-GBP-1",
"quoteId": null,
"amount": "1000.00",
"beneficiaryReference": "BENE-7d1e",
"senderReference": "INV-2026-0421-001",
"paymentPurpose": "Supplier payment",
"sourceCurrency": "GBP",
"destinationCurrency": "GBP",
"paymentReference": "INV-2026-0421-001"
}
Field shape matches instruction.instructions.processed.
instruction.instruction-requests.rejected#
Dispatched when an instruction request is rejected before becoming an instruction.{
"notificationType": "instruction.instruction-requests.rejected",
"externalReference": "IR-Payment-3a8f",
"version": 2,
"failureReason": "Insufficient funds"
}
| Field | Type | Description |
|---|
externalReference | string | Instruction request reference |
version | integer | Aggregate version at the time of rejection |
failureReason | string | null | Human-readable reason for rejection |
accounting.corporateCurrencyAccount.funded#
Dispatched when funds have been received into a Corporate Currency Account.{
"notificationType": "accounting.corporateCurrencyAccount.funded",
"corporateExternalReference": "corp_abc123",
"corporateCurrencyAccountReference": "CA-corp_abc123-GBP-1",
"amount": "50000.00",
"currency": "GBP",
"debtorName": "Acme Supplier Ltd",
"debtorAccount": "GB29NWBK60161331926819",
"senderReference": "Inv-887654",
"externalPaymentReference": "BCS-2026-04-21-abc",
"valueDate": "2026-04-21T00:00:00+00:00",
"paymentChannel": "SEPA"
}
| Field | Type | Description |
|---|
corporateExternalReference | string | External reference of the corporate that owns the CCA |
corporateCurrencyAccountReference | string | CCA receiving the funds |
amount | string (decimal) | Funded amount |
currency | string | ISO 4217 currency |
debtorName | string | null | Name of the party that sent the funds |
debtorAccount | string | null | Account of the party that sent the funds |
senderReference | string | null | Sender's reference for the transaction |
externalPaymentReference | string | null | Provider's reference for the transaction |
valueDate | string (ISO-8601) | null | Value date of the transaction |
paymentChannel | string | null | Payment channel |
Inspecting delivery history#
Use GET /webhooks/notifications to list delivery attempts (filterable by corporateId, eventType, status). Each entry includes HTTP status codes, response bodies, and retry history. If an attempt exhausted retries, you can manually re-queue it with POST /webhooks/notifications/{notificationId}/retry.Modified at 2026-04-21 22:11:45