How to Connect an AI Agent to a Real Email Inbox

7 min read

Give your AI agent its own real email inbox: provision a mailbox, send via API, receive inbound webhooks, and reply in thread. Working code included.

John Joubert

John Joubert

Founder, Robotomail

How to Connect an AI Agent to a Real Email Inbox
Table of contents

Here is how to connect an AI agent to a real email inbox: provision a mailbox the agent owns, give it an API key to send from that address, and register a webhook so inbound mail is pushed into your agent loop as JSON. That is the whole pattern. You do not need SMTP credentials, IMAP polling, or an OAuth consent screen.

The short version, with Robotomail:

npx @robotomail/cli mailbox create shopping-agent

That address now exists, accepts mail from the outside world, and can send. Everything below is the detail that matters once you move past the first message.

What "a real email inbox" actually requires

Developers searching for how to connect an AI agent to a real email inbox usually tried one of two shortcuts first and hit a wall.

The first shortcut is a transactional sending API. It sends fine, but there is no inbox behind the address. Replies vanish or land in a human's mailbox. Your agent is talking into a void.

The second shortcut is a human mail account borrowed from Google or Microsoft. That gets you an inbox, but you inherit OAuth refresh tokens, consent screens, per-account verification, and terms written for humans. It breaks the moment you need fifty agents instead of one. We wrote up the specifics in why Gmail and Outlook don't work for agents.

A real inbox for an agent needs four properties:

Property Why it matters
A routable address with MX records Outside senders can actually reach it
Programmatic send from that same address Replies thread back to the agent, not a human
Push delivery of inbound mail No polling, no IMAP connection state to babysit
Per-agent isolation One agent's inbox is not another's blast radius

If any one is missing, you are simulating email rather than using it.

How to connect an AI agent to a real email inbox, step by step

1. Provision a mailbox the agent owns

One mailbox per agent, or per agent task if the agent runs many concurrent jobs. Keep the address descriptive so logs are readable later.

curl -X POST https://api.robotomail.com/v1/mailboxes \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"address": "shopping-agent"}'

Omit domainId and the mailbox lands on a platform domain, which is the fastest way to get working mail. When you are ready to send from your own domain, add the domain and pass its UUID as domainId. The custom domain guide covers the DNS records.

2. Give the agent a send tool

Expose sending as a single tool or function your model can call. Keep the signature narrow: recipient, subject, body. Do not let the model choose the from address, that is a property of the mailbox.

curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_shopping/messages \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"to": ["vendor@example.com"], "subject": "Order #A-4521 delivery update?", "bodyText": "Hi, checking on the status of order A-4521."}'

In TypeScript, wrapped as a tool handler:

async function sendEmail(input: {
  to: string[];
  subject: string;
  bodyText: string;
  inReplyTo?: string;
}) {
  const res = await fetch(
    `https://api.robotomail.com/v1/mailboxes/${mailboxId}/messages`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.ROBOTOMAIL_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(input),
    },
  );
  if (!res.ok) throw new Error(`send failed: ${res.status}`);
  return res.json();
}

3. Register a webhook for inbound mail

This is the step that turns a sending integration into a real inbox. Register your endpoint as its own resource against your account, and inbound messages are POSTed to it as they arrive. See /docs/concepts/webhooks for registration and retry behaviour.

The payload shape:

{
  "event": "message.received",
  "data": {
    "message_id": "...", "mailbox_id": "...", "mailbox_address": "shopping-agent@robotomail.co",
    "from": "vendor@example.com", "subject": "Re: ...", "body_text": "...",
    "thread_id": "...", "received_at": "2026-04-17T10:00:00.000Z"
  }
}

Note the casing difference: you send bodyText, you receive body_text. It catches people once.

4. Hand the message to your agent and reply in thread

The handler should do three things and nothing more: acknowledge fast, enqueue, and return 200. Model inference is far slower than any sane webhook timeout, so never run it inline.

app.post("/webhooks/email", async (req, res) => {
  const { event, data } = req.body;
  if (event !== "message.received") return res.sendStatus(200);

  await queue.add("agent-email", {
    threadId: data.thread_id,
    messageId: data.message_id,
    mailboxId: data.mailbox_id,
    from: data.from,
    subject: data.subject,
    body: data.body_text,
  });

  res.sendStatus(200);
});

Then in the worker, after the agent decides on a response, pass inReplyTo with the inbound message_id:

await sendEmail({
  to: [job.data.from],
  subject: `Re: ${job.data.subject}`,
  bodyText: reply,
  inReplyTo: job.data.messageId,
});

That single field is what keeps the conversation in one thread in the recipient's client. Use thread_id as the key for the agent's conversation memory, so the model sees the prior exchange rather than treating every inbound message as a cold start. More on how threads are keyed in email threading.

5. Add guardrails before you point it at real recipients

An agent with an inbox is an agent that reads untrusted input from strangers. Treat inbound body_text as hostile data, not as instructions.

  • Keep inbound content outside the system prompt. Pass it as user-role content, clearly delimited.
  • Allowlist recipients during development so a confused loop cannot email the world.
  • Cap sends per thread and per hour at the application level. One agent in a reply loop with an autoresponder can burn through a month of quota overnight.
  • Log every send with the mailbox ID and thread ID. When something goes wrong, you want the trail.
  • Ignore or quarantine automated bounces and out-of-office replies instead of feeding them back to the model.

The agent email security guide goes deeper on prompt injection by email, which is the failure mode that surprises most teams.

Choosing where the inbox lives

If you are weighing options, the practical comparison is between a mail API built for programmatic inboxes and bending a human mail provider to the task. We put the tradeoffs side by side in Robotomail vs the Gmail API. The short version: the Gmail API works for one agent attached to one account you control, and gets painful at ten. Per-agent provisioning in a single API call is the difference.

If your agent only needs to send and genuinely never receives, a transactional provider is fine. The moment a human can reply, you need an inbox.

FAQ

Do I need my own domain to connect an agent to an inbox?

No. Create the mailbox without domainId and it lives on a platform domain, which is enough for development and for plenty of production agents. Add a custom domain when you want the address to carry your brand.

How many mailboxes does one agent need?

Usually one. Give each agent a stable address so recipients can reply to the same place and your threading stays coherent. Spin up extra mailboxes when agents represent distinct functions, like support versus billing, rather than per conversation.

Can I use IMAP instead of webhooks?

You can, and we explain the tradeoffs in IMAP for AI agents. Webhooks are simpler for agent workloads: no long-lived connection, no UID bookkeeping, no idle timeouts, and the message arrives already parsed as JSON.

What happens to attachments?

Inbound attachments are stored and retrievable by the message, so the agent can fetch a PDF invoice or CSV and process it. Sending works the same way in reverse. The attachments reference has the exact calls.

Ready to wire this up? Create a mailbox, register a webhook, and have your agent sending and replying in an afternoon at robotomail.com.

Give your AI agent a real email address

Create a mailbox, connect your agent and test a conversation. Send, receive and retrieve the thread through one API.

Related posts