Every Coinbax payment moves through a state machine. This guide creates one escrowed USDC payment on Base Sepolia and follows it through every state, with the curl calls and webhook events you will see along the way.
Prerequisites: a staging API key and two customers with wallet addresses. The getting started guide covers both.
The lifecycle at a glance
PENDING → RISK_REVIEW → ESCROWED → IN_REVIEW → COMPLETED
│ │
│ ├──▶ REFUNDED
│ └──▶ DISPUTED
└──▶ (COINBAX: auto-release to COMPLETED)
| State | Meaning |
|---|---|
pending |
Transaction created, no funds have moved |
risk_review |
Compliance screening and risk scoring in progress |
pending_user_action |
Waiting on an external wallet to sign and fund the escrow |
escrowed |
Funds are locked (in the escrow contract, or transferred for RAW) |
in_review |
Review window open; can be approved, refunded, or disputed |
disputed |
A dispute is open against the transaction |
completed |
Funds released to the receiver (terminal) |
refunded |
Funds returned to the sender (terminal) |
rescinded |
Sender cancelled during the hold period (terminal) |
failed |
A pre-escrow control failed or the blockchain call errored (terminal) |
The API returns states in lowercase in the status field. This guide uses
uppercase when talking about states conceptually and lowercase in JSON
samples, matching what the API actually returns.
Choose an orchestration type
orchestrationType decides how funds move:
raw |
coinbax |
|
|---|---|---|
| Mechanism | Direct blockchain transfer | Smart contract escrow |
| Time delay | None | Configurable delay before auto-release |
| Review window | Yes, before completion | No, release is automated |
| Typical flow | PENDING → ESCROWED → IN_REVIEW → COMPLETED | PENDING → ESCROWED → COMPLETED |
| Release | Manual approval or review window expiry | Background job releases after the delay |
RAW sends funds directly to the receiver, then holds the transaction in a review window before marking it complete. COINBAX locks funds in an escrow contract defined by your template; a time-delay control sets a release timestamp, and Coinbax releases the funds automatically once it passes. Use COINBAX when you want escrow protection, verification steps, or recourse before settlement.
1. Create the transaction
curl -X POST https://api-staging.coinbax.com/api/v1/transactions \
-H "X-API-Key: $COINBAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fromAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2",
"toAddress": "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
"amount": 100,
"currency": "USDC",
"blockchainNetwork": "base-sepolia",
"orchestrationType": "coinbax",
"templateId": "<your-template-id>"
}'
fromAddress, toAddress, and amount are required. templateId
references a template from your workspace; the template’s
controls run at fixed points in the lifecycle.
The response arrives in the unified envelope with the transaction in
pending:
{
"success": true,
"data": {
"id": "9f8b3c2a-...",
"status": "pending",
"orchestrationType": "coinbax",
"amount": 100,
"currency": "USDC"
},
"meta": { "timestamp": "...", "requestId": "..." },
"error": null
}
Your first webhook fires immediately:
// event: transaction.created
{
"transaction": { "id": "9f8b3c2a-...", "status": "pending" }
}
2. PENDING and RISK_REVIEW: the Verify phase
Before any funds move, Coinbax validates the request (addresses, balance, amount), runs the template’s PRE_ESCROW controls (compliance screening, sanctions checks, SMS verification if configured), and scores the transaction for risk. This is the Verify phase of the Coinbax Execution Framework.
Two outcomes:
- Everything passes: the transaction proceeds to escrow.
- A required control fails or the risk score exceeds the threshold: the
transaction moves to
failedand atransaction.failedwebhook fires with areason. No funds ever moved.
If the template includes a verification control (2FA, SMS), the transaction
pauses until the code is verified. If the sender funds the escrow from an
external wallet, the transaction sits in pending_user_action until the
signed funding transaction lands on-chain.
3. ESCROWED: the Fund phase
For coinbax transactions, funds lock in the escrow contract and Coinbax
records the on-chain transaction hash. For raw, the direct transfer
executes. Check the state at any time:
curl https://api-staging.coinbax.com/api/v1/transactions/9f8b3c2a-... \
-H "X-API-Key: $COINBAX_API_KEY"
{
"success": true,
"data": { "id": "9f8b3c2a-...", "status": "escrowed" },
"meta": { "timestamp": "...", "requestId": "..." },
"error": null
}
The webhook includes the escrow address and hash:
// event: transaction.escrowed
{
"transaction": { "id": "9f8b3c2a-...", "status": "escrowed" },
"escrowAddress": "0x...",
"txHash": "0x..."
}
At this point POST_ESCROW controls run. A TimeDelay control, for example, sets the release timestamp that the auto-release job will honor.
4. IN_REVIEW: the Confirm phase (RAW)
RAW transactions enter a review window (72 hours by default) after the transfer. During this window the transaction can be approved early, refunded, or disputed. When the window expires or an approval lands, the transaction completes.
COINBAX transactions normally skip in_review: the escrow auto-releases when
the time delay passes and all PRE_RELEASE controls succeed.
5. COMPLETED: the Settle phase
// event: transaction.completed
{
"transaction": { "id": "9f8b3c2a-...", "status": "completed" },
"txHash": "0x..."
}
completed is terminal. The full control execution history and on-chain
references stay on the transaction record as the audit trail.
The other endings
Refund. While funds are escrowed or in review, return them to the sender:
curl -X POST https://api-staging.coinbax.com/api/v1/transactions/9f8b3c2a-.../refund \
-H "X-API-Key: $COINBAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Customer request" }'
The transaction moves to refunded and a transaction.refunded webhook
fires with your reason. Requires the cancel:transactions scope.
Dispute. Either party can open a dispute against an escrowed or
in-review transaction via POST /disputes. The transaction moves to
disputed and settlement pauses until the dispute resolves. See the
Payments API reference for the dispute endpoints.
Rescind. If the template allows it, the sender can cancel during the
hold period via POST /transactions/{id}/rescind. The transaction moves to
rescinded and a transaction.rescinded webhook fires.
Next steps
- The Coinbax Execution Framework: how the four phases map to these states
- Payment controls: the rules that ran during this lifecycle
- Webhooks: signature verification and retry behavior
- Payments API reference: every endpoint and field