Skip to content
Sendtier Docs
Error codes

rate_limited

HTTP status: 429

What happened

An API key exceeded the request rate, or the tenant exceeded a hard send cap. Organization creation caps return 422 organization_limit_reached with no Retry-After header.

PlanLive recipients per UTC dayLive recipients per UTC month
Free1003 000
ProNo daily cap100 000
ScaleNo daily cap1 000 000

Tenant overrides replace the plan defaults. Zero disables sends for that period. Test keys share a separate tenant cap of 1 000 recipients per UTC day and do not consume live caps. Each recipient counts, including recipients in batch and scheduled requests. Rejected requests create no email rows or usage debits. UTC days reset at midnight; months reset at midnight on the first day. GET /usage, with a full or read_only key, reports counts, effective limits (null means uncapped), and reset timestamps. A read_only key can access only /usage.

Every API key and every dashboard user has a request rate of 10 requests per second with burst capacity 20, shared across that caller's authenticated routes. The limiter key is the API key id or the dashboard user id. Replays and rejected authenticated requests count. X-RateLimit-* headers are returned on those authenticated customer routes. Platform system mail is not a customer endpoint and does not use these headers.

How to fix

Wait for the integer Retry-After seconds (at least 1). The error hint names the send cap and UTC reset, or the request rate. A 429 is not cached by idempotency; retry with the same Idempotency-Key after the wait.

Every authenticated response, including errors and replays, carries:

  • X-RateLimit-Limit: request rate per second, 10.
  • X-RateLimit-Remaining: remaining requests in the burst capacity.
  • X-RateLimit-Reset: Unix seconds, rounded up, when the burst fully replenishes.

These headers describe request admission; GET /usage describes send caps. On a Valkey error, request admission fails open and logs a WARN. The headers then report capacity 20 and a reset two seconds ahead as an estimate. Postgres send caps still enforce the hard stop. The worker send limiter in ADR-0016 remains fail closed; request admission does not spend worker tokens.

Source: docs/errors/rate_limited.md.

On this page