# Rate limits

10 requests per second per team, shared across every API key the team holds. Four headers tell you where you stand.

## The limit

The bucket holds 10 tokens and refills at 10 a second, so a short burst of 10 is fine and a sustained rate above 10 a second is not.

> The limit is per **team**, not per key. Creating a second API key does not buy more capacity — every key on the team draws from the same bucket.

## The headers

| Header | Meaning |
| --- | --- |
| `ratelimit-limit` | The ceiling, 10. Constant, on every response. |
| `ratelimit-remaining` | How many requests are left in the bucket right now. |
| `ratelimit-reset` | Seconds until the bucket is full again. |
| `retry-after` | Whole seconds to wait. Present only on a `429`, and never zero. |

The first three are on every response, successful or not, so you can slow down before you are refused rather than after.

## Being refused

A rate limited response:

```text
HTTP/1.1 429 Too Many Requests
ratelimit-limit: 10
ratelimit-remaining: 0
ratelimit-reset: 1
retry-after: 1

{
  "statusCode": 429,
  "name": "rate_limit_exceeded",
  "message": "Too many requests. You can only make 10 requests per second."
}
```

- Wait for `retry-after` seconds, then retry. It is never zero, so a client that multiplies it can always make progress.
- Add jitter. Several workers that all wait exactly one second will collide again one second later.
- Use an `Idempotency-Key` on sends, so a retry after a refusal cannot become a second email.

## Sending a lot at once

`POST /emails/batch` is one request for up to a hundred messages, which is one token rather than a hundred. If you are being rate limited by a loop over individual sends, a batch is the fix.
