> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnibook.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate limits

> Two token buckets per key, and how to back off.

Limits are **per key**, not per IP or per account. Two independent token
buckets:

| Bucket | Covers                          | Sustained | Burst |
| ------ | ------------------------------- | --------- | ----- |
| Read   | every `GET`                     | 100/s     | 200   |
| Write  | orders, cancels, every mutation | 50/s      | 100   |

A bucket that starts full can emit `burst + sustained` requests inside one
second, so a read client can briefly reach 300 before throttling.

Batch order placement charges one token **per order in the batch**, not one per
request — a 20-order batch costs 20 write tokens.

## When you exceed a bucket

You get HTTP `429` with `rate_limited`, and the response body carries
`retry_after_ms` in `details`:

```json theme={null}
{
  "error": {
    "code": "rate_limited",
    "origin": "gateway",
    "details": { "retry_after_ms": 220 }
  }
}
```

Back off for that long and retry. A `429` is a soft throttle with no penalty —
you are not penalised for hitting it, and the next window is clean.

<Warning>
  `retry_after_ms` is in the response **body**, not in a `Retry-After` header.
  HTTP client libraries that back off automatically on `Retry-After` will not see
  it — read it from the body yourself.
</Warning>

## A 429 is not a suspension

Worth separating two different kinds of "no":

* **`429 rate_limited`** — a throttle. Back off, carry on.
* **Suspension** — a risk-management action against your account. Orders are
  refused until it is lifted. This is not something you retry your way out of.

If writes start failing with something other than `429`, stop and read the error
code rather than retrying harder.

## Staying under

* Poll market data on an interval rather than in a tight loop. Rounds last 60
  seconds; polling faster than a few times a second gains you nothing. Use the
  [WebSocket](/websocket/overview) for anything latency-sensitive.
* Batch order operations where you can — fewer requests, same token cost.
* Use one key per process. Two processes sharing a key share its buckets.

## Higher limits

Per-key overrides exist. If you have a market-making use case that needs more
than the defaults, get in touch rather than sharding across keys.
