# Rate limits

The per-endpoint and overall request limits on the Victoria AI API, the headers that report them, and how to handle a 429.

Requests are limited per API key over a one-minute window, and two limits apply at once:

| Limit | Requests per minute |
| - | - |
| Each endpoint | 100 |
| All endpoints combined | 600 |

Requests without a valid API key are limited by client IP address instead.

## Headers

Every response, including a `429`, reports where you stand against the endpoint's limit:

| Header | Meaning |
| - | - |
| `RateLimit-Limit` | Requests allowed to this endpoint per minute. |
| `RateLimit-Remaining` | Requests you can still send to this endpoint right now. |
| `RateLimit-Reset` | Seconds until the endpoint's full limit is available again. |

These headers describe the per-endpoint limit only. A request can exceed the 600-a-minute total while `RateLimit-Remaining` is still above zero.

## When you're limited

A request over either limit answers `429` with the error code `RATE_LIMITED` and a `Retry-After` header giving the number of seconds to wait. The request wasn't processed, so it's safe to send again once that time has passed.

**Node.js**

```javascript
async function fetchWithRetry(url, options, attempts = 5) {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429 || attempt === attempts) return response;
    const waitSeconds = Number(response.headers.get("Retry-After")) || 2 ** attempt;
    await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));
  }
}
```

**Python**

```python
import time

import requests


def request_with_retry(method, url, attempts=5, **kwargs):
    for attempt in range(1, attempts + 1):
        response = requests.request(method, url, **kwargs)
        if response.status_code != 429 or attempt == attempts:
            return response
        time.sleep(float(response.headers.get("Retry-After") or 2**attempt))
```

## Staying under the limits

- Spread bulk work out instead of sending it in bursts. 100 requests a minute to one endpoint is a little under two a second.
- Watch `RateLimit-Remaining` and slow down before it reaches zero.
- Request the largest page an endpoint allows when you list records. See [Pagination](https://docs.versionseven.ai/guides/pagination).
- Don't poll for replies. [Webhooks](https://docs.versionseven.ai/guides/webhooks) tell you when a prospect replies.
