# Rate limits and retries

[Open in the interactive reference](https://docs.api.lensing.ai/?op=guide%3Alimits)

Requests are rate-limited per client IP address, across all endpoints, and every client behind the same address shares the limit. A client over the limit is refused with `429` until its request rate falls back below the limit.

The limit is not part of the contract and can change, so do not build against a number. Keep concurrency modest, and prefer one paged walk to many parallel requests.

A `429` has no body and no `Retry-After` header. Retry after a delay that doubles with each attempt, add random jitter so that clients do not retry in step, and give up after a few attempts.

### Retrying other failures

| Status | What to do |
| --- | --- |
| `429` | Back off and retry, as above. |
| `409 IDEMPOTENCY_KEY_CONFLICT` | Wait, then retry with the same key. |
| `500` | Retry once after a short wait, and retry a write only with the same `Idempotency-Key`. A `500` can also mean the API was briefly unavailable while your environment was being changed, which passes on its own. |
| `400, 401, 403, 404, 422` | Do not retry unchanged: the same request fails the same way. |

While your environment is being updated, a request waits up to 45 seconds for that to finish before it runs or fails. Set client timeouts longer than that.

## Examples

**Backing off, in Python**

```
import random, time

def send_with_backoff(send, attempts=6):
    delay = 1.0
    for attempt in range(attempts):
        response = send()
        if response.status_code != 429 or attempt == attempts - 1:
            return response
        time.sleep(delay + random.uniform(0, delay))
        delay *= 2
```
