Payouts API
Create, retrieve, list, and cancel stablecoin payouts.
A payout sends stablecoin from your organization's balance to an on-chain address. See the payout lifecycle for how statuses progress and the reference overview for the payout object.
Create a payout
POST /v1/payouts — Scope: payouts:write
Creates a payout and starts its lifecycle: it is screened, then (if it clears and is within the auto-approval limit) executed on-chain. Use it whenever you need to pay a recipient.
Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key. |
Content-Type | Yes | application/json |
Idempotency-Key | Yes | A unique value per logical payout. Retries with the same key return the original payout. See Idempotency. |
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | Decimal amount > 0, e.g. "25.00". Must be within your organization's limits and balance. |
currency | string | Yes | Asset to send. Must be supported on destination.network (see the matrix below). |
rail | string | No | Defaults to "stablecoin" (the only supported value). |
destination | object | Yes | Where to send. See sub-fields below. |
destination.network | string | Yes | One of polygon, arbitrum, optimism, base, bsc, ethereum, tron, solana. |
destination.address | string | Yes | The recipient address, valid for the network. |
metadata | object | No | Arbitrary key/value pairs echoed back on the payout. Use it to attach your own references. |
Supported network / asset combinations
| Network | Assets |
|---|---|
polygon, arbitrum, optimism, base, bsc, ethereum | USDC, USDT, ETH |
tron | USDT |
solana | USDC, USDT |
A combination outside this matrix returns 422 unsupported_destination.
Request
curl https://api.caiboglobal.com/v1/payouts \
-H "X-API-Key: $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6b2f1e0a-7c3d-4a91-9f2e-1a2b3c4d5e6f" \
-d '{
"amount": "25.00",
"currency": "USDC",
"rail": "stablecoin",
"destination": {
"network": "polygon",
"address": "0x1234abcd5678ef901234abcd5678ef9012345678"
},
"metadata": { "invoice_id": "INV-1001" }
}'Response — 201 Created
Returns the payout. If the amount exceeds your auto-approval limit, the status is pending_approval and the HTTP status is 202 Accepted instead of 201.
{
"id": "po_9f8e7d6c5b4a",
"object": "payout",
"status": "processing",
"mode": "live",
"amount": "25.00",
"currency": "USDC",
"rail": "stablecoin",
"destination": {
"network": "polygon",
"address": "0x1234abcd5678ef901234abcd5678ef9012345678"
},
"screening_status": "clear",
"tx_hash": null,
"metadata": { "invoice_id": "INV-1001" },
"created_at": "2026-07-23T14:03:00Z"
}Behavior
- Screening runs first, in-line. The destination is screened before anything is broadcast. A flagged destination yields
403 screening_blockedand a payout with statusblocked; no funds move. See Compliance & screening. - Auto-approval. Amounts within your organization's auto-approval limit execute immediately; larger ones return
202with statuspending_approvaland wait for a manual approval. - Idempotent. Reusing the
Idempotency-Keywith the same body returns the original payout; with a different body it returns409 idempotency_conflict. - Webhooks. A successful create fires
payout.created, thenpayout.processingand finallypayout.completed(orpayout.failedwith a refund). A blocked payout firespayout.blocked. See Webhook events.
Errors
| HTTP | type | code | When |
|---|---|---|---|
| 400 | invalid_request_error | bad_request | Missing Idempotency-Key, malformed body, or an invalid amount. |
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks payouts:write. |
| 403 | compliance_error | kyb_required | Live mode with an unverified business. |
| 403 | compliance_error | screening_blocked | The destination was blocked by screening. |
| 403 | compliance_error | limit_exceeded | The payout would breach a per-payout, daily, or monthly limit. |
| 402 | invalid_request_error | insufficient_balance | Balance below the amount. |
| 409 | invalid_request_error | idempotency_conflict | The idempotency key was reused with a different request. |
| 422 | invalid_request_error | unsupported_destination | Unsupported network/asset combination or an empty/invalid destination. |
| 429 | rate_limit_error | rate_limited | Too many requests. Back off and retry. |
| 503 | compliance_error | sanctions_unavailable | Live-mode screening is temporarily unavailable; the payout was not sent. Retry later. |
List payouts
GET /v1/payouts — Scope: payouts:read
Returns your organization's payouts, newest first, cursor-paginated.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Page size, 1–100. Defaults to 25. |
starting_after | string | A payout id; returns the page after it. See Pagination. |
status | string | Filter by a single status, e.g. completed. |
Request
curl "https://api.caiboglobal.com/v1/payouts?limit=25&status=completed" \
-H "X-API-Key: $CAIBO_API_KEY"Response — 200 OK
{
"object": "list",
"data": [
{
"id": "po_9f8e7d6c5b4a",
"object": "payout",
"status": "completed",
"mode": "live",
"amount": "25.00",
"currency": "USDC",
"rail": "stablecoin",
"destination": { "network": "polygon", "address": "0x1234...5678" },
"screening_status": "clear",
"tx_hash": "0x8f3a9c2b1d4e5f60...",
"created_at": "2026-07-23T14:03:00Z"
}
],
"has_more": true,
"next_cursor": "po_9f8e7d6c5b4a"
}Errors
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks payouts:read. |
| 429 | rate_limit_error | rate_limited | Too many requests. |
Retrieve a payout
GET /v1/payouts/{id} — Scope: payouts:read
Fetches a single payout by id. Returns 404 resource_missing if it doesn't exist or isn't yours.
curl https://api.caiboglobal.com/v1/payouts/po_9f8e7d6c5b4a \
-H "X-API-Key: $CAIBO_API_KEY"Errors
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks payouts:read. |
| 404 | invalid_request_error | resource_missing | No such payout for your organization. |
Cancel a payout
POST /v1/payouts/{id}/cancel — Scope: payouts:write
Cancels a payout that hasn't started processing. Cancellable statuses are pending, screening, pending_approval, and approved. Once the payout is processing or in a terminal state, cancel returns 409 payout_not_cancelable. Cancelling releases any held balance.
curl -X POST https://api.caiboglobal.com/v1/payouts/po_9f8e7d6c5b4a/cancel \
-H "X-API-Key: $CAIBO_API_KEY"Response — 200 OK
{
"id": "po_9f8e7d6c5b4a",
"object": "payout",
"status": "cancelled",
"amount": "25.00",
"currency": "USDC",
"created_at": "2026-07-23T14:03:00Z"
}Errors
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks payouts:write. |
| 404 | invalid_request_error | resource_missing | No such payout for your organization. |
| 409 | invalid_request_error | payout_not_cancelable | The payout is already processing or terminal. |