# Cancel an order or close a position

Three different ways out, three different endpoints. Cancelling kills a resting order,
flattening closes what is already open, and reversing closes it and opens the opposite leg.

1. ### Get the venue order id

   Cancel keys off the **venue** order id, so read it off the order rows first. It is `null`
   before dispatch and on an order that never dispatched.

   ```bash
   curl -s "https://api.troncharts.xyz/api/v1/accounts/$ACCOUNT_ID/orders?symbol=BTC.HL" \
     -H "authorization: Bearer $TOKEN" \
     -H "x-tenant-slug: $TC_TENANT_SLUG"
   # → { orders: [ { orderId, venueOrderId, symbol, type, state, … } ] }
   ```

2. ### Cancel the working order

   `POST /oms/cancel` composes a cancel intent against the resolved parent and returns
   `201 { intentId }` — the id of the *cancel*, not of the order you killed.

   ```bash
   curl -s https://api.troncharts.xyz/api/v1/oms/cancel \
     -H "authorization: Bearer $TOKEN" \
     -H "x-tenant-slug: $TC_TENANT_SLUG" \
     -H 'content-type: application/json' \
     -H "idempotency-key: $(uuidgen)" \
     -d '{"venueOrderId":"'"$VENUE_ORDER_ID"'"}'
   ```
   ```ts
   await sdk.oms.cancel(venueOrderId, crypto.randomUUID())
   ```
   :::caution[venueOrderId, not intentId]
   `{ venueOrderId }` is the entire schema — sending `intentId` fails with `invalid_body`
   every time. The route resolves the parent intent from the venue id itself; `modify` is
   the endpoint that takes an intent id.
   :::

3. ### Flatten the position

   Both fields are optional and independent: `symbol` narrows to one market, `accountId`
   targets an owned account other than the token's own. An empty body acts on the whole
   scope. Flatten cancels the symbol's working orders *first*, then closes — so a resting
   order can't fire against a now-flat account.

   ```bash
   curl -s https://api.troncharts.xyz/api/v1/oms/flatten \
     -H "authorization: Bearer $TOKEN" \
     -H "x-tenant-slug: $TC_TENANT_SLUG" \
     -H 'content-type: application/json' \
     -d '{"symbol":"BTC.HL"}'
   # → { ok, cancelIntentIds, closeIntentId, alreadyFlat }
   ```
   ```ts
   await sdk.oms.flatten({ symbol: 'BTC.HL' })
   ```
   :::note[The SDK's flatten response type is wrong]
   `flatten()` is typed as resolving `{ intentIds }`, a key the route does not return. Read
   `cancelIntentIds` and `closeIntentId` off the JSON until the type is corrected.
   :::

4. ### Reverse instead of closing

   Same body, opposite intent: `/oms/reverse` closes the position and opens the other side.
   `openIntentId` comes back `null` with `reverseOpenDeferred: true` — the open leg is
   composed at the *realized* close size once the close terminalizes, so it can never
   oversize the flip. It surfaces on the `/ws/risk` Position-Update frame.

   ```bash
   curl -s https://api.troncharts.xyz/api/v1/oms/reverse \
     -H "authorization: Bearer $TOKEN" \
     -H "x-tenant-slug: $TC_TENANT_SLUG" \
     -H 'content-type: application/json' \
     -d '{"symbol":"BTC.HL"}'
   ```
   ```ts
   const { closeIntentId, reverseOpenDeferred } = await sdk.oms.reverse({ symbol: 'BTC.HL' })
   ```
   Cancel and flatten only reduce exposure, so a `liquidation` credential can make them.
   Reverse re-establishes it and needs `fullTrading`. See [Scopes & tiers](https://docs.troncharts.xyz/docs/auth/scopes/).

**Next:** [Place your first order](https://docs.troncharts.xyz/docs/recipes/place-your-first-order/) · [Stream account and position updates](https://docs.troncharts.xyz/docs/recipes/stream-account-updates/) · [Accounts & positions](https://docs.troncharts.xyz/docs/trading/accounts/)