Rate limits and quotas
Several independent limits can affect one request. Read the status, problem code, details, and
Retry-After header instead of inferring the cause from a single counter.
Limit summary
Section titled “Limit summary”| Limit | Unit | Scope |
|---|---|---|
| Enrollment creation limit | Lifetime successful inbox creates | Enrollment key, stored as max_mailboxes and used_count |
| Message content | 1,800,000 encoded bytes, including headers, both bodies and attachments | One email |
| Message recipients | 50 combined To/Cc/Bcc entries | One email |
| Attachments | 20 files sharing the message-size budget | One email |
| Daily send limit | Recipients delivered in a rolling 24-hour window | Inbox |
| Request rate | API requests in the configured window | Agent key or route |
| Project and inbox capacity | Active resources | Billing plan and project |
| Domain purchase authority | Money, domain count, extension, premium status, and cadence | Matching organization, project, and agent purchase limits |
| Wait budget | Seconds or milliseconds per wait | Request and server configuration |
Message size and recipient count
Section titled “Message size and recipient count”Aim for about 1 MB of attachment files in total with a short body. The exact message-size limit is measured after encoding; it is not a raw-file allowance. Larger bodies leave less room for attachments. A 1.5 MB file can exceed the limit once encoded.
API, SDK, MCP and paid SMTP messages use the same limits, including replies,
forwards and revised drafts. Base64 encoding and line wrapping make attachments
about 37% larger than their files on disk. Use links for larger files. Oversized
email returns HTTP 413 or SMTP 552 5.3.4; exceeding the recipient count returns
HTTP 400 or SMTP 550 5.5.3. These are separate from daily/monthly quotas.
See Outbound message limits for examples, reserved delivery-header space and how refused edits preserve drafts.
Lifetime inbox creation
Section titled “Lifetime inbox creation”An enrollment key stops creating inboxes after used_count reaches max_mailboxes. The server owns
the counter, so copying the key does not create another allowance. Deleting an inbox does not refund a
lifetime slot.
The wire fields retain mailbox for compatibility. User-facing instructions and console labels use inbox.
Billing account capacity is separate and shared across all organizations and projects billed to
that account. A key showing 5/7 has used five lifetime creations, but creation can still fail when
the billing account is at 10/10 inboxes. Raising the key allowance does not raise account capacity.
Deleting unused inboxes frees account capacity but does not refund lifetime key slots. These counts
measure inboxes, not send volume.
A create failure identifies which limit blocked it:
| Error / reason | Meaning | Recovery |
|---|---|---|
quota_exceeded / inbox_limit_exceeded | Billing account inbox capacity; used and limit cover every organization and project sharing the account | An authorized administrator can delete unused inboxes or change the account plan |
enrollment_token_mailbox_budget_exhausted | Lifetime creations shared by agents enrolled through that key | Ask an administrator to raise the key allowance or issue a new key; deleting inboxes or upgrading the plan does not restore key slots |
The API message includes the limit source and counts. MCP and CLI also render the quota fields;
the TypeScript SDK preserves them on ApiError.body (reason, used, limit, remaining).
Do not infer an account cap from the number of inboxes visible to a scoped agent.
request_plan_change and list_commerce_requests require commerce:request. Without that scope,
relay the exact failure to an authorized billing administrator. A plan change is one recovery option,
not a requirement when unused inboxes can be removed.
Rolling recipient accounting
Section titled “Rolling recipient accounting”The default inbox limit is 75 recipients per rolling 24 hours. One message sent to three recipients
uses three units. The effective daily_send_limit may be set from 1 to 10,000 with
mailbox:quota; 0 on an enrollment key means the organization’s default should apply.
The limit is checked when a message is submitted and again before reviewed mail is released. The second check prevents a queued message from bypassing a limit that changed while it waited. Capacity is counted once, only when delivery occurs.
- A queued review is not billed send usage, but reserves its recipient units against the billing account’s daily and monthly allowance. Canceling returns those holds; recipient edits resize them atomically. The inbox’s rolling throttle is separate.
intent_required, suppression, and contact-list rejections consume none.- An over-limit response includes
429andRetry-After.
Request throttles
Section titled “Request throttles”When an API throttle applies, the response uses 429 Too Many Requests and includes Retry-After in
seconds. Back off with jitter and preserve the request’s idempotency value when retrying the same
mutation.
The TypeScript SDK retries eligible idempotent requests for transient failures. It does not make an
unsafe mutation idempotent by guessing. For send, reply, and forward, pass idempotency_key; for MCP
outbound mutations, pass client_id.
Wait limits
Section titled “Wait limits”REST and the TypeScript SDK default wait_for_email to 300 seconds and cap it at 600 seconds. MCP
defaults to 120 seconds and also caps at 600 seconds, subject to the packaged server’s configured
maximum. Client and proxy read timeouts must exceed the requested wait.
Review-event long-polls have their own shorter bounded interval. Follow each tool or endpoint’s published field rather than reusing the email wait budget.
Plan and project capacity
Section titled “Plan and project capacity”Plan limits apply to projects, active inboxes, and customer-controlled domains. They are checked in the same authorization path as resource creation. No credential permission bypasses plan capacity.
The commerce:request permission allows plan-change requests, not approval. Explicit Full account
control can approve through customer administrative actions. Downgrades that do
not fit the current resource count remain pending or blocked and never delete resources automatically.
Purchase limits
Section titled “Purchase limits”Domain purchase requests combine plan capacity with every matching organization, project, and agent purchase limit. Controls may restrict:
- a one-time, weekly, monthly, quarterly, or annual budget;
- maximum amount per purchase;
- maximum domains;
- allowed extensions;
- premium-domain authority.
The most restrictive matching result wins. Budget reservations prevent concurrent requests from overspending the same allowance. Unused recurring budget does not roll over.
Handle failures by code
Section titled “Handle failures by code”| Code or status | Meaning | Response |
|---|---|---|
quota_exceeded | A lifetime, active-resource, or recipient quota blocks the request | Read the detail and current limit; do not retry unchanged |
rate_limited | Request rate is too high | Wait for Retry-After, then retry with jitter |
intent_required | Review policy requires reviewer context | Add intent.summary; nothing was sent or queued |
recipient_suppressed | At least one recipient cannot receive this message | Remove or resolve the blocked recipient before retrying |
awaiting_human_approval | A commerce request needs a person | Surface the approval URL and poll at the recommended interval |