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

# Rate Limits

> Understand how API rate limits work and how to handle them gracefully.

## How limits work

Rate limits are enforced per API key, not per account. Each key can be configured with two independent windows:

| Limit field          | Description                                      |
| -------------------- | ------------------------------------------------ |
| `rateLimitPerMinute` | Maximum requests allowed in any 60-second window |
| `rateLimitPerHour`   | Maximum requests allowed in any 60-minute window |

You set these when creating a key. Keys with no explicit limit inherit the platform defaults.

## When a limit is exceeded

The API returns `429 Too Many Requests`:

```json theme={null}
{
  "status": false,
  "message": "Rate limit exceeded",
  "data": null
}
```

## Handling `429` responses

Always implement retry logic for rate-limited requests. Use **exponential backoff** — wait progressively longer between retries:

```javascript theme={null}
async function fetchWithBackoff(url, options, maxRetries = 4) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429) return response;

    const delay = Math.min(1000 * 2 ** attempt, 16000); // cap at 16s
    await new Promise((resolve) => setTimeout(resolve, delay));
  }
  throw new Error('Max retries reached');
}
```

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

def fetch_with_backoff(url, headers, max_retries=4):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers, timeout=30)
        if response.status_code != 429:
            return response
        delay = min(1 * (2 ** attempt), 16)
        time.sleep(delay)
    raise Exception("Max retries reached")
```

## Best practices

**Spread bursty workloads.** If you need to process a large batch of records, use a queue and throttle the dequeue rate to stay within your per-minute limit rather than firing everything at once.

**Create separate keys per workload.** High-volume background jobs should use a different key from interactive user-facing flows. This prevents a batch job from consuming the limit that would block real-time requests.

**Monitor request volume.** Log the response status of every API call. Alert on sustained `429` responses — it means your key limits need to be raised or your request rate needs to be reduced.

**Raise limits when needed.** Update `rateLimitPerMinute` and `rateLimitPerHour` on a key via `PATCH /v1/auth/keys/{id}/scopes` (or recreate the key with higher limits) as your traffic grows.
