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

text
pending ──▶ screening ──▶ approved ──▶ processing ──▶ completed
                │              │                  │
                ▼              ▼                  ▼
             blocked   pending_approval        failed  (funds refunded)

  (cancel is possible up to — but not during — processing) ──▶ cancelled

States

StatusMeaningTerminal?
pendingCreated and accepted; about to be screened.No
screeningThe destination is being screened (sanctions + blacklist).No
approvedScreening cleared and the amount is within the auto-approval limit; execution is starting.No
processingBeing signed and broadcast on-chain.No
completedSettled on-chain. tx_hash is set. Funds have left to the destination.Yes
blockedScreening blocked the destination. The payout was not sent.Yes
failedThe broadcast failed. Funds were refunded to your balance.Yes
cancelledYou cancelled it before it started processing.Yes
pending_approvalCleared 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.createdpending
  • payout.processingprocessing
  • payout.completedcompleted
  • payout.failedfailed (with a refund)
  • payout.blockedblocked

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.

bash
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_approval as 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 id and current status when 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.