# Your First Transaction

> Follow one escrowed staging payment through every state of the Coinbax transaction lifecycle, from creation to settlement.
> Source: https://developers.coinbax.com/docs/getting-started/first-transaction
> Last updated: 2026-07-16

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](/docs/getting-started/) 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

```bash
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](/docs/concepts/controls) run at fixed points in the lifecycle.

The response arrives in the unified envelope with the transaction in
`pending`:

```json
{
  "success": true,
  "data": {
    "id": "9f8b3c2a-...",
    "status": "pending",
    "orchestrationType": "coinbax",
    "amount": 100,
    "currency": "USDC"
  },
  "meta": { "timestamp": "...", "requestId": "..." },
  "error": null
}
```

Your first webhook fires immediately:

```json
// 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](/docs/concepts/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 `failed` and a `transaction.failed` webhook fires with
  a `reason`. 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:

```bash
curl https://api-staging.coinbax.com/api/v1/transactions/9f8b3c2a-... \
  -H "X-API-Key: $COINBAX_API_KEY"
```

```json
{
  "success": true,
  "data": { "id": "9f8b3c2a-...", "status": "escrowed" },
  "meta": { "timestamp": "...", "requestId": "..." },
  "error": null
}
```

The webhook includes the escrow address and hash:

```json
// 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

```json
// 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:

```bash
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](/reference/coinbax-api/) 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](/docs/concepts/execution-framework): how the four phases map to these states
- [Payment controls](/docs/concepts/controls): the rules that ran during this lifecycle
- [Webhooks](/docs/api/webhooks): signature verification and retry behavior
- [Payments API reference](/reference/coinbax-api/): every endpoint and field