Skip to content

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.

LimitUnitScope
Enrollment creation limitLifetime successful inbox createsEnrollment key, stored as max_mailboxes and used_count
Message content1,800,000 encoded bytes, including headers, both bodies and attachmentsOne email
Message recipients50 combined To/Cc/Bcc entriesOne email
Attachments20 files sharing the message-size budgetOne email
Daily send limitRecipients delivered in a rolling 24-hour windowInbox
Request rateAPI requests in the configured windowAgent key or route
Project and inbox capacityActive resourcesBilling plan and project
Domain purchase authorityMoney, domain count, extension, premium status, and cadenceMatching organization, project, and agent purchase limits
Wait budgetSeconds or milliseconds per waitRequest and server configuration

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.

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 / reasonMeaningRecovery
quota_exceeded / inbox_limit_exceededBilling account inbox capacity; used and limit cover every organization and project sharing the accountAn authorized administrator can delete unused inboxes or change the account plan
enrollment_token_mailbox_budget_exhaustedLifetime creations shared by agents enrolled through that keyAsk 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.

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 429 and Retry-After.

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.

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

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.

Code or statusMeaningResponse
quota_exceededA lifetime, active-resource, or recipient quota blocks the requestRead the detail and current limit; do not retry unchanged
rate_limitedRequest rate is too highWait for Retry-After, then retry with jitter
intent_requiredReview policy requires reviewer contextAdd intent.summary; nothing was sent or queued
recipient_suppressedAt least one recipient cannot receive this messageRemove or resolve the blocked recipient before retrying
awaiting_human_approvalA commerce request needs a personSurface the approval URL and poll at the recommended interval