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

# Rate limits

> The Operata API enforces 100 requests per minute per token. Reference for the rate-limit headers, the 429 response body, and the correct back-off pattern.

The Operata API caps each API token at 100 requests per minute. When you exceed the budget the API returns `429 rate_limited` with a `Retry-After` header. Back off and retry; do not retry without a delay.

## Endpoint

```http theme={null}
Any endpoint under https://api.operata.io
```

## Parameters

Rate limiting applies to every request. Three response headers show your current standing:

| Name                    | Type    | Required    | Description                                                                      |
| ----------------------- | ------- | ----------- | -------------------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | integer | yes         | The per-token request ceiling for the current window. Currently 100.             |
| `X-RateLimit-Remaining` | integer | yes         | Requests left in the current window. Hits zero before you receive 429.           |
| `X-RateLimit-Reset`     | integer | yes         | Unix epoch seconds when the window rolls over and `Remaining` resets to `Limit`. |
| `Retry-After`           | integer | on 429 only | Seconds to wait before the next request. Use this; do not invent your own delay. |

## Response

A throttled request returns the standard error envelope from [Errors](/docs/api-errors):

```json theme={null}
{
  "error": {
    "status": 429,
    "code": "rate_limited",
    "message": "You have exceeded the per-token rate limit of 100 requests per minute."
  }
}
```

The response headers tell you exactly when to retry:

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 17
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1747555417
Content-Type: application/json
```

## Example

A client that reads `Retry-After` and adds exponential back-off:

<CodeGroup>
  ```bash curl theme={null}
  # Inspect headers on every response.
  curl -i -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
    "https://api.operata.io/v1/data/calls?size=1"
  ```

  ```python Python theme={null}
  import os, time, requests

  def call_with_backoff(url, params, max_attempts=5):
      delay = 1.0
      for attempt in range(max_attempts):
          response = requests.get(
              url,
              auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
              params=params,
          )
          if response.status_code != 429:
              return response
          wait = int(response.headers.get("Retry-After", delay))
          time.sleep(wait)
          delay *= 2
      response.raise_for_status()

  call_with_backoff(
      "https://api.operata.io/v1/data/calls",
      {"fromTime": "2026-05-17T00:00:00Z", "toTime": "2026-05-18T00:00:00Z", "size": "50"},
  )
  ```
</CodeGroup>

## Errors

| Status | Code           | When                                                | Recover                                                                          |
| ------ | -------------- | --------------------------------------------------- | -------------------------------------------------------------------------------- |
| 429    | `rate_limited` | You exceeded 100 requests per minute on this token. | Wait `Retry-After` seconds, then retry. Add exponential back-off if 429 repeats. |

See [Errors](/docs/api-errors) for the full status code table.
