Skip to content
On this site

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

The rate limit headers
HeaderMeaning
ratelimit-limitThe ceiling, 10. Constant, on every response.
ratelimit-remainingHow many requests are left in the bucket right now.
ratelimit-resetSeconds until the bucket is full again.
retry-afterWhole 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

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."
}
  • 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.