Every response carries your current standing:

```
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 1754231400
```

Limits are counted per API key. Requests that never resolved a key are limited
per IP address at a much tighter rate, which is what a key-guessing loop runs
into.

| Tier            | Requests per minute |
| --------------- | ------------------- |
| Standard        | 300                 |
| Elevated        | 1200                |
| Unauthenticated | 60                  |

Contact us if your integration needs the elevated tier.

## Signing in as a person

The [app endpoints](/docs/api/apps/overview) count separately, because the thing
being protected is different: a sign-in attempt is worth guessing at, and an open
inbox polls.

| What                             | Limit                                                   |
| -------------------------------- | ------------------------------------------------------- |
| A signed-in device               | 600 requests a minute, per device                       |
| Resolving an environment         | 30 a minute, per address                                |
| Signing in                       | 10 attempts per 10 minutes per address, and 5 per email |
| Answering a two-factor challenge | 20 per 10 minutes per address, and 10 per challenge     |

The per-device limit means one person hammering their inbox never slows down a
colleague on the same office connection. A two-factor challenge is also spent
after five wrong codes regardless of the limit above.

## When you go over

You get `429` with `rate_limit_exceeded` and a `Retry-After` header in seconds:

```json
{
    "error": {
        "type": "rate_limit_error",
        "code": "rate_limit_exceeded",
        "message": "Too many requests. Slow down and retry after the window resets.",
        "request_id": "req_01kz4bkr1aj1gv63d8fv3133ey"
    }
}
```

:::tip Back off, do not hammer
Wait at least `Retry-After` seconds, then retry with exponential backoff. Retrying
immediately in a loop only keeps you rate limited for longer.
:::

Because limits are per key rather than per IP, one noisy integration cannot
throttle a different firm that happens to share an outbound address.