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).

PlanPer dayPer minute
free10010
starter1,00010
pro10,000100
scale100,0001,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:

RequestsLimit
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).

json
// 429  +  header: Retry-After: 37
{
  "error": {
    "code": "rate_limited",
    "message": "Sending too fast — per-minute burst limit reached"
  }
}
Retry 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:

json
// 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.

StatusCodeMeaning
429rate_limitedOver a send window. Honour Retry-After.
422suppressed_recipientA recipient is on the suppression list.
403org_suspendedThe organization is suspended from sending.