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

# Rate Limits

> Current request budgets for reads and trading, and how to handle 429 responses.

Each endpoint belongs to a rate-limit class. Each class has a budget per **account** and a smaller budget per **API key**, both counted over fixed 60-second windows. **Both limits apply**: a request is admitted only if neither the account budget nor the key budget for its class is used up.

> [!NOTE]
>
> These are the **current** limits. They may change, and trading budgets can differ between environments. Do not hard-code them as guarantees. Always respect `Retry-After`.

## Read endpoints

| Class | Endpoints | Per account / 60 s | Per key / 60 s |
| - | - | - | - |
| Light | `GET /status`, `GET /balances`, `GET /markets/{instrumentId}` | 600 | 360 |
| Catalog | `GET /markets`, `GET /positions` | 120 | 72 |
| History | `GET /orders`, `GET /orders/{orderId}`, `GET /fills`, `GET /executions` | 240 | 144 |
| Book | `GET /markets/{instrumentId}/orderbook` | 300 | 180 |

`/fills` and `/executions` share the History budget.

## Trading endpoints

| Class | Endpoint | Per account / 60 s | Per key / 60 s |
| - | - | - | - |
| Place | `POST /orders` | 500 | 300 |
| Cancel | `POST /orders/{orderId}/cancel` | 450 | 270 |
| Cancel all | `POST /orders/cancel-all` | 50 | 30 |

Cancellation has its own budgets, so heavy quoting can never use up your ability to cancel. A retried placement that returns an existing order (`duplicate: true`) still counts against Place.

## How budgets are counted

* **Classes are independent.** Heavy order-book polling does not use up your budget for balances, executions or trading.
* **Per-key share.** One key can use up to 60% of the account's budget for a class, so one key cannot starve the other. Both keys together stay within the account budget. Adding a key does not add capacity.
* **What counts.** Every authenticated request counts, including one later refused with `400`, `409` or `422`. Requests that fail authentication (`401`/`403` from the key check) are refused before anything is counted.
* **Fixed windows.** Budgets reset at the start of each 60-second window, not on a rolling basis.

## When you are limited

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Cache-Control: no-store
Content-Type: application/json; charset=utf-8

{ "error": "RATE_LIMITED", "message": "Too many requests. Retry after the indicated delay." }
```

`Retry-After` is a whole number of seconds and is at least `1`. A `429` means the request was **not admitted**: nothing was done, so retrying the same request is safe.

Usually `Retry-After` is the time until the current window ends. Under a burst of simultaneous requests, D1 can also briefly refuse admission with `Retry-After: 1` even though your budget is not used up. Handle both the same way:

> Treat `429` as retryable and respect `Retry-After`.

For automated clients:

* wait at least `Retry-After` seconds before retrying, and add a small random jitter;
* if `429`s continue, back off further, up to a bounded maximum;
* do not retry from many workers at the same instant;
* keep a placement's `clientOrderId` unchanged across retries.

Successful responses do not include rate-limit headers, so pace your requests yourself rather than waiting to hit `429`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.