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

# Rate Limits

> Per-key request limits, response headers, and retry guidance

Every API key has per-minute request limits. Limits vary by endpoint based on computational cost.

## Limits by endpoint

| Endpoint                                  | Limit       | Rationale                         |
| ----------------------------------------- | ----------- | --------------------------------- |
| `POST /api/v1/classify`                   | **5 RPM**   | Analyzes PDFs; 10-30s per request |
| `POST /api/v1/check`                      | **60 RPM**  | Deterministic, sub-millisecond    |
| `GET /api/v1/courts`, `/judges`, `/rules` | **300 RPM** | Read-only lookups                 |

RPM = requests per minute, per API key. Limits use a sliding window (no burst-at-boundary problem).

## Response headers

Every response (including successful ones) includes rate limit headers:

| Header                  | Description                                 | Example      |
| ----------------------- | ------------------------------------------- | ------------ |
| `X-RateLimit-Limit`     | Maximum requests allowed in the window      | `5`          |
| `X-RateLimit-Remaining` | Requests remaining in the current window    | `3`          |
| `X-RateLimit-Reset`     | Unix epoch (seconds) when the window resets | `1709913600` |

## 429 response

When the limit is exceeded, the API returns `429 Too Many Requests`:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": "Rate limit exceeded",
  "suggestion": "Wait 30 seconds before retrying. See rate limit headers for usage details.",
  "docs_url": "https://docs.courtrules.app/api-reference/rate-limits",
  "contact": "api@courtrules.app"
}
```

The response also includes a `Retry-After` header with the number of seconds to wait.

## Retry guidance

1. **Read `Retry-After`** and wait at least that many seconds before retrying.
2. **Use exponential backoff** if you receive multiple 429s in a row: wait 1s, 2s, 4s, etc.
3. **Check `X-RateLimit-Remaining`** before sending requests to avoid hitting the limit in the first place.

## Common mistakes

**Tight-loop classify calls.** `/classify` is limited to 5 RPM because each request takes 10-30 seconds to analyze a PDF. If you need to process a batch, space requests at least 12 seconds apart or queue them server-side.

**Ignoring `Retry-After`.** Retrying immediately after a 429 wastes your remaining budget and delays recovery. Always respect the header value.

**Polling `/check` on every keystroke.** While `/check` has a generous 60 RPM limit, calling it on every form change in a UI can still exhaust it. Debounce to at most once per second.

## Need higher limits?

Contact [api@courtrules.app](mailto:api@courtrules.app) with your use case. We can increase limits for production integrations.
