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

# Errors and limits

> Status codes, plan restrictions, and how to handle 429s.

Error bodies are JSON with a `detail` string. Validation errors (`422`) use an array of field errors instead.

```json theme={null}
{ "detail": "Invalid or expired API key." }
```

## Status codes

| Status | When it happens                                              |
| ------ | ------------------------------------------------------------ |
| `400`  | Bad timestamp, date range, limit, or cursor                  |
| `401`  | Missing, invalid, or expired API key                         |
| `403`  | Plan does not allow this data point, resolution, or lookback |
| `404`  | Market or token not found                                    |
| `422`  | Parameter failed schema validation                           |
| `429`  | Requests-per-minute limit exceeded                           |
| `500`  | Unexpected server error                                      |

## Plan limits

Plans gate three things:

* Finest `resolution` (`1m` through `1d`)
* Rolling lookback window (`max_history_days`)
* Which of metrics, prices, and books you can query

`GET /v1/usage` returns the live values for your key:

```json theme={null}
{
  "plan": "trader",
  "organization": "Acme Corp",
  "limits": {
    "requests_per_minute": 100,
    "requests_remaining": 95,
    "granularity_allowed": "1m",
    "max_history_days": 30,
    "data_points": {
      "metrics": true,
      "prices": true,
      "books": true
    }
  },
  "reset_at": 1706184000
}
```

A history call outside those limits returns `403`, for example:

```json theme={null}
{ "detail": "Your plan does not allow historical order books." }
```

Compare your request to `GET /v1/usage` before you retry. Upgrading a plan takes effect immediately.

## Rate limits

`429` means you exhausted the current RPM window. `reset_at` on `/v1/usage` is the Unix timestamp when the window resets (null on unlimited plans).

```json theme={null}
{ "detail": "Rate limit exceeded. Please try again later." }
```

<Tip>
  Reuse a `requests.Session` (or the SDK client) and pace bursts. A short sleep between market loops is faster end-to-end than retrying `429`s.
</Tip>

The Python SDK retries `429` and `5xx` with exponential backoff and jitter. Tune `max_retries`, `retry_backoff_base`, `retry_backoff_max`, and `timeout` on `PolymarketDataClient`.

## History validation examples

| Problem                     | Typical `detail`                                                             |
| --------------------------- | ---------------------------------------------------------------------------- |
| `limit` above 200           | `limit too large. Requested: 250, Maximum: 200`                              |
| Market-level page too small | `limit too small for this market. Minimum required: 3`                       |
| Too many tokens             | `Market has more than 200 tokens. Use /v1/tokens/{token_id}/prices instead.` |
| Bad `resolution`            | `Input should be '1m', '10m', '1h', '6h' or '1d'`                            |

Standard coverage starts in August 2025. Asking for an earlier `start_ts` on a non-enterprise plan returns `403`.
