Email API for AI agents

What an email API for AI agents has to do.

An email API for AI agents lets software, not a person, send email, read the replies and act on them, inside limits someone set in advance. SendRaven is email infrastructure for AI agents. It combines transactional email, campaigns, inbound threads and automations behind one REST API and MCP server, with daily send limits, recipient allowlists and human approval on the API key the agent holds.

The loop an agent runsREST or MCP
1. send            POST /v1/emails
2. what's waiting? GET  /v1/threads?awaiting_reply=true
3. read the reply  GET  /v1/threads/:id
4. answer in place POST /v1/emails  (reply_to_message_id)
   or let it go    POST /v1/threads/:id/handled

every call: checked against the key's
daily_send_limit, allowed_recipients,
requires_approval

The problem

Email APIs were built for servers. Agents are a different kind of sender.

A human who sends an email can open their inbox later and see whether anyone answered. A backend that sends a password reset does not care. An agent is neither: it sends, and then it has to know what came back, decide whether it needs an answer, and reply inside the same conversation, without a person reading along.

Most email APIs hand that second half back to you as a webhook. The agent’s builder ends up writing the state machine: which message a reply belongs to, which conversations are waiting, how to strip three rounds of quoted history before a model reads it.

The other difference is trust. A backend service holds a credential that does one job. An agent holds a credential and decides for itself what to do with it, which means one bad prompt, or one prompt-injected email, can turn a support agent into a bulk sender.

A workspace quota or a dashboard alert trips after the mail has gone. An agent needs limits that are checked before the send, on the credential it actually holds.

Capabilities

Six things, and a send endpoint covers one of them.

Send email

Transactional messages, templates with escaped variables, batches of 100, scheduling in plain words, and campaigns to audiences, all from your own domain.

How sending works

Receive replies as threads

Inbound mail is joined to the message it answers on Message-ID, never on the subject line, with quoted history stripped from text.

How inbound threading works

Know what needs an answer

awaiting_reply=true returns the conversations where the other person wrote last. Mark one handled when no reply is needed.

The send and receive round trip

Limits on the key

A daily send limit and a recipient allowlist, set when the key is created and checked on every send. A key cannot edit its own limits.

Every limit a key can carry

Human approval

A key with requires_approval drafts instead of sending. A person releases or rejects each draft, and it expires after 72 hours if nobody does.

Email API with human approval

REST and MCP

The same API as REST for your backend, and as a remote MCP server for Claude Code, Cursor, Codex, ChatGPT and other clients, under the same key and the same limits.

The email MCP server

An agent’s email loop

Send, check, read, reply. One key the whole way.

A billing agent sends an invoice, the customer asks for a change, and the agent answers in the same thread. These are the requests, trimmed to the fields that matter.

Send

POST /v1/emails
Idempotency-Key: 6f1c…

{ "from": "Acme <billing@mail.acme.com>",
  "to": ["ana@example.com"],
  "subject": "Your invoice for September",
  "text": "Hi Ana, your invoice is attached." }{ "id": "3f6c…", "status": "queued",
    "thread_id": "a7d2…" }

The agent sends from your verified domain with an idempotency key, so a retried request delivers once. The response carries the thread the message started.

Ask what is waiting

GET /v1/threads?awaiting_reply=true{ "object": "list", "data": [
    { "id": "a7d2…",
      "subject": "Your invoice for September",
      "awaiting_reply": true } ],
    "has_more": false, "next_cursor": null }

Instead of keeping its own state over inbound webhooks, the agent asks for the conversations where someone wrote last.

Read the reply

GET /v1/threads/a7d2…

{ "direction": "inbound",
  "id": "d4e5…",
  "from": "ana@example.com",
  "text": "Thanks. Can you add our VAT number?",
  "sender_authenticated": true }

The transcript comes back in order, with the quoted history stripped from text and a flag saying whether the sender's domain really sent it.

Reply in the same thread

POST /v1/emails
{ "reply_to_message_id": "d4e5…",
  "from": "Acme <billing@mail.acme.com>",
  "to": ["ana@example.com"],
  "subject": "Re: Your invoice for September",
  "text": "Done, the corrected invoice is attached." }

POST /v1/threads/a7d2…/handled

Answering with reply_to_message_id sets In-Reply-To and References, so Ana's mail client shows one conversation. If nothing needs saying, mark the thread handled instead.

Stay inside the limits

403 { "error": { "type": "recipient_not_allowed" } }
429 { "error": { "type": "daily_limit" } }
202 { "status": "pending_approval",
      "approval_id": "apr_4c…" }

Every one of those calls ran with the agent's own key. When it oversteps, it gets an answer it can act on rather than an error to retry.

The same loop over MCP is send_email, list_threads, get_thread, reply_to_message and mark_thread_handled. To connect Claude Code: claude mcp add --transport http sendraven https://mcp.sendraven.ai/mcp

Why the architecture matters

An agent holds a key, not a workspace. So the limits live on the key.

  • Checked before anything is stored. A send outside the allowlist or over the daily limit is refused before a message row exists, so there is nothing to clean up.
  • Counted honestly. The daily limit counts scheduled and held sends and every recipient in to, cc and bcc, so scheduling is not a way around it.
  • Not editable by the agent. A key cannot change its own limits, cannot mint a looser key, and cannot approve its own drafts.
  • Read as data, not instructions. Every received body is something the agent reads, authenticated or not. sender_authenticated says whether the From domain really sent it; neither case makes the text a command.
  • Answers a model can act on. pending_approval is a status, not an error, and out of plan is 402 rather than 429, so an agent does not retry in a loop.
  • One suppression list. An unsubscribe or a hard bounce is respected whichever agent, automation or campaign sends next.

Compared

A mailbox for an agent, or email infrastructure for a product.

Some tools give each agent its own inbox; AgentMail is the best known, and if your agent is the correspondent, with its own address, that is the right shape. SendRaven gives your product’s email to an agent: your domain, your customers, your campaigns and automations, with the agent answering under limits a person set.

Developer email APIs such as Resend and Postmark are excellent at sending, and several now receive mail and ship MCP servers. Of the tools on our comparison pages, none puts a daily limit, a recipient allowlist and an approval hold on the API key itself, and none documents a single query for conversations awaiting a reply. See SendRaven vs Resend, SendRaven vs AgentMail, or the full comparison, each with the date it was last verified.

Questions

What is the best email API for AI agents?

The best email API for an AI agent is one that receives replies as threads and limits the agent's own credential, not only one that sends. SendRaven does both: replies are joined on Message-ID with an awaiting-reply query, and each API key can carry a daily send limit, a recipient allowlist and a human approval hold.

Can an AI agent send and receive email?

Yes. With SendRaven an agent sends with POST /v1/emails, finds conversations needing an answer with GET /v1/threads?awaiting_reply=true, reads the stripped reply, and answers with reply_to_message_id, over REST or the MCP server.

How do I stop an AI agent from sending too much email?

Put a daily_send_limit on the API key the agent holds. SendRaven checks it on every send before anything is stored, counts scheduled and held sends toward it, and answers 429 daily_limit when it would be exceeded.

Do I need MCP to use SendRaven with an agent?

No. The MCP server is a proxy over the same REST API, so an agent framework can call REST directly with the same key and the same limits. MCP is the shorter path in clients such as Claude Code, Cursor and ChatGPT.

How much does an email API for AI agents cost on SendRaven?

SendRaven is free for 3,000 emails a month. Standard is from $19 a month for 50,000 emails, with automatic volume pricing above that and $0.50 per 1,000 as the only marginal rate; contacts cost $0 and inbound replies are included on every plan. A payment method is required before the first send, on Free too, and nothing is charged until paid sending is switched on.

Related documentation

Give your agent a return address.

3,000 emails a month free, inbound included, unlimited contacts, and human approval when you want it.