# Track orders

> Track delivery success or failure, read what was paid and refunded, and list your orders.

## Poll one order

`GET /v2/orders/{orderId}` is public: anyone holding the `orderId` can read the order without a key. It allows any origin, so a browser can poll it directly. Keep order ids out of shared URLs, logs and analytics.

Poll every 10 to 15 seconds until `state` is `delivered` or `delivery_failed`. There are no webhooks. Keep polling through `withdrawn_on_hub`, which means hub settlement with delivery not yet fully recorded. Use a local timeout and retain the `orderId` to resume: a timeout means the result is unconfirmed, not that the transfer failed. See [Order lifecycle](/guides/order-lifecycle/) for every state and cases where delivery tracking can remain incomplete.

## Read the result

Nested objects are `null` until their event is seen, so "not yet" is distinct from "seen, with zero". Every `at` is unix seconds.

| Field | What it tells you |
|---|---|
| `state` | Where the order is. |
| `deposit` | The deposit seen on the source chain. Stays `null` on a non-EVM source. |
| `traces.withdraw` | The settlement on the hub: `settledOutcome` paid out (destination units), `refundSource` refunded and `accruedFee` kept (source units). |
| `deliver` | The payout and refund transfers as they land: `deliver.payout` on the destination chain, `deliver.refund` on the source chain. |
| `deliveryFailed` | Set with `delivery_failed`: which transfer could not be delivered. |
| `traces.rootIntentId` | The published intent. You need it to sign a cancel. |
| `traces.chainObservations` | The intent's trail on the hub: one entry per fill with `intentState: "Solved"`, plus one `"Cancelled"` entry for a cancellation or expiry. A `Cancelled` entry whose `at` is before the deadline was a cancel. |

Two timing details:

- `traces.withdraw` appears as soon as the order settles, but its amounts can be `null` for a short time until the settlement event is indexed. `traces.withdraw` present with `settledOutcome: null` means "settled, amounts still coming". Poll again.
- `deliver.*.amount` repeats the figures in `traces.withdraw`. It is not measured from the transfer itself.

### Payout or refund

The API's `delivered` state covers both payouts and refunds. When the state is `delivered`:

- `deliver.payout` alone means a payout was delivered.
- `deliver.refund` alone means the order was refunded, after fees. Show **Refunded** to the user.
- Both mean a partial fill paid out and the remainder was refunded.

`refunded` is a display label here, not a separate v2 API state. A refund is complete only after its source-chain transfer is recorded; `withdrawn_on_hub` alone is not enough.

## Reconcile an order

Some figures are not returned:

- No endpoint returns the filled source amount or the commission earned on one order. `settledOutcome` divided by the rate recovers the filled source only approximately.
- `fullFee` is everything held back at publish, your commission included. On a partial fill Khalani keeps only part of it, and `accruedFee` reports that part. It includes the whole flat fee, so it is non-zero whenever the pair has a flat fee, even on an order that never filled.
- Your commission reaches your commission wallet as its own transfer on the hub.

Responses carry no build timestamp and no `nonce`. Record the build time yourself.

Addresses come back lowercase in orders and checksummed from `/v2/params` and `/v2/quote`. Compare them case-insensitively.

## List your orders

`GET /v2/orders` returns your orders, newest first by build time, always limited to your key's account.

| Query | Meaning |
|---|---|
| `depositor`, `from`, `to` | Filter by depositor or by source or destination token. Either form of a TRON address matches. |
| `state` | One of the eight states. |
| `limit` | Page size, 1 to 200. Default 50. |
| `cursor` | `nextCursor` from the previous page. |

Entries have the same shape as a single order, except that `traces.chainObservations` is always empty: read the single order for its trail.

```bash
curl -s "https://api.hyperstream.dev/v2/orders?state=published&limit=20" -H "X-API-Key: $KHALANI_API_KEY"
```

Paging rules:

- The cursor marks a position. Orders built after your first page do not appear on later pages. To pick up new orders, poll the first page.
- Keep the filters unchanged while paging.
- A final, partial page still carries a cursor. Stop when a page comes back with no orders.
- There is no time filter, and unknown query parameters are ignored, not rejected. For a recurring job, read from the first page until you reach an `orderId` you already have.
