Skip to main content
OMS sends 26 webhook event types across 9 resources. Subscribe with POST /webhooks, passing a url and the subscriptions you want. To build the endpoint that receives them, see Receiving webhooks.

Subscriptions

A subscription that names a type not in this catalog receives nothing.

Envelope

Every event has the same six fields. data holds:
A field that does not apply, or has no value yet, is left out rather than sent as null. Status, sub-status, and event-type lists can grow without a version bump: ignore a type you do not handle, and fall back to the part of a sub-status before the dot.

Event types

Each resource sends created once, statusChanged on every status change, and updated for any other visible change. Deleting or closing a resource is a status change. A resource that existed before you subscribed has no created event, so treat the first event you see for an ID as its creation.

Resource notes

  • transaction: a change of subStatus alone also sends transaction.statusChanged, with previousStatus equal to status. There is no transaction.updated. Sub-statuses are listed in the transaction lifecycle.
  • transfer: one movement of money on one rail. A transaction is made of a deposit transfer, a payout transfer, and a refund transfer when money goes back to the sender. A transfer that moves through several statuses at once sends one statusChanged per status. transfer.updated reports late details such as a transaction hash in tracking.
  • customer: sent a short delay after the change. data.resource is the GET /customers/{customerId} body without balances or empty lists. A customer OMS sees for the first time is announced pending in customer.created, then moved by customer.statusChanged with previousStatus: "pending", even if it was already active. Endorsement changes arrive as customer.updated with endorsements in changedFields.
  • customerWallet: created carries pending with no address; statusChanged to active carries the address. updated covers label, metadata, and the first address.
  • depositAddress: created carries pending. changedFields on updated is a subset of destination, payout, returnDestination, label, metadata, and depositInstructions.
  • virtualAccount: created carries pending. changedFields on updated is a subset of depositInstructions, destination, label, metadata, payout, returnDestination, and returnPayout. A delete sends statusChanged into deleting and again on to deleted.
  • cashIn: refreshing the cash-in code sends cashIn.updated with changedFields: ["depositInstructions"].
  • externalAccount: a move to invalid (for example after a bank return) always sends statusChanged.
Deposits into deposit addresses and virtual accounts, and their payouts, are reported through transaction.* and transfer.*. There are no per-rail deposit or payout events.

Never delivered

transaction.cryptoToCrypto.underReview, transaction.cryptoToFiat.underReview, and transaction.fiatToCrypto.underReview exist for compliance only. They are never delivered and cannot be subscribed to. A transaction under review reads processing.underReview, announced through transaction.statusChanged.

Delivery

  • Each delivery is an HTTPS POST of the envelope, signed in a Webhook-Signature header: t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256 under your signing key of <t>.<raw request body>. Reject a t more than 300 seconds from your clock. The timestamp and signature are regenerated on every attempt.
  • A 2xx acknowledges. Anything else, a timeout (the webhook’s timeoutMs, default 5000, maximum 10000), or a network error is retried 10 times over about 3 days.
  • Delivery is at-least-once, in parallel, and unordered. Deduplicate on id and idempotencyKey; order by createdAt per resource.
  • An endpoint failing continuously for about 72 hours is suspended. Re-enable it with POST /webhooks/{webhookId}/enable.
  • Delivery history is kept for 30 days. GET /webhooks/{webhookId}/deliveries lists it (filters status, eventId, test, createdAfter, createdBefore), and each record nests the body sent under event. POST /webhooks/{webhookId}/deliveries/retry sends deliveries again. There is no GET /events.
Manage endpoints with POST/GET /webhooks, GET/PATCH/DELETE /webhooks/{webhookId}, and POST /webhooks/{webhookId}/enable, /disable, /rotate-key, and /test. See the API reference.