Rate limits

The buckets, the headers, and how a refusal answers.

Every route checks a bucket before it runs. A refusal answers 429 with code rate_limited and a Retry-After header naming how many seconds to wait.

Three headers report the check furthest through its allowance, not the one with fewest requests left, because on a route that keys by contact the subject changes every request. Read X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (a unix timestamp).

The buckets

BucketWindowKeyed on
conversation_write60 per minutemember
conversation_read600 per minuteprincipal
conversation_bulk10 per minutemember
conversation_create10 per minute per contact, 30 per minute per IPcontact and IP
search10 per minute per key, 60 per minute per memberprincipal
report_read10 per minute per key, 60 per minute per memberprincipal
member_read600 per minutemember
member_write30 per minutemember
api_key_write30 per minutemember
messenger_boot20 per minute per contact, 120 per minute per IPcontact and IP
email_inbound600 per minuteenvelope recipient
email_domain_verify20 per hourworkspace

A search compiles to a scan, so an API key gets 10 a minute while a signed-in member gets 60 in a bucket of their own. The same split applies to report reads, which scan up to 92 days of rows. Outbound email has its own ceilings: 300 sends an hour per workspace, and 5 an hour to any one address, the loop guard for well-behaved exchanges the header refusals miss.

Note

These are the phase-1 limits, keyed on the member or the principal. Per-key and per-workspace tiers arrive with the public API; until then a key's budget is its owner's.