POST /webhooks, passing a url and the events you want; omit the list or pass ["*"] to receive everything. Verify every delivery with the Webhook-Signature header before processing, and use the envelope’s eventId to handle retries idempotently. This page lists every event you can receive and the envelope it arrives in.
Event envelope
Every event shares one envelope. The resource that changed is carried in full underpayload, so you rarely need a follow-up read.
| Field | Type | Description |
|---|---|---|
eventId | string | Unique, stable ID for this event. Use it to deduplicate retried deliveries. |
eventName | string | The event type from the catalog below. |
schemaVersion | integer | Envelope schema version. |
producerService | string | The OMS service that produced the event. |
orgId | string | Your organization. |
projectId | string | The project the event belongs to. Optional. |
customerId | string | The customer the resource belongs to, when applicable. Optional. |
mode | string | The environment the event was produced in. Optional. |
resourceType | string | The kind of resource in payload (for example cashIn, virtualAccount, transaction_crypto_to_fiat). |
resourceId | string | The ID of the resource in payload. |
sequence | integer | Monotonic sequence for ordering events about the same resource. Optional. |
occurredAt | timestamp | When the event occurred. |
correlationId | string | Correlates events produced by the same logical operation. Optional. |
causationId | string | The event that caused this one, when applicable. Optional. |
payload | object | The full resource object at the time of the event. |
status lives inside payload, not on the envelope: branch on payload.status (or the event name itself) rather than expecting envelope-level status fields.
Transactions
Transaction events are namespaced by transfer type. Refund events fire when a failed transaction’s funds are returned (see Returns and refunds).| Event | Fires when |
|---|---|
transaction.fiatToCrypto.processing | A fiat-funded transaction starts executing. |
transaction.fiatToCrypto.completed | Crypto delivered to the destination. |
transaction.fiatToCrypto.failed | The transaction failed; see payload.error. |
transaction.fiatToCrypto.refundCompleted | The refund for a failed transaction was delivered. |
transaction.fiatToCrypto.refundFailed | The refund itself failed; operator follow-up. |
transaction.cryptoToFiat.processing | A crypto-funded payout starts executing. |
transaction.cryptoToFiat.cashPickupReady | Cash payout only: the pickup code was issued. |
transaction.cryptoToFiat.codeExpired | Cash payout only: the pickup code expired uncollected. |
transaction.cryptoToFiat.completed | Fiat delivered to the destination. |
transaction.cryptoToFiat.failed | The payout failed; see payload.error. |
transaction.cryptoToFiat.refundCompleted | The stablecoin re-credit for a failed payout was delivered. |
transaction.cryptoToFiat.refundFailed | The re-credit itself failed; operator follow-up. |
transaction.cryptoToCrypto.processing | A crypto-to-crypto send starts executing. |
transaction.cryptoToCrypto.completed | Crypto delivered to the destination. |
transaction.cryptoToCrypto.failed | The send failed; see payload.error. |
transaction.cryptoToCrypto.refundCompleted | The refund for a failed send was delivered. |
transaction.cryptoToCrypto.refundFailed | The refund itself failed; operator follow-up. |
Cash-in
| Event | Fires when |
|---|---|
cashIn.created | A cash-in code was issued. |
cashIn.completed | The cash was deposited and converted; the auto-created transaction is linked on the cash-in. |
cashIn.expired | The code expired before a deposit was made. |
Virtual accounts
| Event | Fires when |
|---|---|
virtualAccount.created | The virtual account record was created. |
virtualAccount.provisioned | The underlying deposit account was provisioned; bankDetails is populated. |
virtualAccount.active | The account is live and accepting deposits. |
virtualAccount.frozen | Deposits are suspended. |
virtualAccount.closed | The account reached end of life. |
virtualAccount.deleted | An asynchronous delete finalized. |
virtualAccount.failed | Provisioning failed. |
virtualAccount.deposit.pending | An inbound bank deposit was detected and is settling. |
virtualAccount.deposit.settled | The inbound deposit settled. |
virtualAccount.deposit.failed | The inbound deposit failed. |
virtualAccount.deposit.returned | The inbound deposit was returned by the bank. |
virtualAccount.cryptoTransfer.initiated | The converted crypto leg was initiated toward the destination wallet. |
virtualAccount.cryptoTransfer.pending | The crypto leg is in flight. |
virtualAccount.cryptoTransfer.settled | The crypto leg was delivered. |
virtualAccount.cryptoTransfer.failed | The crypto leg failed. |
Deposit addresses
Lifecycle events use thedepositAddress. prefix; per-deposit and per-payout legs use the deposit_address. prefix.
| Event | Fires when |
|---|---|
depositAddress.created | The deposit address record was created. |
depositAddress.active | The inlet address is provisioned and monitoring; depositInstructions is populated. |
depositAddress.paused / depositAddress.resumed | Monitoring was paused or resumed. |
depositAddress.frozen | Deposits are held pending review. |
depositAddress.closed | The address reached end of life. |
depositAddress.deleted | The record was removed. |
depositAddress.failed | Provisioning failed. |
deposit_address.crypto_deposit.pending | An inbound on-chain deposit was detected. |
deposit_address.crypto_deposit.settled | The inbound deposit settled. |
deposit_address.crypto_deposit.failed | The inbound deposit failed. |
deposit_address.crypto_deposit.needs_attribution | The deposit came from an unrecognized sender and is held for sender attribution. |
deposit_address.ach_payout.initiated / .pending / .settled / .failed / .returned | The ACH payout leg progressed. |
deposit_address.wire_payout.initiated / .pending / .settled / .failed / .returned | The domestic wire payout leg progressed. |
deposit_address.intl_wire_payout.initiated / .pending / .settled / .failed / .returned | The international wire payout leg progressed. |
External accounts
| Event | Fires when |
|---|---|
externalAccount.created | The account was registered and is being validated. |
externalAccount.verified | Validation passed; the account is usable on quotes. |
externalAccount.declined | Validation failed. |
externalAccount.deleted | The account was removed. |
Endorsements
| Event | Fires when |
|---|---|
endorsement.updated | A customer endorsement changed state. |
endorsement.active | An endorsement became active; the customer can use the operations it gates. |
Wallets
| Event | Fires when |
|---|---|
wallet.provisioned | A custodial wallet’s on-chain address was provisioned. |
wallet.depositDetected | Crypto arrived at a wallet address outside any OMS-initiated transaction. |
Delivery and verification
- Deliveries are signed with the
Webhook-Signatureheader (t=<unix>,v1=<hex>, an HMAC-SHA256 over<timestamp>.<raw-body>with your per-endpoint signing secret). Verify before processing and reject stale timestamps. - Deliveries can arrive more than once and, across different resources, out of order. Deduplicate on
eventIdand usesequenceto order events about the same resource. - Manage subscriptions with the Webhooks endpoints:
POST/GET /webhooks,GET/PATCH/DELETE /webhooks/{id}.