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

# Rate Limits

> Request limits and how to handle 429 responses.

## Current limits

| Tier | Requests | Window |
| - | - | - |
| Default | 300 | Per minute, per API key |
| Bulk write endpoints | 60 | Per minute, per API key |
| Enrichment | 20 | Per minute, per workspace |

Bulk write endpoints include: `POST /lead-lists/{id}/enrich`, `POST /campaigns/{id}/leads` (when `lead_list_id` is used).

## Response headers

Every response includes rate-limit headers:

| Header | Description |
| - | - |
| `X-RateLimit-Limit` | Maximum requests in the window |
| `X-RateLimit-Remaining` | Requests remaining in the current window |
| `X-RateLimit-Reset` | Unix timestamp when the window resets |
| `Retry-After` | Seconds to wait (present only on 429 responses) |

## Handling 429s

When you hit a rate limit:

1. Read the `Retry-After` header
2. Wait that many seconds before retrying
3. Use exponential backoff for sustained high-volume workloads

```python theme={"dark"}
import httpx, time

def call_api(client, url):
    resp = client.get(url)
    if resp.status_code == 429:
        retry_after = int(resp.headers.get("Retry-After", "5"))
        time.sleep(retry_after)
        return call_api(client, url)
    return resp
```

## Tips for staying under limits

* **Paginate efficiently**, use the `cursor` param on list endpoints instead of fetching all pages at once
* **Batch lead enrollment**, use `lead_list_id` instead of individual `lead_ids` arrays
* **Cache read responses**, analytics and agent configs change infrequently
* **Webhook over polling**, register webhook endpoints instead of polling the jobs or conversations API


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.