Skip to content
Guides

Order lifecycle

Step Call Who
1. Quote GET /v2/quote prices the trade and returns the build request, signed and ready. Your backend
2. Build POST /v2/build creates the order and returns the transactions to send. Your backend
3. Deposit Send the approvals, then the deposit, on the source chain. The user’s wallet
4. Track Poll GET /v2/orders/{orderId} every 10 to 15 seconds until delivery succeeds or fails. Your backend
5. Cancel (optional) POST /v2/orders/{orderId}/cancel settles a published order early. The user signs; your backend relays

GET /v2/params is optional. The quote is not: it is the only place the price comes from.

state is a closed set of eight values. Client logic should depend on these strings only. Orders move forward and can skip states: deposited is skipped on a TRON source, and partially_filled when the first fill completes the order. terminal_chain usually lasts seconds, so a poller often sees withdrawn_on_hub right after published.

stateDiagram-v2
    [*] --> pending_deposit
    pending_deposit --> deposited
    pending_deposit --> published
    deposited --> published
    published --> partially_filled
    published --> terminal_chain
    partially_filled --> terminal_chain
    terminal_chain --> withdrawn_on_hub
    withdrawn_on_hub --> delivered
    withdrawn_on_hub --> delivery_failed
    delivery_failed --> delivered
State Meaning Stop polling?
pending_deposit Built. Waiting for the user’s deposit. No
deposited The deposit was seen on the source chain and is on its way to the hub. Not entered on a non-EVM source. No
published The order is live as an intent and open to fills. traces.rootIntentId and fullFee are now set, and a cancel is possible from here on. No
partially_filled Part of the order filled and the rest is still open. Set on the first fill only. No
terminal_chain No more fills are expected: the order filled completely, reached its deadline, or was cancelled. Settlement follows automatically. No
withdrawn_on_hub Settled on the hub. Payout and refund delivery is not yet fully recorded. No
delivered Every payout and refund transfer was confirmed on its chain and recorded in deliver. Yes
delivery_failed At least one transfer could not be delivered after retries. The order is settled on the hub; deliveryFailed says which transfer. If the failed transfer is recovered, the order moves on to delivered. Yes

The terminal delivery states for client polling are delivered and delivery_failed. Keep polling through withdrawn_on_hub: settlement alone does not confirm receipt of the payout or refund.

Use a local polling timeout and retain the orderId so tracking can resume. A timeout means the result is unconfirmed; it does not cancel the order or imply delivery_failed. There is no expired state, so an order that is never deposited stays at pending_deposit.

Delivery tracking is best effort: an order can stay at withdrawn_on_hub after funds arrive if their delivery is never observed. A settlement with no payout or refund to transfer also stays at withdrawn_on_hub. Neither case is proof of a failed transfer; inspect deliver and the settlement amounts when reconciling a timed-out order. The API keeps checking for delivery for 12 hours after settlement. After that the order does not change on its own, so check the recipient on-chain and contact Khalani if a transfer is missing.

Each order has a deadline, in Unix seconds: the time of the build plus your orderTtl (see GET /v2/params). It is signed into the order as the published intent’s validBefore, and each order keeps the orderTtl it was built with.

  • The clock starts at the build, not the deposit. The deposit still has to confirm on the source chain and reach the hub before the order publishes. Ask the user to deposit promptly.
  • Only a TRON-source build response includes deadline. For an EVM source, record the time you called /v2/build and add your orderTtl, because no response carries the build time.
  • A deposit that reaches the hub after the deadline does not publish and is not refunded on its own. The order stays at deposited, or at pending_deposit if the deposit landed more than a minute after the deadline. If the user deposited late, contact Khalani with the orderId and the deposit transaction hash.

An order settles in one hub transaction, triggered by whichever comes first:

  • it fills completely,
  • its deadline passes, or
  • a cancel is relayed.

Settlement is usually submitted within a minute of the trigger; a relayed cancel submits it immediately. It pays the filled part to payoutAddr on the destination chain at the order’s rate, and refunds the unfilled share of the deposit, after the flat fee, to refundAddr on the source chain. An order that never fills gets its deposit back, less the flat fee.

Orders can fill in parts, from more than one fill. traces.chainObservations gets one entry per fill, plus one for a cancellation or expiry.