---
title: "AgentMail compatibility"
description: "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."
canonical: "https://machinemail.dev/docs/reference/agentmail-compatibility"
---

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

Source: https://machinemail.dev/docs/reference/agentmail-compatibility

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](https://machinemail.dev/compare/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:

- 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](https://machinemail.dev/docs/reference/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](https://machinemail.dev/docs/reference/authentication#agent-access-tokens).                                                                                                                      |
| 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](https://machinemail.dev/docs/reference/webhook-events#verifying-signatures).                                                                                      |
| 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](https://machinemail.dev/docs/reference/limits#messages-and-attachments).                                                                                                     |
| 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.                                                                                                                                                                                                                                          |
| DNS conflict check             | `dns_conflicts` on domains: the records a domain already has that conflict with the ones to publish (MX records of another mail provider, an SPF record at the same name), each with how to resolve it. Conflicts never refuse a domain, so AgentMail's `allow_conflicting_provider` has nothing to allow.                                                   |
| 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](https://machinemail.dev/docs/reference/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.                                                                                                                                                                                                                                                                                 |
