> For the complete documentation index, see [llms.txt](https://dev.strixlab.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev.strixlab.io/typescript-sdk/orders.md).

# Orders

Everything on this page needs [HMAC credentials](/http-and-websocket-api/authentication.md). Without them the SDK throws `StrixAuthError` before making a request.

{% hint style="warning" %}
**Fills are asynchronous.** The response to a placement is an acknowledgement — a crossing order still returns `status: "OPEN"` with `filledQuantity: "0"`. Watch [`order.update` / `trade.settled`](/typescript-sdk/websockets.md#your-orders-and-fills) for what actually happened. See [Core Concepts](/get-started/concepts.md#orders-settle-asynchronously).
{% endhint %}

## Limit orders

```ts
const order = await client.orders.place({
  tokenId,
  side:      'BUY',      // 'BUY' | 'SELL'
  price:     0.65,       // 65¢ — must be a multiple of the market's tickSize
  quantity:  100,        // shares
  orderType: 'GTC',      // 'GTC' | 'GTD' | 'FOK' | 'FAK'
});

order.orderHash;   // ← keep this; it is the handle for cancelling
order.status;      // "OPEN"
```

### Order types

<table><thead><tr><th width="110">Type</th><th width="230">Name</th><th>Behaviour</th></tr></thead><tbody><tr><td><code>GTC</code></td><td>Good Till Cancelled <em>(default)</em></td><td>Rests on the book until you cancel it or the market closes.</td></tr><tr><td><code>GTD</code></td><td>Good Till Date</td><td>Rests until <code>expiredAt</code>, then auto-cancels.</td></tr><tr><td><code>FOK</code></td><td>Fill Or Kill</td><td>Must fill <strong>completely</strong> at the limit right now, or it is cancelled entirely.</td></tr><tr><td><code>FAK</code></td><td>Fill And Kill <em>(IOC)</em></td><td>Fills whatever is available right now; the remainder is cancelled.</td></tr></tbody></table>

{% tabs %}
{% tab title="GTC" %}

```ts
// Rest a bid and wait to be hit. Makers pay no fee.
await client.orders.place({
  tokenId, side: 'BUY', price: 0.60, quantity: 250, orderType: 'GTC',
});
```

{% endtab %}

{% tab title="GTD" %}

```ts
// Auto-cancels in an hour — good for quotes you might forget about.
await client.orders.place({
  tokenId, side: 'SELL', price: 0.70, quantity: 50,
  orderType: 'GTD',
  expiredAt: new Date(Date.now() + 3_600_000).toISOString(),
});
```

`expiredAt` must be **at least one minute** in the future — the expiry sweep runs every 60 seconds, so anything shorter could match after its nominal expiry. TypeScript enforces that `expiredAt` is present on `GTD` and absent on every other type.
{% endtab %}

{% tab title="FOK" %}

```ts
// All 100 shares at 66¢ or better, or nothing at all.
await client.orders.place({
  tokenId, side: 'BUY', price: 0.66, quantity: 100, orderType: 'FOK',
});
```

{% endtab %}

{% tab title="FAK" %}

```ts
// Take whatever is resting at the touch, cancel the rest.
// This is the tick-safe way to "sweep" a book.
await client.orders.place({
  tokenId, side: 'SELL', price: bestBid, quantity: 100, orderType: 'FAK',
});
```

{% endtab %}
{% endtabs %}

### Validation rules

Break one of these and you get a `400` before the order ever reaches the book:

<table><thead><tr><th width="240">Rule</th><th>Detail</th></tr></thead><tbody><tr><td>Price grid</td><td>A multiple of the event's <code>tickSize</code> (<code>0.01</code> or <code>0.001</code>), and of <code>0.0001</code> overall.</td></tr><tr><td>Price bounds</td><td><code>0.0001 ≤ price ≤ 0.9999</code>. Exactly 0 or 1 is rejected.</td></tr><tr><td>Minimum value</td><td><code>price × quantity ≥ $1.00</code>.</td></tr><tr><td>Market state</td><td>The market must be open and have <code>enableOrderBook: true</code>.</td></tr><tr><td>Balance</td><td>A buy holds <code>price × quantity</code> USDC; a sell holds the shares. Both are reserved until the order is filled or cancelled.</td></tr><tr><td>Open orders</td><td>Up to <strong>2,000</strong> open orders per API-key account.</td></tr></tbody></table>

{% hint style="info" %}
**Self-trading is rejected.** A buy that would cross your own resting sell (or the equivalent on the sibling outcome, in YES terms) is refused with a message naming the order it hit. Cancel first, then re-quote — or use [`cancelBatch`](#cancelling) in the same cycle.
{% endhint %}

## Market orders

A market order sweeps the book instead of naming a price. **Sizing differs by side, because the units differ:** a buy is capped by the USDC it may spend, a sell by the shares it sells.

{% tabs %}
{% tab title="Market BUY" %}

```ts
const { order, executionPlan } = await client.orders.placeMarket({
  tokenId,
  side:     'BUY',
  maxSpend: 100,          // USDC — never spends more than this
});

executionPlan.submittedQuantity;        // "153.846154" shares
executionPlan.limitPrice;               // "0.66" — worst level the sweep reaches
executionPlan.estimatedAveragePrice;    // "0.6534"
executionPlan.estimatedQuoteAmount;     // "99.998..."
```

{% endtab %}

{% tab title="Market SELL" %}

```ts
const { order, executionPlan } = await client.orders.placeMarket({
  tokenId,
  side:           'SELL',
  quantity:       50,        // shares
  timeInForce:    'FAK',     // fill what's there, cancel the rest
  maxSlippageBps: 50,        // optional: abort if the sweep is worse than 0.5%
});

// If your wallet held fewer shares than requested, the order is trimmed and
// executionPlan.availableQuantity tells you what was actually submitted.
```

{% endtab %}
{% endtabs %}

`timeInForce` defaults to **`FOK`** — all or nothing. Pass `'FAK'` to accept a partial sweep.

{% hint style="info" %}
`executionPlan` is a **plan, not a fill report**. Every field is a decimal string (these are money and share counts; floats would round them). The fills arrive over the WebSocket.
{% endhint %}

### Two behaviours that surprise people

{% hint style="danger" %}
**1. A market BUY only takes resting asks on the same token.** It does not mint-cross into the sibling outcome's bids. On a book with bids but no asks it fails with `no_liquidity`, even though the screen shows plenty of size. To lift a resting bid on the other leg, place a **crossing limit buy on the sibling token at `1 − bidPrice`**.

**2. A market SELL's computed price can land off-tick** and be rejected on a coarse-tick market. Prefer a tick-aligned crossing limit sell at the best bid with `orderType: 'FAK'` — same effect, no rounding surprise.
{% endhint %}

```ts
// The reliable "take the bid" pattern on a 0.01-tick market:
const { price: bestBid } = await client.orderbook.price(tokenId, 'sell');
await client.orders.place({ tokenId, side: 'SELL', price: bestBid, quantity: 50, orderType: 'FAK' });
```

## Batch orders

Up to **15** orders in one round-trip. Each is validated independently — one failure does not roll back the rest.

{% code title="Quote both sides at once" %}

```ts
const results = await client.orders.placeBatch([
  { tokenId: yesTokenId, side: 'BUY',  price: 0.60, quantity: 100, orderType: 'GTC' },
  { tokenId: yesTokenId, side: 'SELL', price: 0.64, quantity: 100, orderType: 'GTC' },
]);

for (const r of results) {
  if (r.success) console.log(`#${r.index} placed ${r.order.orderHash}`);
  else           console.error(`#${r.index} rejected: ${r.error}`);
}
```

{% endcode %}

`index` maps each result back to the order you submitted, in the order you submitted them.

## Cancelling

<table><thead><tr><th width="290">Call</th><th width="130">Rate limited</th><th>Use for</th></tr></thead><tbody><tr><td><code>orders.cancel(orderHash)</code></td><td><strong>Yes</strong></td><td>A single order, off the hot path.</td></tr><tr><td><code>orders.cancelBatch(hashes)</code></td><td>No</td><td>Up to 100 specific orders — the requote path.</td></tr><tr><td><code>orders.cancelAll({ … })</code></td><td>No</td><td>Everything, or one token / one market. The kill-switch.</td></tr></tbody></table>

```ts
await client.orders.cancel(order.orderHash);

const { cancelled, failed } = await client.orders.cancelBatch([h1, h2, h3]);

await client.orders.cancelAll();                     // everything
await client.orders.cancelAll({ tokenId });          // one outcome
await client.orders.cancelAll({ marketId });         // one market
```

{% hint style="danger" %}
**`cancelAll()` is the most important call in your bot.** It is deliberately exempt from rate limiting, because cancels only ever remove risk. On a disconnect, a model failure, an unhandled exception, or shutdown — fire it first, ask questions later.
{% endhint %}

Three things to know about cancel results:

1. **Single cancel&#x20;*****is*****&#x20;rate limited.** It shares the order-write budget with placements, so it can return `429` under load. Prefer the bulk paths in a loop.
2. **A failed cancel means the order is still live.** Never assume it's gone — quoting against an assumed-dead order is how you self-trade.
3. **Bulk results are counts, not lists.** Orders that were already filled, cancelled, or locked in settlement (`HOLD`) are skipped and counted in `failed`. Re-list your open orders next cycle to pick them up once settlement confirms.

{% hint style="info" %}
Only `OPEN` orders can be cancelled. Once any part of an order is matched, cancelling would race the in-flight settlement, so the venue refuses — that quantity is committed.
{% endhint %}

## Listing your open orders

```ts
const open = await client.orders.list();                          // all of them
const forMarket = await client.orders.list({ marketId });         // scoped
```

Returns your `OPEN` and `PARTIALLY_FILLED` orders. The response is always scoped to the caller — for aggregated market depth use the [public order book](/typescript-sdk/orderbook.md).

{% code title="What's actually still resting" %}

```ts
for (const o of await client.orders.list()) {
  const resting = Number(o.quantity) - Number(o.filledQuantity) - Number(o.holdQuantity);
  console.log(`${o.side} ${resting}/${o.quantity} @ ${o.price}  ${o.status}`);
}
```

{% endcode %}

{% hint style="warning" %}
Subtract **`holdQuantity`** as well as `filledQuantity`. The two-term version looks correct and overstates your resting size for the \~15–20 seconds a settlement is in flight.
{% endhint %}

## The Order object

{% code title="Every field is a decimal string" %}

```ts
interface Order {
  id: string;
  orderHash: string;          // cancel handle
  walletAddress: string;
  marketId: string;
  tokenId: string;
  side: 'BUY' | 'SELL';
  price: string;              // "0.65"
  quantity: string;           // "100"
  filledQuantity: string;     // settled
  holdQuantity: string;       // matched, settlement in flight
  status: OrderStatus;
  timeInForce: 'GTC' | 'GTD' | 'FOK' | 'FAK';
  expiredAt: string | null;
  createdAt: string;
  updatedAt: string;
}
```

{% endcode %}

Prices and quantities come back as strings on purpose — they are exact decimals on the wire, and parsing them as floats is how rounding bugs get into money. Convert at the edge, keep the string as your record.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://dev.strixlab.io/typescript-sdk/orders.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
