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

# Rate limits

> Read the rate-limit headers, handle 429 with back-off, and stay a good client.

Requests are rate limited per API key. The API tells you where you stand on every
authenticated response — read the headers and back off when you approach the
limit. CreatorAudit does not publish specific numeric limits; rely on the headers
rather than hard-coding a number.

## Rate-limit headers

Every **authenticated** response includes:

| Header                  | Meaning                                          |
| ----------------------- | ------------------------------------------------ |
| `X-RateLimit-Limit`     | Your ceiling for the current window.             |
| `X-RateLimit-Remaining` | Requests left in the current window.             |
| `X-RateLimit-Reset`     | Unix timestamp (seconds) when the window resets. |

The unauthenticated `GET /health` and `GET /meta` are not rate limited and omit
these headers.

```http theme={null}
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 12
X-RateLimit-Reset: 1718354400
```

<Note>
  The values above are illustrative. Read `X-RateLimit-Remaining` and
  `X-RateLimit-Reset` at runtime instead of assuming a fixed limit — limits can change
  without a new API version.
</Note>

## When you hit the limit

Exceeding the limit returns `429` with `code: RATE_LIMITED` and a `Retry-After`
header giving the number of seconds to wait:

```json theme={null}
{
  "type": "urn:creatoraudit:error:rate-limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded.",
  "code": "RATE_LIMITED",
  "instance": "/v2/accounts",
  "request_id": "a1b2…"
}
```

Honor `Retry-After` when present, then fall back to exponential back-off. Slowing
down proactively as `X-RateLimit-Remaining` approaches zero avoids most `429`s.

```python theme={null}
import time
import httpx


def get_with_backoff(client: httpx.Client, url: str, *, max_attempts: int = 5):
    delay = 1.0
    for attempt in range(max_attempts):
        resp = client.get(url)
        if resp.status_code != 429:
            return resp
        # Prefer the server's hint; otherwise exponential back-off.
        wait = float(resp.headers.get("Retry-After", delay))
        time.sleep(wait)
        delay *= 2
    resp.raise_for_status()
    return resp
```

The same back-off pattern is a good fit for transient `503`
(`SERVICE_UNAVAILABLE`) responses. See [Errors](/api-reference/errors).

## Be a good client

* **Paginate efficiently.** Use the largest sensible `limit` (up to `200`) to
  fetch a page set in fewer calls. See [Pagination](/api-reference/pagination).
* **Cache with ETags.** `GET` responses carry a strong `ETag` and
  `Cache-Control: private, no-cache`. Send the value back as `If-None-Match`; an
  unchanged representation returns `304 Not Modified` with an empty body — a
  conditional request still counts, but you skip the re-download.
* **Skip `include_total` unless needed.** It adds a `COUNT` query per request.
* **Batch with the metrics endpoints.** Instead of polling many resources one at a
  time, use the batch windowed metrics endpoints — `POST /v2/accounts/metrics`,
  `POST /v2/videos/metrics`, and `POST /v2/account-videos/metrics` — and the video
  deltas endpoint to retrieve many records in a single call. See the
  [API reference](/api-reference/introduction) for these endpoints.
* **Spread out background jobs.** Add jitter and avoid bursts so you do not exhaust
  a window all at once.

For how rate limits sit alongside pagination caps, account quotas, and other
ceilings, see [Limits & quotas](/limits-and-quotas).
