Payout lifecycle
A payout moves through a well-defined state machine. Know each state, what it means, and how to react.
Every payout has a status. It starts at pending and advances through screening and execution to a terminal state. Design your integration around these states — and let webhooks drive your reactions rather than polling.
The state machine
pending ──▶ screening ──▶ approved ──▶ processing ──▶ completed
│ │ │
▼ ▼ ▼
blocked pending_approval failed (funds refunded)
(cancel is possible up to — but not during — processing) ──▶ cancelledStates
| Status | Meaning | Terminal? |
|---|---|---|
pending | Created and accepted; about to be screened. | No |
screening | The destination is being screened (sanctions + blacklist). | No |
approved | Screening cleared and the amount is within the auto-approval limit; execution is starting. | No |
processing | Being signed and broadcast on-chain. | No |
completed | Settled on-chain. tx_hash is set. Funds have left to the destination. | Yes |
blocked | Screening blocked the destination. The payout was not sent. | Yes |
failed | The broadcast failed. Funds were refunded to your balance. | Yes |
cancelled | You cancelled it before it started processing. | Yes |
pending_approval | Cleared screening but exceeds the org's auto-approval limit, so it's held for manual approval. | No |
How events map to states
Webhook events track the transitions:
payout.created→pendingpayout.processing→processingpayout.completed→completedpayout.failed→failed(with a refund)payout.blocked→blocked
Cancelling
You can cancel a payout while it is pending, screening, pending_approval, or approved — anytime before it starts processing. Once it is processing or in a terminal state, cancel returns 409 payout_not_cancelable. Cancelling releases any held balance.
curl https://api.caiboglobal.com/v1/payouts/po_9f8e7d6c5b4a/cancel \
-X POST -H "X-API-Key: $CAIBO_API_KEY"Handling pending_approval
Each organization has an auto-approval limit. Payouts at or below it flow straight through; payouts above it clear screening and then wait in pending_approval for a manual approval by an authorized member of your organization. Once approved, the payout continues to processing and then completed.
- Don't treat
pending_approvalas failure — it's a hold, not a rejection. - Surface these payouts to whoever approves them (they can act from the Business dashboard).
- You'll receive the completion (or failure) webhook once it resumes.
Handling blocked
A blocked payout was stopped by screening and never sent — no funds moved. Retrying the same destination will block again. Retrieve the payout to read the safe screening summary (status and reasons), and route the case to your compliance process rather than retrying. See Compliance & screening.
Handling failed
A failed payout means the on-chain broadcast didn't go through; the amount was refunded to your balance. Failures are typically transient (network conditions). You can create a new payout to the same destination — use a new idempotency key, since it's a new payout, and read failure_reason for context.
Recommended pattern
- Persist each payout's
idand currentstatuswhen you create it. - Update your record from webhook events; re-fetch by id to confirm before doing anything irreversible.
- Reconcile periodically by listing payouts and comparing against your records.