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

# Rate Limits

> Per-caller request limits on the LiveAvatar API

The LiveAvatar API enforces per-caller rate limits on every public endpoint. A caller that exceeds a limit receives a `429 Too Many Requests` response and should retry after the interval given in the `Retry-After` header.

## How limits are counted

Limits are counted per **caller** and per **endpoint**, over a fixed one-second window.

* **Per caller.** The caller is identified by the credential on the request: the `X-API-KEY` header for backend calls, or the `Bearer` session token for session-scoped calls. Unauthenticated requests are counted by client IP.
* **Per endpoint.** Each endpoint has its own counter. Requests to `GET /v1/avatars` do not consume budget for `GET /v1/voices`. Path parameters are ignored, so `GET /v1/sessions/{session_id}` shares one counter across all session IDs.
* **Fixed window.** The counter resets at the start of each one-second window. The `X-RateLimit-Reset` header reports the seconds remaining in the current window.

Because the identity is the API key rather than the account, two API keys in the same space have independent budgets.

## Limits by endpoint

| Endpoints                                                                           | Limit                | Counted per   |
| ----------------------------------------------------------------------------------- | -------------------- | ------------- |
| `POST /v1/sessions/token`                                                           | 10 requests / second | API key       |
| `POST /v1/sessions/start`, `POST /v1/sessions/stop`, `POST /v1/sessions/keep-alive` | 5 requests / second  | Session token |
| All other public endpoints                                                          | 10 requests / second | API key       |

Session lifecycle calls are counted per session token, so each active session has its own budget. A backend that manages many concurrent sessions is not throttled by their combined keep-alive traffic.

## Response headers

Every rate-limited endpoint returns these headers on both successful and rejected responses:

| Header                  | Description                                    |
| ----------------------- | ---------------------------------------------- |
| `X-RateLimit-Limit`     | Maximum requests allowed in the current window |
| `X-RateLimit-Remaining` | Requests remaining in the current window       |
| `X-RateLimit-Reset`     | Seconds until the current window resets        |

A rejected request also includes:

| Header        | Description                                                    |
| ------------- | -------------------------------------------------------------- |
| `Retry-After` | Seconds to wait before retrying. Equal to `X-RateLimit-Reset`. |

## Rejected requests

An over-limit request returns HTTP `429` with the standard error envelope:

```json theme={null}
{
  "code": 4290,
  "data": null,
  "message": "Rate limit exceeded"
}
```

The request is rejected before any processing, so a rejected call has no side effects.

## Handling limits

* **Honor `Retry-After`.** Windows are one second, so the wait is never longer than that. Retry after the given interval rather than immediately.
* **Watch `X-RateLimit-Remaining`.** When it reaches zero, pause until the window resets instead of sending a request that will be rejected.
* **Spread bursts.** Limits cap requests per second, not per minute. Ten calls in one second are rejected; ten calls spread across two seconds are not.
* **Reuse session tokens.** Minting a new token for every operation consumes the `POST /v1/sessions/token` budget. Mint one token per session and reuse it for lifecycle calls.

## Availability

Rate limiting is designed to fail open. If the limiter itself is unavailable, requests are allowed through rather than rejected, and no `5xx` is returned. Rate limit headers are still present on the response.
