Skip to main content

Order lifecycle

Every swap and bridge response is a snapshot of a durable order. Store its orderId, use the appropriate read endpoint, and render customerState rather than predicting the next step from elapsed time.

Statuses

StatusMeaning for an integration
awaiting_depositNothing has arrived yet. Show the returned source funding instruction.
awaiting_xmr1Show the XMR1 funding instruction.
awaiting_trx1Show the TRX1 funding instruction.
processingA deposit has been seen and the order is moving. Continue tracking. Do not predict completion from elapsed time.
completedRender the resolved outcome; use customerState for presentation.
failedRender the failed outcome unless customerState declares another current recovery state.
expiredRender expiry unless customerState declares an exact refund recovery action.
refundedA refund workflow completed.
needs_reviewLegacy value kept for wire compatibility; current API versions no longer emit it — treat it like processing if ever encountered.

status is the coarse business outcome used for reporting and compatibility. customerState is the exhaustive display/action state machine. Its processing stages are deliberately generic (confirming, routing, trading, sending, refunding). confirmations and requiredConfirmations remain optional facts.

status is derived, not stored—no column holds processing—and every surface derives it the same way: an order past its deposit and not yet terminal reads processing, on the per-order read and in the session list alike. So awaiting_deposit means what it says on both: nothing has been observed arriving for this order. A deposit that is seen but not yet confirmed is already processing; confirmations and requiredConfirmations, not status, are how you tell those two apart.

Read the current order

Order typeDurable REST readOptional WebSocket upgrade
SwapGET /v2/swaps/{id}GET /v2/swaps/{id}/events
Native bridgeGET /v2/bridges/{id}GET /v2/bridges/{id}/events

Both read endpoints require either the owning session (x-session-id) or the exact destination address as the single-order verify query value. An order ID alone is insufficient. The verify path is read-only. A missing order and an absent or invalid credential intentionally produce the same 404 response, so do not infer that an order exists from a failed read.

See live updates for the WebSocket transport, opaque close behavior, and REST polling requirement.

Pauses and customer actions

customerState.kind === "paused" carries one safe reason for wait/support copy. It is a plain display string, nothing more.

customerState.kind === "action_required" is the only authority for an interactive control. Currently supported actions are coinflip and refund_address; use the separately validated coinflip or refundRecovery resource for the form/game data. Never infer an action from status, resource presence, or elapsed time.

Session lists and bulk reads

Use GET /v2/orders with x-session-id to list the orders owned by one session. A row is the same order summary the per-order read returns, minus customerState: a pause, an action, and a recovery are authoritative only on the per-order read. Bridge rows also carry asset and direction, so a list can label an XMR deposit against a TRX withdrawal without a read per row. Both are optional—swap rows omit them—so keep using product as the discriminator.

A row's status is derived by the rule above, but from a cheaper input: the list reads a progress projection refreshed shortly after each order event, while the per-order read watches the order's workflow live. A non-terminal projection that has gone unrefreshed for two minutes is treated as carrying no progress at all, and the row falls back to the order's stored status. A list row can therefore trail the per-order read—an order the detail already calls processing may briefly read awaiting_deposit in the list—and it never runs ahead. Treat the list as an index and the per-order read as the answer.

Refund address submission

PUT /v2/orders/{id}/refund-address is an ownership-protected action. It saves a refund address only when the order is eligible. For normal failed or expired orders, saving that address is not a completed refund. Continue tracking until status becomes refunded.

When refundRecovery.kind is wrong_chain, address submission only saves the immutable customer destination. Render the form only when customerState.action is refund_address; the recovery resource supplies its exact asset, chain, amount, and phase.

See actions and retries for owner-action eligibility and uncertain-request handling.