# AgentMail compatibility

> How MachineMail's /v0 API compares with AgentMail's: what works the same, what differs, what is missing, how to switch and what MachineMail adds.

MachineMail's `/v0` API is wire-compatible with [AgentMail](https://docs.agentmail.to)'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](/content/compare/agentmail/index.html).

## 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:

- JSON is snake_case: `organization_id`, `api_key_id`, `pod_id`, `inbox_id`, `thread_id`, `message_id`, `draft_id`, `webhook_id`, `domain_id`.
- `inbox_id` is the email address, as in AgentMail.
- Pagination is `limit` and `page_token`; responses carry `count`, `limit` and `next_page_token`.
- `client_id` on create is an idempotency key: the same `client_id` returns the existing resource.
- Enums match AgentMail: domain `status` (`NOT_STARTED`, `PENDING`, `INVALID`, `FAILED`, `VERIFYING`, `VERIFIED`), DNS record `status` (`MISSING`, `INVALID`, `VALID`) and `type` (`TXT`, `CNAME`, `MX`), inbox `status` (`active`, `paused`), draft `send_status` (`scheduled`, `sending`, `failed`), list `direction` (`send`, `receive`) and `type` (`allow`, `block`).
- API key permissions use AgentMail's names (`inbox_read`, `message_send`, ...) and its object-of-booleans format.

## Switching from AgentMail

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

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.

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](/content/docs/reference/errors/index.html).                                                                                                                                                                             |
| 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](/content/docs/reference/authentication#agent-access-tokens/index.html).                                                                                                                      |
| 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](/content/docs/reference/webhook-events#verifying-signatures/index.html).                                                                                      |
| 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](/content/docs/reference/limits#messages-and-attachments/index.html).                                                                                                     |
| 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 (`/drafts/{draft_id}/attachments/...`, `/threads/{thread_id}/attachments/...`) | 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|jsonl`.                                                                                                                                                                                                                                                                                                      |
| 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](/content/docs/reference/mcp-tools/index.html).                                                                                                                                                                                                                                 |
| 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.
