Rate limits & suppression
Sending is metered by two windows — a per-minute burst and a daily cap — sized to your plan; the rest of the API is metered per key. Recipients that bounce or complain are suppressed to protect deliverability.
Send budgets
Each send is checked against a per-minute burst window and a rolling 24-hour daily cap. Both are derived from your plan: the daily cap is the plan's email allowance, and the burst is 1% of it (floor 10/min).
| Plan | Per day | Per minute |
|---|---|---|
| free | 100 | 10 |
| starter | 1,000 | 10 |
| pro | 10,000 | 100 |
| scale | 100,000 | 1,000 |
The two windows are checked together and atomically: a rejected request consumes no budget in either window, so a client hammering into a 429 can never drain its daily quota. Organizations placed in a throttled state run on a reduced fraction (default 10%) of these numbers.
Platform limits
The non-sending /v1 surface — domains, mailboxes, audiences, broadcasts, templates, webhooks, analytics — is metered per API key rather than per plan:
| Requests | Limit |
|---|---|
| Writes (POST, PATCH, DELETE) | 60 / minute |
| Reads (GET) | 600 / minute |
The two run on separate windows, so polling a domain verification or a broadcast's progress cannot starve a write. Rejections carry the same Retry-After header as send budgets.
A handful of endpoints add their own guard on top — re-checking one domain's DNS, for instance, is limited to once per 30 seconds regardless of the key's remaining budget.
Handling 429
When a window is exhausted the request returns 429 rate_limited with a Retry-After header (in seconds) sized to when the oldest request in the window falls out — wait that long and a slot is guaranteed (barring new traffic).
// 429 + header: Retry-After: 37 { "error": { "code": "rate_limited", "message": "Sending too fast — per-minute burst limit reached" } }
429 (and 5xx) with exponential backoff, honouring Retry-After when present. Pair retries with an idempotency_key so a retry after a timeout can never send twice.Per-mailbox cap
Mail sent from a hosted mailbox (webmail / SMTP) additionally carries a fixed per-mailbox hourly cap — a compromised-mailbox guard, plan-independent. Transactional API sends via /v1/emails are governed by the org budgets above, not this cap.
Suppression list
Atrix Mail keeps a suppression list per organization (plus a global list). A recipient lands on it after a hard bounce or a spam complaint. Any send whose to, cc, or bcc includes a suppressed address is refused before it consumes budget:
// 422 { "error": { "code": "suppressed_recipient", "message": "One or more recipients are suppressed", "fields": { "ava@client.io": "hard_bounce" } } }
The fields map names each suppressed recipient and why. Suppression protects your sending reputation: repeatedly mailing addresses that bounce or complain is the fastest way to get filtered to spam. Remove the recipient from your own lists, or manage suppression entries from the dashboard.
| Status | Code | Meaning |
|---|---|---|
| 429 | rate_limited | Over a send window. Honour Retry-After. |
| 422 | suppressed_recipient | A recipient is on the suppression list. |
| 403 | org_suspended | The organization is suspended from sending. |