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.
| Field | Type | Required | Description |
|---|---|---|---|
walletId | UUID | Yes | The to debit. |
amount | String | Yes | Positive decimal amount, up to 6 decimal places. |
currency | String | Yes | Must match the wallet's currency. Payouts are crypto-only today. |
beneficiary.type | String | Yes | INDIVIDUAL or COMPANY. |
beneficiary.firstName / lastName | String | For INDIVIDUAL | Recipient's name. |
beneficiary.organisationName | String | For COMPANY | Recipient's company name. |
beneficiary.country | String | Yes | ISO 3166-1 alpha-2 country code. |
crypto.address | String | Yes | Destination address. |
crypto.network | String | Yes | Destination network/protocol. |
crypto.tag | String | No | Destination tag or memo, if the network requires one. |
internalReference | String | No | Your own label (up to 100 characters). Not used for deduplication — use Idempotency-Key for that. |
payoutReference | String | No | Up to 18 alphanumeric characters, unique per merchant. Auto-generated if omitted. |
communication.notifications.url | String | Yes | Webhook URL for this payout's status-change notifications (must be https://). |
{
"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"
}
}
}{
"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
| Status | Description |
|---|---|
PENDING | Payout created, not yet processed. |
PROCESSING | Payout is being executed. |
ON_HOLD | The payout is paused pending manual review. |
COMPLETED | Funds successfully sent to the destination. |
FAILED | Payout failed — see failureReason. |
CANCELLED | Payout was cancelled. |
When a payout ends in FAILED, failureReason explains why:
| Failure reason | Description |
|---|---|
INSUFFICIENT_FUNDS | The wallet does not have enough funds. |
INVALID_ADDRESS | The destination address was rejected for the given network. |
WALLET_NOT_FOUND | The specified wallet was not found. |
WALLET_MERCHANT_MISMATCH | The wallet does not belong to your account. |
COMPLIANCE_REJECTED | The payout was rejected during compliance screening. |
REJECTED_BY_PROVIDER | The payout was rejected by the provider. |
RETURNED | Funds were returned after being sent. |
INTERNAL_ERROR | An internal error occurred. |
Reference
Full payouts API reference can be found .
How is this guide?
Last updated on