Integration guides

Payouts

Send an on-demand stablecoin payout from your wallet to an external crypto address


Overview

A payout moves funds from one of your stablecoin wallets to an external crypto address you specify, on demand, via the API. There is no beneficiary-registration step — the destination is specified inline on every request. For the conceptual flow, see in the integration overview.

Payouts are unrelated to . A payout is a single, ad-hoc transfer to a destination you specify on each request. A settlement is a recurring or manual sweep to a destination you pre-configure in Fuzebox, and has no public API.

Create the payout

Requires an Idempotency-Key header (1–64 characters) and an X-JWS-Signature header — a detached JWS signing the raw request body, with replay protection. See for how to generate this.

FieldTypeRequiredDescription
walletIdUUIDYesThe to debit.
amountStringYesPositive decimal amount, up to 6 decimal places.
currencyStringYesMust match the wallet's currency. Payouts are crypto-only today.
beneficiary.typeStringYesINDIVIDUAL or COMPANY.
beneficiary.firstName / lastNameStringFor INDIVIDUALRecipient's name.
beneficiary.organisationNameStringFor COMPANYRecipient's company name.
beneficiary.countryStringYesISO 3166-1 alpha-2 country code.
crypto.addressStringYesDestination address.
crypto.networkStringYesDestination network/protocol.
crypto.tagStringNoDestination tag or memo, if the network requires one.
internalReferenceStringNoYour own label (up to 100 characters). Not used for deduplication — use Idempotency-Key for that.
payoutReferenceStringNoUp to 18 alphanumeric characters, unique per merchant. Auto-generated if omitted.
communication.notifications.urlStringYesWebhook URL for this payout's status-change notifications (must be https://).
Request body
{
  "walletId": "a1b2c3d4-1234-5678-9abc-def012345678",
  "amount": "250.00",
  "currency": "USDC",
  "beneficiary": {
    "type": "INDIVIDUAL",
    "firstName": "Jane",
    "lastName": "Doe",
    "country": "GB"
  },
  "crypto": {
    "address": "0xabc...def",
    "network": "ETHEREUM"
  },
  "payoutReference": "PAYOUT2026001",
  "communication": {
    "notifications": {
      "url": "https://example.com/webhooks/payouts"
    }
  }
}
Response 201
{
  "id": "d4e5f6a7-1234-5678-9abc-def012345678",
  "walletId": "a1b2c3d4-1234-5678-9abc-def012345678",
  "status": "PENDING",
  "type": "CRYPTO",
  "payoutReference": "PAYOUT2026001",
  "debited": null,
  "paid": {
    "amount": "250.00",
    "currency": "USDC"
  },
  "rate": null,
  "beneficiary": {
    "type": "INDIVIDUAL",
    "firstName": "Jane",
    "lastName": "Doe",
    "country": "GB"
  },
  "crypto": {
    "address": "0xabc...def",
    "network": "ETHEREUM"
  },
  "transaction": null,
  "failureReason": null,
  "createdAt": "2026-04-08T10:12:04Z",
  "updatedAt": "2026-04-08T10:12:04Z"
}

Reusing an Idempotency-Key always returns 409 Conflict — it does not replay the original response. Use a new key for every distinct payout.

A request rejected for an invalid or missing X-JWS-Signature returns the same 401 response regardless of the specific reason, so the failure can't be used to probe your signing setup.

The one exception: a valid signature that was already used returns 409 Conflict with code CONFLICT. A signature is used up even when the request fails, so this doesn't tell you whether the payout was created. Re-sign every attempt, including retries, but keep the same Idempotency-Key: the retry creates the payout if the first attempt didn't, or returns 409 Conflict with code IDEMPOTENCY_CONFLICT if it did.

Track the payout, or wait for the webhook

Volt notifies the webhook URL you set in communication.notifications.url when creating the payout once its status changes. Alternatively, poll:

Payout statuses

StatusDescription
PENDINGPayout created, not yet processed.
PROCESSINGPayout is being executed.
ON_HOLDThe payout is paused pending manual review.
COMPLETEDFunds successfully sent to the destination.
FAILEDPayout failed — see failureReason.
CANCELLEDPayout was cancelled.

When a payout ends in FAILED, failureReason explains why:

Failure reasonDescription
INSUFFICIENT_FUNDSThe wallet does not have enough funds.
INVALID_ADDRESSThe destination address was rejected for the given network.
WALLET_NOT_FOUNDThe specified wallet was not found.
WALLET_MERCHANT_MISMATCHThe wallet does not belong to your account.
COMPLIANCE_REJECTEDThe payout was rejected during compliance screening.
REJECTED_BY_PROVIDERThe payout was rejected by the provider.
RETURNEDFunds were returned after being sent.
INTERNAL_ERRORAn internal error occurred.

Reference

Full payouts API reference can be found .

How is this guide?

Last updated on