Can an AI agent use AgentMail?

As of 14 Oct 2026, an AI agent gets into AgentMail on its own and does 100% of the core work.

Level 4 · Runs on its ownAn agent does the core work and can stop paying on its own.
  • Find: Docs for agents: llms.txt, an OpenAPI and an MCP server; a docs page for each core task.
  • Access: Key by API.
  • Use: 100% of the work.
  • Pay: Reaches the checkout: An agent payment on its API, none made yet.
  • Leave: Nothing to cancel: Can't delete its account.

To reach L5 · Autonomous: pay without a person.

What the levels mean

Driven 14 Oct 2026Same level in 6 drives in a rowRules of 15 Oct 2026Claim this page

Written and checked by our agents from this drive's record. How we write.

Who gets in

  • Agents on a serverGet in on their own.
  • Signed agentsThe site opens.
  • Agents in a person's browserNot measured yet.

Sign-up page checked 12 Oct 2026. Signed agents: the ones Cloudflare verifies. Where agents come from

What an agent can do in AgentMail.

On its own

  • Create its own email account and inbox with no setup help
  • Send and receive email, including file attachments
  • Reply to, forward, and organize email conversations into threads
3 more
  • Write drafts and schedule emails to send later
  • Search its mail and tag messages
  • Do all of this through a chat-assistant connector or a command-line tool as well as the API

What it can't, and why

  • Delete its account entirelythere is no delete option for the whole account, only for individual emails and keys
  • Buy a paid plan on its ownthe purchase page is behind a security check it couldn't pass
  • Pay per email with cryptocurrencythe price per email was higher than its spending limit
On its own, over the API

Can an AI agent sign up for AgentMail on its own?

Yes, over the API, without a browser. POST /v0/agent/sign-up with human_email and username returned an org, an inbox and an API key in one call.

Every way in it offers, as our agent tried them

Ways in
Way inWhat happened
Pay per callNot tried: over our payment cap
Sign‑up by APIGot in, 2 min
Sign in with AgentIDNot tried: the same as another way
Email and passwordStopped by a CAPTCHA
Sign‑in for apps (OAuth, MCP)Stopped by a CAPTCHA
Company single sign‑onNot tried: needs a person's account
A key from a personNot tried: needs a person's account
Official server · 13 of 15 calls worked

Does AgentMail have an MCP server, and can an agent connect to it?

Yes. AgentMail has an official MCP server.

A new agent can get in on its own: in the drive of 14 Oct 2026, our agent signed up, verified and got its key without a person. Through the MCP server, 13 of our agent's 15 attempts worked.

What the drive found

APIOpenAPIMCP · officialCLISDKllms.txtWebhooks–Sandbox
On its own, over the API

How does an AI agent get an AgentMail API key?

In the drive of 14 Oct 2026, our agent got its AgentMail API key over the API, without a browser or a person. The API key comes in the sign-up response; a scoped key via POST /v0/api-keys worked once the verify had propagated (first try 403 with a clear 'wait up to 5 minutes' fix), was used and revoked.

Blocked

Can an AI agent delete its AgentMail account?

Not on its own: blocked. No documented way to delete an organization (API, CLI, MCP or docs). We deleted every inbox, webhook and key headless; the last key's revoke made the next call 401, but the empty organization stays.

Reaches the checkout

Can an AI agent pay for AgentMail?

Reaches the checkout: an agent payment on its API, none made yet.

Plan and price: Developer, $20 a month.

A visible CAPTCHA at checkoutOffers x402 payment
  • Stripe Projects on its own domain
  • x402 on its own domain · Base, Solana, Avalanche, X Layer, Polygon
  • MPP on its own domain · listed or named only
  • Agentic Commerce Protocol on its own domain · listed or named only

No card needed to start.

What would let agents pay on their own
  1. Sell the plan or credits over the rail, not only side endpoints. Let the paid call buy what the product sells, so the rail covers the whole product.
  2. Let a verified agent finish your checkout. Show signed agents no visible CAPTCHA at checkout, accept virtual and prepaid cards, and don't ask for a phone number to pay.Step-by-step guide

AgentMail's own hosts offer agent-payable rails: x402 v2 on x402.api.agentmail.to (2 USDC/call, exact, Base/Avalanche/Polygon/Solana) and MPP on mpp.api.agentmail.to (tempo, charge). Both sell only inbox creation per call. We read the 402 and decoded it but paid nothing because 2 USDC is over our $1 cap, this is the most agentic route (agent_rail) and nothing blocked it except our own cap. Separately, buying the $20/month Developer plan is console-only: the upgrade URL redirects to accounts.console.agentmail.to/sign-in behind a Cloudflare interstitial that never cleared and that our agent-made org has no console user to get past; that is a product wall, not a person-solvable CAPTCHA, and is unrelated to the agentic rail's checkout fields.

Ways to pay checked 14 Oct 2026.

For the team behind AgentMail.

Where agents stop in AgentMail today, and the fixes that get them further, highest impact first.

Wall at delete

The fixes, highest impact first

  1. Add an organization delete endpoint
  2. Let verified agents through the console checkStep-by-step guide
  3. Sell plans through a billing API
3 more fixes
  1. Give DCR clients the device grant Step-by-step guide
  2. Answer bad keys with a 401 body
  3. Serve the MCP server card at /server-card Step-by-step guide
  • Claim it free and reply next to the result.
  • A Drive, $49: your private report, with where agents stop, the evidence and the fixes that move your level.
  • Fixed something? Order a Drive ($49) any time, or the Monthly drive ($29/month).
See the example report
Details

Your API, MCP server or CLI is the product? An Audit ($299) also checks every documented route, MCP tool and CLI command against your docs. Compare plans.

Already claimed it? Open it in your dashboard.

Rather not be driven? Block AgentDrivesAgent in robots.txt or write to us. We stop driving it ourselves; this page stays, with its date.

Embed the badge on your site

Driven · L4 · Runs on its own badge

Behind the level.

The part scores and the measures behind them.

Part scores and the measures · the docs · level history · paid plans

Part scores

  • Holds up: 82 of 100, fair

Agent-ready setup

  • llms.txt: found
  • OpenAPI: found
  • MCP server: found
  • CLI: found

Not measured in this drive: Docs match (part of an Audit).

The measures

  1. Work done100
  2. Reliability71
  3. Crash test94

The docs

357 of 833 pages read. Complete.

  • A getting-started page
  • An auth page
  • Errors listed with their codes
  • Code examples on most pages
  • Newest page updated 13 Oct 2026
  • A page for 9 of 9 core tasks

Read on 14 Oct 2026.

Tried as documented

27 of 27 documented ways to do the core work worked when tried.

Tried as documented
What happenedWays
Worked when tried27
Documented, didn't work0
Not tried (a paid plan, or no way to reach it)0
Worked, but not in the docs0

Level history

  1. 1 Oct 20262 drivesL4Runs on its own
  2. 2 Oct 20262 drivesL4Runs on its own
  3. 3 Oct 2026L4Runs on its own
  4. 14 Oct 2026L4Runs on its own

Needs a paid plan

Not counted in the level. Our drive used free plan.

Needs a paid plan
CapabilityPlan
Custom sending domainDeveloper ($20/month)
Remove 'Sent via AgentMail' footerDeveloper+
/31/32 White-label, dedicated IPs, EU/BYO cloudEnterprise
SOC 2 reportStartup ($200/month)
Team seatsDeveloper+ (2 seats)
How AgentMail handles an agent's mistakes · 11 probes · core run 3×

Malformed requests, a retry, a wrong key and a short burst of reads on our agent's own account, and how AgentMail answered.

  1. Clear errors86
  2. Recovery92
  3. Safe retries100
  4. Rate limits100
  • SilentPATCH webhook with unknown field add_event_typesCreate and manage webhook endpoints for email events200, webhook returned unchanged (unknown field silently ignored)
  • SilentRepeat inbox create with same client_id, changed usernameCreate an email inbox for an agent200, returns the original adt-idem inbox; no error that the body differs
  • VagueWrong API keyCreate an email inbox for an agent403 {"message":"Forbidden"} (API gateway; not 401, no fix/docs unlike other errors)
  • ClearSend to a 4th distinct recipient in the first hour (free plan)Send an email from an inbox429 rate_limit_exceeded, Retry-After: 2806, application/json {name,code,message,fix,docs}: "sending ramp restarted ... at most 3 distinct recipients in its first hour (5 in its first 24 hours) ... lif
  • ClearRepeat a send with the same Idempotency-KeySend an email from an inbox200 + 200, same message_id, one message stored; changed body -> 409 IdempotencyKeyConflictError with fix
  • ClearSend without any recipientSend an email from an inbox400 validation_error, errors[].message "to, cc, or bcc must be specified", fix text
  • ClearGET a well-formed inbox id that does not existCreate an email inbox for an agent404 not_found "Inbox not found" + fix naming id/scope/permissions
  • ClearDraft with send_at "tomorrow"Schedule a draft to send at a future time400 validation_error invalid_format datetime (path send_at, regex shown)
  • ClearBurst 15 quick GET /v0/inboxes?limit=1Receive incoming email into an inboxstatuses ['200', '200', '200', '200', '200', '200', '200', '200', '200', '200', '200', '200', '200', '200', '200']; no RateLimit/X-RateLimit headers
  • ClearSend to two recipients, one on the block listSend an email from an inbox403 message_rejected naming the blocked recipient; the other recipient got nothing (search in adt-mcp-1: 0 hits): all-or-nothing, consistent
  • ClearCall with a revoked keyCreate an email inbox for an agent401 unknown_api_key "Unknown or revoked API key" + fix + docs link (contrast: a made-up key gets 403 {"message":"Forbidden"})

For agents and builders.

The drive as data, every checkpoint and all 140 attempts.

How an agent connects · 7 tips
  • Follow llms.txt: POST /v0/agent/sign-up with a human_email you can read, then POST /v0/agent/verify with the emailed code.
  • Wait ~5 minutes after verify before creating scoped keys; the 403 says so.
  • On the free plan you can mail only 3 new recipients in the first hour; replies to people who wrote to you don't count.
  • Use Idempotency-Key unquoted (A-Z a-z 0-9 -. _ ~) on sends, client_id on creates.
  • MCP: send x-api-key to https://mcp.agentmail.to/mcp; the OAuth path hits a Cloudflare check.
  • Polling webhooks need no public URL but events arrive with a delay; WebSockets are instant.
  • Errors carry a fix field that names the next step: read it.
Every checkpoint, in detail · 9 checkpoints
  1. DocsHeadlessllms.txt opens with agent sign-up steps; OpenAPI 3.1.0 (113 paths) at docs.agentmail.to/openapi.json; every docs page as Markdown (.md, and Accept: text/markdown redirects to it).
  2. Sign upHeadlessPOST /v0/agent/sign-up with human_email and username returned an org, an inbox and an API key in one call.
  3. VerifyHeadlessThe 6-digit code reached the agent's inbox in seconds; POST /v0/agent/verify answered verified:true.
  4. KeyHeadlessThe API key comes in the sign-up response; a scoped key via POST /v0/api-keys worked once the verify had propagated (first try 403 with a clear 'wait up to 5 minutes' fix), was used and revoked.
  5. First callHeadlessGET /v0/inboxes 200 with the new inbox.
  6. First actionHeadlessPOST /v0/inboxes created a second inbox, read back with GET.
  7. PayNot triedAgentMail's own hosts offer agent-payable rails: x402 v2 on x402.api.agentmail.to (2 USDC/call, exact, Base/Avalanche/Polygon/Solana) and MPP on mpp.api.agentmail.to (tempo, charge). Both sell only inbox creation per call. We read the 402 and decoded it but paid nothing because 2 USDC is over our $1 cap, this is the most agentic route (agent_rail) and nothing blocked it except our own cap. Separately, buying the $20/month Developer plan is console-only: the upgrade URL redirects to accounts.console.agentmail.to/sign-in behind a Cloudflare interstitial that never cleared and that our agent-made org has no console user to get past; that is a product wall, not a person-solvable CAPTCHA, and is unrelated to the agentic rail's checkout fields.
  8. CancelNot neededNothing to cancel: our agent used the free plan.
  9. DeleteBlockedNo documented way to delete an organization (API, CLI, MCP or docs). We deleted every inbox, webhook and key headless; the last key's revoke made the next call 401, but the empty organization stays.
The attempt log · 140 attempts
Attempt log
CapabilityRouteResultEvidence
Docs: llms.txt, robots.txtnonedone ✓https://www.agentmail.to/llms.txt 200 (27.5 KB, agent sign-up steps at top); robots.txt: User-Agent * Allow / Disallow /internal/, no Content-Usage/Content-signal lines
Docs: MCP server/discover 2026-07-28mcpfailed ✓POST https://mcp.agentmail.to/mcp server/discover -> 401 {"error":"Unauthorized"}, WWW-Authenticate: Bearer resource_metadata=https://mcp.agentmail.to/.well-known/oauth-protected-resource/mcp (retry with key later)
Docs: MCP server card / AI catalog / A2A cardnonepartial ✓<mcp>/server-card 404; /.well-known/ai-catalog.json 404; /.well-known/mcp/server-card.json 200 application/json (older draft path, oauth2 via clerk.console.agentmail.to); agent-card.json 404; agent.json 404
Docs: OAuth PRM + AS metadatanonedone ✓PRM at /.well-known/oauth-protected-resource/mcp 200; AS clerk.console.agentmail.to: registration_endpoint (DCR), device_authorization_endpoint, device_code grant; client_id_metadata_document_supported absent (no CIMD)
Docs: Markdown docsnonedone ✓docs.agentmail.to/welcome with Accept: text/markdown -> 303 to /welcome.md, Vary: Accept; /welcome.md 200 text/markdown
Docs: OpenAPIapidone ✓https://docs.agentmail.to/openapi.json 200 application/json, openapi 3.1.0, 113 paths, servers api/x402.api/mpp.api/api.agentmail.eu
Docs: Find docsnonedone ✓docs.agentmail.to + llms.txt + OpenAPI; docs_pass.json verdict found getting started/auth/errors/examples
Sign up: POST /v0/agent/sign-up with human_emailapidone ✓200 returned organization_id, inbox [redacted], api_key (am_us_••••)
Verify: Read OTP mail, POST /v0/agent/verifyapidone ✓OTP mail arrived in ~5 s from yes-reply@agentmail.to; verify 200 {"verified":true}
Key: API key from sign-up responseapidone ✓api_key returned in sign-up body; GET /v0/auth/me 200 credential_scope_type organization
First call: GET /v0/inboxesapidone ✓200 count 1, the sign-up inbox listed
Create inbox: POST /v0/inboxes username adt-cap01-aapidone200 {"organization_id": "[redacted]", "pod_id": "[redacted]", "inbox_id": "adt-cap01-a@agentmail.to", "email": "adt-cap01-a@agentmail.to", "client_id":
Create inbox: GET /v0/inboxes/{id}apidone ✓200 email=adt-cap01-a@agentmail.to display_name=AgentDrives Test
Create inbox: PATCH display_name, read backapidone ✓PATCH 200; GET display_name=AgentDrives Test Updated
First action: Create a second inbox via POST /v0/inboxesapidone ✓adt-cap01-a@agentmail.to created 200 and read back via GET 200
Send email: Send mail with attachment to the agent's inbox the agent's inboxapidone ✓POST send 200 message_id+thread_id; GET message labels [sent, adtest]; mail arrived at the agent's inbox 05:17:30 (token [redacted])
Attachments: Send note.txt as base64 attachmentapidone ✓send 200; GET message lists attachment note.txt size 62
Attachments: GET attachment, download file and extracted textapidone ✓GET attachment 200 with download_url + text_url (signed, expires 1h); both returned the exact file content (alpha-bravo-7731)
Receive email: Mail sent over SMTP from inbox A to inbox B, list inbox B messagesapidone ✓GET /v0/inboxes/adt-cap01-a/messages after 15 s: count 1, labels [received, unread], subject "Inbound test for ", SPF pass header (went via SES)
Create inbox: Receive mail in the new inboxapidone ✓adt-cap01-a received the mail (see)
Reply: Reply from inbox B to the received messageapidone ✓POST reply 200 thread_id [id]; GET /v0/threads/[id] shows original + reply [sent]; sender inbox thread eea9db77 shows the reply [received] appended
Quote stripping / text extraction: Read received reply: text vs extracted_textapidone ✓received reply text contains "On ... wrote: > Inbound body..." quoted history; extracted_text holds only the new reply body (plus signature footer); attachment text_url gave extracted file text
Reply: reply-all back to inbox Bapidone ✓POST reply-all 200; inbox B thread now has 3 messages
Forward: Forward the received message to the agent's inboxapidone ✓POST forward 200; GET message to [the agent's inbox] labels [sent] subject "Fwd: Inbound test for "; arrived in the agent's inbox with fig-6060 and the original kiwi-5521 body
Threads: List threads of inbox B, get threadapidone ✓GET threads 200 count 1; GET /v0/threads/[id] earlier returned messages grouped as one conversation (original, reply, reply-all, forward)
Threads: PATCH thread add/remove labels, read backapidone ✓add -> labels ['received', 'unread', 'needs-followup', 'adtest', 'sent']; remove -> ['received', 'unread', 'adtest', 'sent']
Labels: Add then remove a custom label on a threadapidone ✓add -> ['received', 'unread', 'needs-followup', 'adtest', 'sent']; remove -> ['received', 'unread', 'adtest', 'sent']
Labels: PATCH message: remove unread, add processedapidone ✓PATCH 200; GET labels ['received', 'adtest', 'processed']
Search: Search messages for "zebra" and threads for "kiwi"apidone ✓messages/search?q=zebra 200 count 1 = the message; threads/search?q=kiwi 200 count 1 = the thread
Drafts: Create draftapidone200 draft_id [id]
Drafts: GET draftapidone ✓200 text='Draft v1 lemon-1111'
Drafts: PATCH draft text, read backapidone ✓PATCH 200; GET text='Draft v2 lemon-2222'
Drafts: Send draft, read back as messageapidone ✓POST drafts/send 200; GET message labels ['sent'] text "Draft v2 lemon-2222"; GET draft afterwards 404 (draft consumed by send)
Schedule: Create draft with send_at +3 minapidone ✓200 send_status scheduled, labels [draft, scheduled], send_at 2026-10-14T05:23:12Z
Drafts: Create + DELETE a draft, read backapidone ✓DELETE 204; GET 404
Schedule: PATCH send_at of a scheduled draft, read backapidone ✓PATCH 200; GET send_at 2026-10-14T06:50:26Z status scheduled
Schedule: Cancel scheduled send by DELETE draft, read backapidone ✓DELETE 204; GET 404
Forward: DELETE the forwarded message, read backapidone ✓DELETE 204; GET 404
Reply: DELETE the reply message, read backapidone ✓DELETE 204; GET 404
Receive email: DELETE the received message, read backapidone ✓DELETE 204; GET 404
Threads: DELETE thread, read backapidone ✓DELETE 202; GET 404
Send email: DELETE the sent message (with attachment), read backapidone ✓DELETE 204; GET 404
Attachments: Delete message, check attachment goneapidone ✓GET attachment after message delete -> 404
Key: POST /v0/api-keys scoped read-only key (1st try, ~5 min after verify)apifailed ✓403 missing_permission; fix: "organization has not completed agent verification ... If you just verified, the credential's cached permissions can lag for up to 5 minutes: wait and retry."
Scoped API keys: Create read-only key (1st try)apifailed ✓403 missing_permission, cached permissions lag after verify (documented in the fix text)
Allow/block lists: Block send to our own address, try a send, unblockapidone ✓POST lists/send/block 200; GET lists count 1; send to blocked address -> 403 message_rejected with fix naming the DELETE path; DELETE 204; GET count 0
Webhooks: Create webhook, read back, PATCH event_types+enabled, read backapidone ✓POST /v0/webhooks 200 (secret returned); GET url+events match; PATCH 200 -> events ['message.bounced', 'message.received', 'message.sent'] enabled False. Delivery not observed: we have no public receiver.
Schedule: Wait for the scheduled draft to sendapidone ✓send_at 05:23:12Z; draft gone (404) and message "AgentDrives scheduled test" in sent at 05:23:42Z; arrived in an inbox inbox: True
Drafts: Draft send delivered to the agent's inboxapidone ✓lemon-2222 (draft v2 text) arrived at an inbox: True
WebSockets: TS SDK websockets.connect, subscribe inbox, send mail into itsdkdone ✓WS frames: subscribed, then event (message.received) with subject "WS test " within seconds of the send
Webhooks: Polling webhook: create, read events with Svix AutoConfigConsumersdkpartialPOST /v0/webhooks/polling 200 with token; consumer.receive returned done:true, 0 events ~1 min after a message.received in the covered inbox (WS saw it)
Key: POST /v0/api-keys read-only key (retry ~8 min after verify)apidone ✓200 api_key_id c042f563…, permissions inbox_read+message_read only; GET /v0/api-keys/{id} 200
Key: Use scoped key: list inboxes (allowed), create inbox (not allowed)apidone ✓GET /v0/inboxes 200 count 2; POST /v0/inboxes 403 missing_permission naming inbox_create; used_at set on the key
Scoped API keys: Create read-only key, use it within and outside scopeapidone ✓create 200; GET key 200; read 200, create 403 missing_permission
Docs claim: Create an email inbox for an agent: create_inboxmcpdone ✓tools/call create_inbox on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'inboxId': 'adt-mcp-1@agentmail.to'}
Docs claim: Send an email from an inbox: send_messagemcpdone ✓tools/call send_message on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'messageId': '<010001a138df08cf-[id]-000000@email.amazonses.com>', 'threadId': '76626cb
Docs claim: Receive incoming email into an inbox: list_messagesmcpdone ✓tools/call list_messages on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'count': 2, 'limit': 10, 'messages': [{'inboxId': 'adt-mcp-1@agentmail.to', 'threadId': 'e223f1d5-9b4d-4a22-8633-ac1c77
Docs claim: Reply to a message (reply or reply-all) within its thread: reply_to_messagemcpdone ✓tools/call reply_to_message on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'messageId': '<010001a138df85a4-[id]-000000@email.amazonses.com>', 'threadId': 'e223f1d
Docs claim: Forward a message to new recipients: forward_messagemcpdone ✓tools/call forward_message on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'messageId': '<010001a138df8b16-[id]-000000@email.amazonses.com>', 'threadId': 'e223f1d
Docs claim: View and manage threaded conversations across an inbox: list_threadsmcpdone ✓tools/call list_threads on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'count': 1, 'limit': 10, 'threads': [{'inboxId': 'adt-mcp-1@agentmail.to', 'threadId': 'e223f1d5-9b4d-4a22-8633-ac1c770
Docs claim: View and manage threaded conversations across an inbox: get_threadmcpdone ✓tools/call get_thread on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'inboxId': 'adt-mcp-1@agentmail.to', 'threadId': '[id]', 'labels': ['received', 'unread
Docs claim: Send and download file attachments on messages: get_attachmentmcpdone ✓tools/call get_attachment on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'attachmentId': '[id]', 'filename': 'a.txt', 'size': 62, 'contentType': 'text/plain', '
Docs claim: Create, edit and send a draft email: create_draftmcpdone ✓tools/call create_draft on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'inboxId': 'adt-mcp-1@agentmail.to', 'draftId': '[id]', 'labels': ['draft'], 'to': ['dr
Docs claim: Create, edit and send a draft email: update_draftmcpdone ✓tools/call update_draft on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'inboxId': 'adt-mcp-1@agentmail.to', 'draftId': '[id]', 'labels': ['draft'], 'to': ['dr
Docs claim: Create, edit and send a draft email: send_draftmcpdone ✓tools/call send_draft on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'messageId': '<010001a138df9d2e-[id]-000000@email.amazonses.com>', 'threadId': '1fead67
Docs claim: Schedule a draft to send at a future time: create_draft (sendAt)mcpdone ✓tools/call create_draft (sendAt) on https://mcp.agentmail.to/mcp (2026-07-28, x-api-key) -> {'inboxId': 'adt-mcp-1@agentmail.to', 'draftId': '[id]', 'labels': ['draft', 'scheduled'
Docs claim: Create an email inbox for an agent: POST /v0/inboxesapidone ✓create 200, GET read back
Docs claim: Send an email from an inbox: POST /v0/inboxes/{inbox_id}/messages/sendapidone ✓200, delivered to an inbox
Docs claim: Receive incoming email into an inbox: GET /v0/inboxes/{inbox_id}/messagesapidone ✓lists received mail
Docs claim: Reply to a message (reply or reply-all) within its thread: POST .../reply and /reply-allapidone ✓both 200, threaded
Docs claim: Forward a message to new recipients: POST .../forwardapidone ✓200, delivered
Docs claim: View and manage threaded conversations across an inbox: GET /v0/inboxes/{inbox_id}/threads, GET /v0/threads/{thread_id}apidone ✓both 200
Docs claim: Send and download file attachments on messages: send attachments + GET attachmentapidone ✓download_url and text_url work
Docs claim: Create, edit and send a draft email: POST/PATCH drafts, POST drafts/sendapidone ✓all 200
Docs claim: Schedule a draft to send at a future time: POST drafts send_atapidone ✓scheduled, sent 30 s after send_at
Create inbox: DELETE inbox adt-cap01-a, read backapidone ✓DELETE 202; GET 404
Docs claim: Create an email inbox for an agent: agentmail inboxes createclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'created_at': '2026-10-14T05:26:06.665Z', 'display_name': 'AgentDrives CLI', 'email': 'adt-cli-1@ag
Docs claim: Send an email from an inbox: agentmail inboxes messages send --attachmentsclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'message_id': '<010001a138e01f88-[id]-000000@email.amazonses.com>', | map names "--attachment"; the real flag is --attachments <JSON_OBJECT>
Docs claim: Receive incoming email into an inbox: agentmail inboxes messages listclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'count': 6, 'messages': [{'attachments': [{'attachment_id': '[id]',
Docs claim: Reply to a message (reply or reply-all) within its thread: agentmail inboxes messages replyclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'message_id': '<010001a138e05279-[id]-000000@email.amazonses.com>',
Docs claim: Forward a message to new recipients: agentmail inboxes messages forwardclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'message_id': '<010001a138e055c8-[id]-000000@email.amazonses.com>',
Docs claim: View and manage threaded conversations across an inbox: agentmail inboxes threads listclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'count': 2, 'threads': [{'attachments': [{'attachment_id': '[id]',
Docs claim: Send and download file attachments on messages: agentmail inboxes messages get-attachmentclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'attachment_id': '[id]', 'content_disposition': 'attachment', 'cont
Docs claim: Create, edit and send a draft email: agentmail inboxes drafts createclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'created_at': '2026-10-14T05:26:29.563Z', 'draft_id': '[id]', 'inbo
Docs claim: Schedule a draft to send at a future time: agentmail inboxes drafts create --send-atclidone ✓agentmail-cli 1.9.0 (npm), exit 0: {'created_at': '2026-10-14T05:26:29.939Z', 'draft_id': '[id]', 'inbo
Docs claim: Send an email from an inbox: client.inboxes.messages.send (TypeScript SDK agentmail)sdkdone ✓sent "WS test ", received in the target inbox
Create an email inbox for an agent: Repeat core task, fresh objects (trial 2)apidone ✓create 200 GET 200; DELETE 202 GET 404
Send an email from an inbox: Repeat core task, fresh objects (trial 2)apifailedsend 429; GET labels None
Receive incoming email into an inbox: Repeat core task, fresh objects (trial 2)apifailedreceived after polling: False
Create, edit and send a draft email: Repeat core task, fresh objects (trial 2)apidone ✓create 200 update 200 text v2 send 200
Schedule a draft to send at a future time: Repeat core task, fresh objects (trial 2)apidone ✓create 200 status scheduled send_at 2026-10-14T05:30:28Z (send checked later)
Create an email inbox for an agent: Repeat core task, fresh objects (trial 3)apidone ✓create 200 GET 200; DELETE 202 GET 404
Send an email from an inbox: Repeat core task, fresh objects (trial 3)apifailedsend 429; GET labels None
Receive incoming email into an inbox: Repeat core task, fresh objects (trial 3)apifailedreceived after polling: False
Create, edit and send a draft email: Repeat core task, fresh objects (trial 3)apidone ✓create 200 update 200 text v2 send 200
Schedule a draft to send at a future time: Repeat core task, fresh objects (trial 3)apidone ✓create 200 status scheduled send_at 2026-10-14T05:31:22Z (send checked later)
Reply to a message (reply or reply-all) within its thread: Repeat core task, fresh message (trial 2); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓reply 200; thread msgs 2
Forward a message to new recipients: Repeat core task, fresh message (trial 2); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓forward 200; GET 200 to ['the agent's inbox']
View and manage threaded conversations across an inbox: Repeat core task, fresh message (trial 2); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓thread get 200 msgs 3
Send and download file attachments on messages: Repeat core task, fresh message (trial 2); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓attachment GET 200; download matches True
Reply to a message (reply or reply-all) within its thread: Repeat core task, fresh message (trial 3); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓reply 200; thread msgs 2
Forward a message to new recipients: Repeat core task, fresh message (trial 3); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓forward 200; GET 200 to ['the agent's inbox']
View and manage threaded conversations across an inbox: Repeat core task, fresh message (trial 3); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓thread get 200 msgs 3
Send and download file attachments on messages: Repeat core task, fresh message (trial 3); sender is a fresh inbox, recipient an inbox already mailed (sending ramp)apidone ✓attachment GET 200; download matches True
Pods: Create pod, inbox in pod, list pod inboxes, deleteapidone ✓POST /v0/pods 200; POST /v0/pods/{id}/inboxes 200; GET pod inboxes lists only adt-pod-inbox; DELETE inbox 202, DELETE pod 204, GET pod 404
Metrics: GET metrics usage/events/ratesapidone ✓all 200; events shows message.sent count 26, message.received 13, message.delivered present, matching the drive's activity; rates bounce/complaint empty
Raw MIME: GET message raw, download .emlapidone ✓GET raw 200 returns size 4961 + signed download_url (not inline MIME); .eml downloaded (4885 bytes) with headers ['From: AgentMail <adt-trial-4@agentmail.to>', 'Subject: trial 3 r', 'Message-ID: <010001a138e3e1fe-[id]-000000@email.amazonses.com>']
Idempotency: Send twice with Idempotency-Key; create inbox twice with client_idapidone ✓send x2 same Idempotency-Key -> both 200 with the same message_id, search shows one message; changed body with same key -> 409 conflict with fix. Inbox create x2 same client_id -> same inbox; a changed username with same client_id silently returned the original inbox (200). Quoted SF-string key form ("...") rejected 400 with clear character rule.
Custom domain: POST /v0/domains amtest.agentdrives.comapiplan_gated ✓403 limit_exceeded "Your plan's domain limit is 0 ... Developer raises it to 10 for $20.00/month", upgrade_url console.agentmail.to/dashboard/upgrade
App catalog: GET /v0/apps and /v0/apps/searchapidone ✓GET /v0/apps 200 count 5 with app_id, slug, name (Firecrawl first) and next_page_token; search q=firecrawl count 1; q=search count 0
Create account at third-party app (AgentID): POST /v0/apps/{app_id}/connectapiskippedNot tested: connecting creates an account at another company's product (e.g. Firecrawl): outside this drive's scope (only account at AgentMail). Endpoint and MCP tool connect_app exist in OpenAPI / tools/list.
Public-key credentials: Register P-256 JWK via POST /v0/api-keys, read, deleteapidone ✓200 type public_key with fingerprint; GET 200; DELETE 204; GET 404. No pending/active status field seen (map check mentions one); the AgentID sign-in with it was not exercised (third-party app).
IMAP/SMTP: Connect over IMAP with inbox id + API key, list messagesapidone ✓IMAP4_SSL imap.agentmail.to:993 login(adt-mcp-1@agentmail.to, API key) OK; select INBOX OK; 1 messages; last Subject: For MCP claims
IMAP/SMTP: Compare IMAP INBOX with the API listapipartial ✓IMAP INBOX showed 1 message; GET messages?labels=received lists 5 for the same inbox (4 arrived after the first one, minutes before). Docs say a missing permission stops updates; our key is unrestricted.
Team seats: Check against docs/pricingnoneplan_gatedpricing: Free "Team Members" listed; Developer 2 organization seats, Startup 10; console-only, no API route in OpenAPI
Remove footer: Check against docs/pricingnoneplan_gatedpricing table row "Sent via AgentMail" footer (free plan carries it: our sent mail had "--\nSent via AgentMail"); removal on paid plans
White-label: Check against docs/pricingnoneplan_gatedllms.txt + pricing: "White-label platform" in Enterprise (custom pricing, contact)
SSO: Check against docs/pricingnoneskippedpricing: "Social SSO" on all plans; llms.txt: OIDC/SAML SSO on Enterprise; console settings only, not tried (console sign-in not used on this drive)
SOC 2 report: Check against docs/pricingnoneplan_gateddocs page soc-2-compliance.md: 2025 SOC 2 Type II completed, 2026 audit with A-LIGN; report on Startup ($200/mo)
Dedicated IPs: Check against docs/pricingnoneplan_gatedpricing: "Dedicated IPs: Contact us" (Enterprise)
EU / BYO cloud: Check against docs/pricingnoneplan_gatedllms.txt + pricing: EU region cloud, BYO cloud on Enterprise; OpenAPI lists server https://api.agentmail.eu (eu-prod)
Agent sign-up + human OTP verify: POST /v0/agent/sign-up, OTP mail, POST /v0/agent/verifyapidone ✓sign-up 200 (unverified org, send limited to the human email); OTP arrived in seconds; verify 200 verified:true; sends to other recipients then worked (after which the 3-recipient first-hour ramp applies)
Webhooks: Polling webhook: receive again ~10 min latersdkdone ✓Svix AutoConfigConsumer.receive returned 6 events (message.sent x5, message.received "Re: For MCP claims"), committed; first receive minutes earlier had returned 0 (events queue with delay)
Sign up: x402/MPP pay-per-call inbox create without accountapiskippedpay_tx.json: x402 v2 402 on https://x402.api.agentmail.to/v0/inboxes asks 2 USDC (exact, eip155:8453), over our $1 per-payment cap, refused by us, nothing paid
Sign up: Sign in with AgentID at AgentMailnoneskippedAgentID is AgentMail's product for agents signing in to OTHER apps; the console sign-up shows only Google and email/password, no AgentID button. Not a way into AgentMail itself.
Sign up: Console sign-up with email+password (the agent's inbox)browserblocked ✓https://console.agentmail.to/sign-up: after Continue the form is replaced by a Cloudflare Turnstile "Verify you are human" widget (Clerk bot protection). Not solved, not retried.
Sign up: Stripe ProjectsnoneskippedListed in the Stripe Projects catalog (door_probe, lead); our agent has no Stripe Projects account
Key: MCP OAuth (DCR + authorize, PKCE, resource)browserblocked ✓DCR at /oauth/register 200 (client_id issued). /oauth/authorize redirects to accounts.console.agentmail.to/sign-in, which shows a Cloudflare "Performing security verification" interstitial that did not clear after 15 s; and the agent-created org has no console user to consent with. MCP with x-api-key works instead.
Sign up: OIDC/SAML SSOnoneskippedEnterprise plan only (llms.txt)
Sign up: Human creates key in consolenoneskippedllms.txt Step 2 fallback: developer generates a key at console.agentmail.to
Pay: Public pay probesapidone ✓x402 v2 on x402.api.agentmail.to (PAYMENT-REQUIRED header, 2 USDC exact on Base eip155:8453 + Avalanche/Polygon/Solana/eip155:196; realm api.paysponge.com) and MPP on mpp.api.agentmail.to (WWW-Authenticate: Payment method="tempo" intent="charge", 2000000 of token 0x20C0…b50 on chainId 4217, problem+json body). OpenAPI servers list both. No billing/subscription endpoint in OpenAPI (113 paths). GET /v0/organizations: billing_plan_id free. Domain create 403 names upgrade_url console.agentmail.to/dashboard/upgrade ($20/mo Developer). Pricing: Free plan, no card.
Pay: Walk to the last click: console.agentmail.to/dashboard/upgradebrowserblocked ✓Upgrade URL redirects to accounts.console.agentmail.to/sign-in behind a Cloudflare interstitial that does not clear; our agent-made org has no console user, and console sign-up shows Turnstile. Checkout not reached; processor unknown.
Cancel: Cancel plannoneskippedNothing to cancel: free plan, no trial, nothing paid. Docs/OpenAPI show no billing API; plan changes are in the console.
Schedule a draft to send at a future time: Scheduled draft sends (trial 2)apidone ✓send_at 2026-10-14T05:30:28Z; draft GET 404; sent message [('trial sched 2', ['sent'], '2026-10-14T05:30:44.868Z')]
Schedule a draft to send at a future time: Scheduled draft sends (trial 3)apidone ✓send_at 2026-10-14T05:31:22Z; draft GET 404; sent message [('trial sched 3', ['sent'], '2026-10-14T05:31:42.830Z')]
Key: DELETE /v0/api-keys/{id}, use the key againapidone ✓DELETE 204; GET /v0/inboxes with the revoked key -> 403 {'message': 'Forbidden'}
Webhooks: DELETE webhook and polling webhook, read backapidone ✓webhook DELETE 204 GET 404; polling DELETE 204 GET 404
Docs claim: Create an email inbox for an agent: delete_inboxmcpfailedtools/call delete_inbox -> GET inbox 409
Docs claim: Create an email inbox for an agent: delete_inboxmcpdone ✓read back: GET inbox -> 409 resource_deleting "Inbox is being deleted" (asynchronous delete, DELETE answers 202); list no longer shows it
Delete: Delete account: delete all inboxes, webhooks, keys; look for an org deleteapipartial ✓No documented account/organization delete (OpenAPI 113 paths: /v0/organizations is GET only; docs and llms.txt name none; privacy policy lists a right to request deletion, no route). Deleted every inbox (DELETE 202, GET 404, list count 0), both webhooks, the scoped key, then the org's own key: DELETE 204, next call 401 unknown_api_key. The empty organization (agent-type, the agent's inbox) stays; the console that might delete it is behind Cloudflare checks and the org has no console user.

Also in Email infrastructure.