AgentMail compatibility · MachineMail Docs

The rule

MachineMail’s /v0 API is wire-compatible with AgentMail’s. Code written against AgentMail’s API or SDKs works against MachineMail by changing the base URL and the API key. For the products rather than the API, see MachineMail vs AgentMail.

The rule

Wherever AgentMail’s published API defines a path, an enum value or a field name, MachineMail uses exactly that. MachineMail-only features use their own names and never change the meaning of an AgentMail field.

In practice:

Switching from AgentMail

  1. Create an API key in the MachineMail dashboard (or let your agent onboard itself through https://api.machinemail.dev/auth.md).

  2. Point your client at https://api.machinemail.dev. With AgentMail’s SDKs, set the base URL option to that value and the API key to your mm_live_... key.

  3. Use addresses on machinemail.dev, or add your own domain with POST /v0/domains.

Supported

Area Endpoints
Inboxes list, create, get, update (including pause), delete, search
Messages list, get, send, reply, reply-all, forward, update labels, delete, raw, attachments, batch-get, batch-update, search
Threads list, get, update labels, delete, search; at /v0/threads and /v0/inboxes/{inbox_id}/threads
Drafts list, create, get, update, delete, send; scheduled sends with send_at
Domains list, create, get, update, delete, verify, zone-file
Webhooks list, create, get, update, delete
Lists allow and block lists at /v0/lists, /v0/pods/{pod_id}/lists and /v0/inboxes/{inbox_id}/lists
Pods list, create, get, update, delete
API keys list, create, get, update, delete; organization, pod and inbox keys
Organization GET /v0/organizations
Metrics /v0/metrics/events, /v0/metrics/usage, /v0/metrics/rates
Scoped routes every resource under /v0/pods/{pod_id}/...; webhooks, lists, metrics, events and API keys under /v0/inboxes/{inbox_id}/...

Differences

Topic AgentMail MachineMail
Error body AgentMail’s error shapes One envelope on every /v0 route: {"error": {"type", "message", "param"?}}. See Errors.
Agent sign-up /v0/agent/sign-up, /v0/agent/human, /v0/agent/verify The auth.md protocol: POST /agent/identity, POST /agent/identity/claim, POST /oauth2/token. See Authentication.
Webhook signatures AgentMail’s own signing scheme X-MachineMail-Signature: t=...,v1=... (HMAC-SHA256 over <t>.<body>) plus X-MachineMail-Event, -Event-Id, -Delivery-Id. See Webhook events.
Webhook body event payload Same keys at the top level, plus type: "event", event_id, event_type, timestamp, and the payload again under data.
Creating keys body may carry pod_id / inbox_id The route sets the scope: POST /v0/pods/{pod_id}/api-keys, POST /v0/inboxes/{inbox_id}/api-keys. pod_id and inbox_id in the body are ignored.
Status codes 200 on create (per AgentMail’s spec) 201 on create and on sends, 200 when a client_id matches. Deletes return {"ok": true}.
Inbox events GET /v0/inboxes/{inbox_id}/events is a label-event log The same path returns MachineMail’s event log narrowed to the inbox.
Labels System labels are uppercase: INBOX, SENT, UNREAD, SPAM, BLOCKED, UNAUTHENTICATED, QUARANTINE, TRASH. Other labels are free strings.
Recipients no published per-message cap At most 50 recipients per message across to, cc and bcc, each address counted once; more is a 400 validation error. See Limits.
Authentication results authentication_results withholds SPF unless its domain aligns with the sender, and can report verdicts sealed by a trusted forwarder (arc_sealer) Same field, values and domain keys, and the same withholding: SPF only when its domain aligns with the sender, DKIM and DMARC only when From names one domain. The verdicts are the ones recorded by the receiving provider or MachineMail’s receiving server. ARC results are not used, so arc_sealer is not sent.
Organization billing and limit fields domain_limit is the plan’s custom-domain allowance. inbox_limit, billing and authentication fields are not returned. Inbox count is not a quota.

Not available

AgentMail feature Status
Calendar (/v0/inboxes/{inbox_id}/calendar/...) Out of scope
Apps and accounts (/v0/apps, /v0/accounts, .../accounts) Out of scope
Domain setup-link Not planned; MachineMail offers Domain Connect instead (GET /v0/domains/{domain_id}/domain-connect)
POST /v0/inboxes/{inbox_id}/authorize Not yet
Draft and thread attachment routes Not yet; use the message attachment route
Open tracking (track_opens, message.opened) Not available; track_opens is ignored
Fields accepted but ignored forward_of and reply_all on draft create, quarantine_threshold on inboxes, subdomains_enabled, tracking_enabled and allow_conflicting_provider on domains

MachineMail extensions

Extension Where
Trust reports trust on every inbound message, trust_level on list items, GET /v0/inboxes/{inbox_id}/messages/{message_id}/trust. Verdicts verified, known, unknown, suspicious, quarantined, with SPF/DKIM/DMARC results, classifier scores for spam, phishing and prompt injection, link and attachment analysis, and an agent-safe trust.content.text.
Quarantine Mail that looks like prompt injection or phishing gets the QUARANTINE label and the message.received.quarantined event, and is hidden from lists unless asked for.
Ephemeral inboxes ttl_seconds, ephemeral, expires_at on inboxes; inbox.created and inbox.expired events.
Catch-all domains catch_all and catch_all_ttl_seconds on domains: mail to an unknown address creates an inbox. Also inbound_enabled, feedback_enabled, nameservers, dns_provider, dns_provider_url.
Domain Connect GET /v0/domains/{domain_id}/domain-connect returns a one-click DNS setup link where the DNS provider supports it.
Event log and streams GET /v0/events (with after=<event_id> cursors), GET /v0/events/{event_id}, server-sent events at GET /v0/events/stream, WebSocket at /v0/ws.
Delivery inspection and replay GET /v0/webhooks/{webhook_id}/deliveries, POST .../deliveries/{delivery_id}/replay, POST /v0/webhooks/{webhook_id}/test.
Webhook custom headers headers on PATCH /v0/webhooks/{webhook_id} replaces or clears the whole set (AgentMail’s /headers endpoints, also served, merge). The webhook object lists header_names and headers_updated_at; values are never returned.
Suppressions /v0/suppressions: addresses that bounced, complained or were added by hand.
Export `GET /v0/inboxes/{inbox_id}/export?format=mbox
Extra event types message.received.quarantined, message.received.blocked, inbox.created, inbox.expired, draft.sent, webhook.test.
Extra fields direction, delivery_status, received_via and pod_id on messages; organization_id on inboxes, domains and keys.
Remote MCP server /mcp, with agent-safe tools such as wait_for_message. See MCP tools.
Agent onboarding auth.md (/auth.md, /agent/identity, /oauth2/token), /v0/agent-registrations.
Raw injection POST /inbound/raw with the inbound_raw permission, for testing with real MIME.
Lists A reply list direction, and entry_type (email or domain) on entries.