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

# AuditRails API Rate Limits: Tiers, 429 & Retry Logic

> Understand AuditRails' three-tier rate limiting model, how 429 responses work, and how to build clients that handle limits gracefully.

AuditRails enforces rate limits to ensure fair, stable throughput for all customers. There are three independent limit tiers applied in sequence on every request. Exceeding any single tier returns a `429 Too Many Requests` response — understanding each tier helps you stay well within bounds and design resilient integrations.

***

## The Three Tiers

| Tier                     | Scope                               | Limit       | Window           | Notes                                                                   |
| ------------------------ | ----------------------------------- | ----------- | ---------------- | ----------------------------------------------------------------------- |
| **Per-IP**               | All traffic, unauthenticated or not | 100 req/s   | 1 second (fixed) | Applied before authentication; protects against unauthenticated floods. |
| **Per-plan (live keys)** | Requests using `at_live_` keys      | 1,000 req/s | 1 second (fixed) | Default limit; applies to your entire plan across all live keys.        |
| **Test keys**            | Requests using `at_test_` keys      | 60 req/s    | 1 second (fixed) | Shared pool across all AuditRails test-key users; not for production.   |

All windows are **fixed-window, 1-second** intervals. Counters reset at the top of each second — there is no rolling window or token-bucket smoothing.

<Note>
  A `POST /v1/events/batch` request counts as **one request** against all tiers, regardless of how many events are in the payload (up to the 100-event maximum). Batching is the most efficient way to ingest high volumes while staying within limits.
</Note>

***

## 429 Response & Retry-After

When you exceed a rate limit, AuditRails responds with HTTP `429 Too Many Requests` and a `Retry-After` header indicating how many seconds to wait before retrying.

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Content-Type: application/json

{
  "error": {
    "code": "rate_limit/exceeded",
    "message": "You have exceeded the rate limit for this key. Retry after 1 second.",
    "request_id": "req_01HX7YGBFZ3QK8N9VMJT5RPCE4",
    "doc_url": "https://docs.auditrails.io/reference/error-codes"
  }
}
```

<Info>
  AuditRails does **not** include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, or `X-RateLimit-Reset` headers on successful responses. Use the `Retry-After` header on 429 responses to drive your back-off logic.
</Info>

***

## Handling Rate Limits in Your Code

### Respect Retry-After

Always parse the `Retry-After` header value (in seconds) and wait at least that long before resending a request. A value of `1` is typical given the 1-second fixed window.

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

def post_event(payload, api_key):
    while True:
        response = requests.post(
            "https://api.auditrails.io/v1/events",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json=payload,
        )
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 1))
            time.sleep(retry_after)
            continue
        response.raise_for_status()
        return response.json()
```

### Use Batch Ingestion

If you are sending many events in a tight loop, switch to `POST /v1/events/batch`. A single batch request of 100 events consumes only 1 request from your per-plan quota — a 100× improvement in throughput efficiency.

```bash theme={null}
curl -X POST https://api.auditrails.io/v1/events/batch \
  -H "Authorization: Bearer at_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      { "action": "user.login",  "actor_id": "user_001" },
      { "action": "user.logout", "actor_id": "user_002" }
    ]
  }'
```

### SDK Auto-Retry

All official AuditRails SDKs automatically retry `5xx` server errors with **exponential back-off**. While SDKs do not automatically retry `429` responses (to avoid thundering-herd issues), they surface the `Retry-After` value so you can implement the wait loop shown above.

<Warning>
  Do not implement aggressive retry loops without honouring `Retry-After`. Hammering the API after a 429 prolongs the window in which your requests are being dropped and may trigger stricter protective limits.
</Warning>

***

## Increasing Your Limits

Default plan limits cover the vast majority of production workloads. If you have a use case that requires sustained throughput above 1,000 req/s on live keys, contact the AuditRails sales team to discuss a custom plan.

<CardGroup cols={2}>
  <Card title="Talk to Sales" icon="phone" href="https://auditrails.io/contact-sales">
    Request a higher rate limit or discuss an enterprise plan tailored to your ingestion volume.
  </Card>

  <Card title="Batch Ingestion" icon="layer-group" href="/api-reference/post-events-batch">
    Learn how to structure batch payloads and maximise throughput within your existing limits.
  </Card>
</CardGroup>
