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

# Rate limits

> Per-endpoint rate limits, response headers, and retry strategy.

<Info>
  Denialbase enforces rate limits at two layers — Cloud Armor at the edge (per-IP) and Rack::Attack at the application (per-user). Both return `429 Too Many Requests` when exceeded, with a `Retry-After` header telling you how long to wait.
</Info>

## Application-level limits (per authenticated user)

| Endpoint group                     | Limit | Window     |
| ---------------------------------- | ----- | ---------- |
| General reads                      | 300   | 1 minute   |
| General writes                     | 60    | 1 minute   |
| Auth (login, password reset)       | 5     | 20 seconds |
| 2FA setup                          | 5     | 1 minute   |
| Passkey operations                 | 10    | 1 minute   |
| File uploads                       | 30    | 1 minute   |
| Email sending (per target address) | 3     | 5 minutes  |
| Token verification (magic links)   | 10    | 1 minute   |
| Data exports                       | 10    | 1 hour     |

## Edge limits (per IP)

| Environment | Threshold    | Action           |
| ----------- | ------------ | ---------------- |
| Staging     | 500 req/min  | 5-minute 429 ban |
| Production  | 1000 req/min | 5-minute 429 ban |

## Response headers

When a rate limit is in effect or hit, we return:

| Header                  | Meaning                                  |
| ----------------------- | ---------------------------------------- |
| `X-RateLimit-Limit`     | The limit that applies                   |
| `X-RateLimit-Remaining` | Requests remaining in the current window |
| `X-RateLimit-Reset`     | Unix timestamp when the window resets    |
| `Retry-After`           | Seconds to wait (only on 429)            |

## Retry strategy

<Steps>
  <Step title="On 429">
    Sleep for `Retry-After` seconds, then retry. Don't ignore the header — ignoring it will get you edge-banned for 5 minutes.
  </Step>

  <Step title="On 5xx">
    Exponential backoff: 500ms, 1s, 2s, 4s, 8s, 16s, 30s cap. Give up after 5–7 attempts.
  </Step>

  <Step title="Use idempotency keys for writes">
    See [Errors → Idempotency](/api-reference/errors#idempotency-example).
  </Step>
</Steps>

## Best practices

* **Cache** read responses where appropriate; `GET` responses include `ETag` headers for conditional requests (`If-None-Match`).
* **Batch** where batch endpoints exist — a single call to `POST /api/v1/documents/bulk` is better than 50 serial uploads.
* **Webhook** for event notifications rather than polling (see [Webhooks](/integrations/webhooks)).
* **Paginate** list endpoints — don't pull more than you need. Default page size is 25; max is 100.

## Higher limits

Enterprise customers with legitimate high-volume workflows (bulk ingestion, clearinghouse batch uploads) can request higher limits via [support@denialbase.com](mailto:support@denialbase.com). We're not in the business of rate-limiting paying customers out of core workflows — but we do want to know the shape of your traffic to keep the platform healthy.
