Skip to content
machinemail

Limits

Inbox, address, TTL, message, attachment, batch, sandbox and retention limits.

These are the limits the API enforces today. Values marked “deployment default” are configuration on the hosted service at api.machinemail.dev and may change.

Inboxes and addresses

LimitValue
Number of inboxesNo limit on your own domains. Inbox count is not a quota.
Inboxes on the shared domain (machinemail.dev)1000 per organization (deployment default). Past that, creating one returns 403 Inbox limit reached for <domain> (1000 per organization). Add your own domain for more.
Username1 to 64 characters: a-z, 0-9, ., _, +, -; must start and end with a letter or digit. Input is trimmed and lowercased.
Username when omittedRandom, 12 characters.
Address uniquenessGlobal. An address taken by any organization returns 409 Inbox with email <email> already exists.
Domain on createDefaults to the shared domain. Any other domain must belong to your organization (404 Domain not found otherwise).
MetadataString values. No size or key-count limit is enforced.

Addresses on the shared domain are first come, first served across all organizations. Mail to an unknown address on the shared domain is never turned into a new inbox.

Ephemeral inboxes

SettingValue
ttl_secondsAny positive number of seconds. There is no maximum.
ephemeral: true without ttl_secondsTTL of 3600 seconds (one hour).
Expiryexpires_at = created_at + ttl_seconds. Every inbound message moves it to now + ttl_seconds (never earlier).
Changing itPATCH with a new ttl_seconds restarts the clock from now. ttl_seconds: null or ephemeral: false makes the inbox permanent.
DeletionAn expired inbox is deleted with its messages, threads, drafts and files within about a minute (the reaper runs every 60 seconds), and inbox.expired is emitted.

Catch-all domains

A custom domain with catch_all: true creates an inbox the first time mail arrives for an unknown address, when all of these hold:

  • the domain is VERIFIED (deployment default) and inbound_enabled is true;
  • the local part is a valid username.

The new inbox has created_by: "catch_all". If the domain sets catch_all_ttl_seconds (any positive number), the inbox is ephemeral with that TTL; otherwise it is permanent. inbox.created is emitted.

Messages and attachments

LimitValue
Recipients per messageAt least one of to, cc, bcc, and at most 50 (deployment default; MachineMail can change it, and the error states the cap in force) across all three, each address counted once (case-insensitive). An unclaimed agent sandbox inbox has a lower cap. More returns 400 Too many recipients: <n> across to, cc and bcc. A message can have at most 50 recipients; send separate messages instead. (param: to). Applies to sends, replies, reply-all, forwards, drafts (checked on create, update and send) and scheduled drafts (over the cap at send time: send_status: failed). An entry holding an address list (a@x.com, B <b@y.com>) counts, and is checked against suppressions and send lists, as each address in it. Each address must look like name@host.
Attachment by urlFetched by MachineMail: public http(s) only, no redirects, at most 25 MB, 20 second timeout.
Attachment by base64 contentNo separate limit.
Raw message injection (POST /inbound/raw)40 MB.
Preview (preview field)First 200 characters.
Attachment download_urlExpires one hour after the request (unless the storage backend signs its own expiry).
Suppressed recipientsSending to an address in suppressions returns 403. Permanent bounces and complaints add addresses automatically.
Paused inboxCannot send (403) or receive (mail is not stored; message.rejected is emitted).
LimitValue
Page size (limit)Default 50, maximum 500. See Pagination.
batch-get, batch-update100 message IDs per request; extra IDs are dropped.
Thread detailUp to 500 messages per thread in GET /v0/threads/{thread_id}. Thread label updates touch up to 500 messages.
Thread searchScans the newest 500 matching messages (truncated: true when more).
Inbox search (GET /v0/inboxes/search)Scans the newest 500 inboxes.
Allow and block listsUp to 500 entries per direction are applied to mail (the first 500 in entry order).
Metricsperiod 1 to 86400 seconds; default range the last 30 days; start must be before end; at most 100,000 events counted per query.
Export (GET /v0/inboxes/{inbox_id}/export)No limit: streams every message as mbox or jsonl.

Webhooks and events

LimitValue
Webhooks per organizationNo limit. Events are matched against the first 500 webhooks of an organization.
Webhook URLPublic http(s); private and loopback addresses are refused.
Delivery timeout10 seconds.
Retries1 m, 5 m, 30 m, 2 h, 12 h, then daily, for up to 5 days. See Webhook events.
Stored response bodyFirst 1024 bytes.
SSE resume (Last-Event-ID)Up to 500 missed events.
SSE keepalive: ping after 15 seconds without events.
WebSocket idle timeout120 seconds without traffic. Send {"type":"ping"} to keep it open.
MCP wait_for_messageUp to 60 seconds per call (default 30).

Domains

LimitValue
Domains per organizationNo limit.
Domain nameA valid hostname, 3 to 253 characters.
UniquenessA domain can belong to one organization only (409 Domain <domain> is already registered). The shared domain cannot be added (409 <domain> is a shared domain).
DNS checksPENDING and INVALID domains are re-checked in the background at most every 5 minutes, for 7 days after the domain was added. After that, call POST /v0/domains/{domain_id}/verify. Domain Connect discovery is cached for 6 hours (10 minutes after a provider error).

Pods

  • The default pod cannot be deleted.
  • A pod with inboxes cannot be deleted (409 Pod still has inboxes; delete them first).

Agent sandbox

An agent that registers itself anonymously through auth.md gets, until a person claims it:

LimitValue (deployment defaults)
InboxesOne sandbox inbox on the shared domain, agent-<12 characters>@machinemail.dev
Sandbox inbox lifetime24 hours
Messages10 per rolling 24 hours
Different recipients10 per rolling 24 hours (writing again to an address already counted is free)
Recipients per message5 (to, cc and bcc together; never more than the cap for every message)
Scopesinboxes.read, messages.read, messages.send, messages.write on that inbox only
Claim window24 hours
Access token lifetime1 hour
Registrations3 per rolling hour and 10 per rolling 24 hours per IPv4 address or IPv6 /64, 100 per hour across the service

The message, recipient and registration numbers are platform limits: MachineMail can change them at any time without notice, for example to stop abuse. The current values are in auth.md and in every error a cap returns. Every send counts when it is made: deleting sent messages or threads does not give any back. Claiming the agent lifts the sandbox caps. See Rate limits.

Credentials

ItemLifetime
API keyUntil revoked, or until its expires_at
Dashboard session30 days
Sign-in link15 minutes, single use
First API key display (GET /auth/first-key)10 minutes after first sign-in, once

Retention

Messages, raw MIME, attachments, events and webhook deliveries are kept until you delete them (or the inbox expires). There is no automatic retention window today.