Payout events

Payout events notify you as each recipient's crypto payout moves through its lifecycle. They are emitted when a payout order has a callback_url (see Subscribing).

All payout events use the standard event envelope. This page documents the reference shared by every payout event: the identifier set, the status values, and the data snapshot shape. Each individual event is documented on its own page:

Identifiers

Payout events carry these domain identifiers in the envelope:

FieldTypeValue
payout_order_uuidStringUUID of the payout order this event belongs to. Stable across retries.
recipient_emailStringEmail of the recipient whose payout this event describes.
external_send_idStringIdentifier for the underlying crypto send. A single recipient can produce multiple external_send_ids if a quote expires and is reopened — treat each one as a separate lifecycle.

Status values

The envelope status field on a payout event is one of:

statusMeaning
in_progressThe send request has been accepted. No funds have moved yet.
processingThe send is being processed. An FX exchange may be in flight or the chain broadcast is pending.
completedThe send is finalized. If tx_hash is present, funds are confirmed on chain.
failedThe send did not go through. failure_reason carries the cause.
expiredThe send was not actioned within its lifetime window.
canceledThe send was canceled. No funds moved.

completed, failed, expired, and canceled are terminal — no further events fire for that external_send_id once a payout.terminal_state event has been sent.

data shape

data is present on payout.quote_* events and on payout.terminal_state events (it is omitted on payout.status_changed). It carries the full send-request snapshot at the moment the event was generated.

FieldTypeNotes
idIntegerSend-request ID. Equals external_send_id parsed as integer.
statusStringCurrent status of the underlying send. Mirrors the top-level status.
purposeStringHuman-readable description of the payout.
created_atStringISO-8601 timestamp when the send request was created.
input_amountStringAmount the recipient is sending, in input_currency.
input_currencyHashSee Currency object.
sending_amountStringAmount the recipient will receive, in sending_currency.
sending_currencyHashSee Currency object.
input_to_sending_rateStringFX rate used to convert input_amount to sending_amount. "1.0" for same-currency sends.
balance_debit_amountStringAmount debited from the merchant's ledger, in balance_debit_currency.
balance_debit_currencyHashSee Currency object.
sending_to_balance_debit_rateStringFX rate used to convert from sending_currency to balance_debit_currency.
fees.service_feeHash{ amount, currency }. amount is a decimal string; currency follows the Currency object shape.
fees.conversion_feeHash{ amount, currency }. Only present on cross-currency sends.
ledger_accountHash{ id, title, status, balance, account_type, currency }. The merchant ledger account funds were debited from.
beneficiary_payout_settingHash{ id, beneficiary_id, created_at, currency, platform, crypto_address, crypto_address_metadata }. The destination wallet for this send.
blockchain_transactionsArrayEmpty [] until the chain broadcast lands. Once populated, each entry is { id, txid, amount, status, network_confirmations, currency }. The txid of the first entry is surfaced at the top level as tx_hash on payout.terminal_state.
requires_2fa_confirmationBooleanWhether the recipient must complete 2FA before the send proceeds.

Currency object

input_currency, sending_currency, balance_debit_currency, and the currency nested under fees.* / ledger_account / beneficiary_payout_setting all share the same shape:

FieldTypeNotes
idIntegerInternal currency ID.
kindString"fiat" or "crypto".
titleStringFull currency name (e.g. "Ethereum", "USDC").
symbolStringTicker symbol (e.g. "ETH", "USDC").
enabledBooleanWhether the currency is currently enabled for new sends.
disabled_messageString (optional)Reason a disabled currency is unavailable. null when enabled: true.

BlockchainTransaction object

Entries in data.blockchain_transactions[] describe individual on-chain transactions backing the send. The array is empty until the chain broadcast lands; once populated, the txid of the first entry is surfaced at the top level as tx_hash on payout.terminal_state.

FieldTypeNotes
idIntegerInternal transaction ID.
txidStringOn-chain transaction hash.
amountStringDecimal amount transferred in this transaction.
statusStringTransaction status (e.g. "confirmed").
network_confirmationsIntegerNumber of confirmations the transaction has received.
currencyHashA thinner variant of the Currency object: { id, title, symbol, platform: { id, title } }. The nested platform identifies the chain the transaction was broadcast on (e.g. "Base", "Solana", "Ethereum").

Example:

{
  "id": 7000001,
  "txid": "0x1111111111111111111111111111111111111111111111111111111111111111",
  "amount": "12.0",
  "status": "confirmed",
  "network_confirmations": 1,
  "currency": {
    "id": 113,
    "title": "USDC",
    "symbol": "USDC",
    "platform": {
      "id": 42,
      "title": "Base"
    }
  }
}
📘

Decimal amounts are strings

All amounts are decimal strings — parse with your language's arbitrary-precision decimal type, not floats. Additional fields may appear in data; treat unknown fields as informational.