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

# Rate limits and quotas

> How the ScripX API meters requests: a per-minute sliding-window rate and a monthly call quota per key, the exact X-RateLimit response headers on every call, the public-surface per-IP limits, and how to back off correctly on a 429.

Every key is metered on two axes: a **per-minute rate** and a **monthly call quota**. The live numbers for your key are on every response, so you never have to look them up. Sandbox keys (`scripx_test_…`) are unmetered.

## Headers on every response

You never have to guess where you stand. Every authenticated response carries the live numbers:

| Header                   | Meaning                                    |
| ------------------------ | ------------------------------------------ |
| `X-RateLimit-Plan`       | The key's plan name                        |
| `X-RateLimit-Limit`      | Calls allowed per 60-second sliding window |
| `X-RateLimit-Remaining`  | Calls left in the current window           |
| `X-RateLimit-Reset`      | Seconds for the window to fully clear      |
| `X-RateLimit-Quota`      | Monthly call quota (absent when unmetered) |
| `X-RateLimit-Quota-Used` | Calls consumed this month                  |
| `Retry-After`            | On a 429 only: seconds to back off         |

The same numbers are available as JSON at [`GET /v1/usage`](/api-reference/account/usage).

## When you hit a limit

Exceeding either the per-minute rate or the monthly quota returns:

```json theme={"dark"}
{
  "error": "rate_limited",
  "code": "rate_limited",
  "message": "rate limit exceeded"
}
```

with HTTP `429` and a `Retry-After` header.

<Warning>
  The per-minute window is **sliding**, not fixed. Hammering the endpoint resets nothing and only pushes your recovery further out. Read `Retry-After` and wait exactly that long.
</Warning>

## Handling 429 correctly

1. On a `429`, sleep for the `Retry-After` seconds, then retry the same request.
2. Watch `X-RateLimit-Remaining` and slow down before you hit zero, rather than sprinting into the wall.
3. Spread bulk work: prefer [`POST /v1/orders:batch`](/api-reference/trading/orders-batch) (up to 500 orders in one call) over hundreds of single calls.
4. Never key retry logic on the `message` string; branch on the stable `code` (`rate_limited`). See [Errors](/errors).

## Idempotency and retries

Because retries are a normal part of living within a rate limit, make them safe. Send an `Idempotency-Key` on every [`POST /v1/orders`](/api-reference/trading/orders-create): re-sending the same key returns the original order instead of creating a second one, so a retry after a `429` or a network blip can never double-place.

## The public surface

The no-key [public rate index and enquiry endpoints](/api-reference/public/rates) are rate-limited **per IP**, independently of any API key:

* Rate endpoints (`/public/rates*`) use a normal per-IP budget and are CDN-cacheable.
* Enquiry endpoints (`/public/enquiry/*`) use a stricter per-IP budget.

A public 429 returns a `retry_after_s` hint in its `detail`. These limits protect the open surface and are separate from your metered key quota.

## Related

* [Authentication](/authentication), the header, scopes and error codes.
* [Usage](/api-reference/account/usage), the live meter as JSON.
* [Errors](/errors), the full error contract.
