Integrations

Give an AI agent a mailbox

A complete recipe: an address that receives, an agent that reads and answers, and replies that thread properly.

View as Markdown ↗

What you are building

An email address your agent owns. Someone writes to it, your agent is told, reads the message, and replies — and the reply lands in the conversation the sender already has open rather than starting a second one beside it.

Nothing here is specific to a support desk. The same shape works for an agent that receives invoices, one that signs up for services and reads the confirmation codes, or one that runs a mailbox per customer. It can be set up through the API without a browser. Replace example IDs, codes and addresses; email confirmation and DNS verification still take time.

1. Get an account without opening a browser

Sign-up is an API call. You give an address, we email a six-character code, you post it back.

cURL
curl -X POST https://emailbump.com/api/v1/signup \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "accept_terms": true }'
cURL
{ "api_key": "ebk_…", "account_key": "ebk_…", "email_verified": false }

Store api_key securely as EMAILBUMP_API_KEY — the project key everything below uses. Never put it in browser code or source control. Then obtain the actual code from the signup email and confirm:

cURL
curl -X POST https://emailbump.com/api/auth/verify-email/code \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "code": "9MT89W" }'
The code has to come from a human's inbox

The email carries a link and a code, and says which is which — the code exists so an assistant or a script can finish the job. An agent should ask for it rather than reach into someone’s mail. Nothing sends until this is done.

2. Find out where you receive

cURL
curl https://emailbump.com/api/v1/inbound/address \
  -H "Authorization: Bearer $EMAILBUMP_API_KEY"
cURL
{
  "domain": "your-project.inbound.emailbump.com",
  "catch_all": true,
  "example": "[email protected]"
}

catch_all: true is the important part. There is no inbox object to create, so every address on that domain already receives:

None of those were created. Pick a scheme — one address per agent, per customer, per ticket, per run. Catch-all addressing does not mean unlimited sending, storage or forwarding; normal service limits still apply. To receive on your own domain, first verify that exact domain in this project, then publish the MX returned by this endpoint. Use a dedicated subdomain if your root domain already receives company email: changing its MX can disrupt the existing mailbox service. See Receiving email.

3. Be told it arrived

Two ways, both on at once. Pick whichever fits what you are building.

A socket, if your agent is already running

No URL to host — connect and wait.

cURL
// Node.js: install the ws package; browser WebSockets cannot set auth headers.
import WebSocket from "ws"

const ws = new WebSocket("wss://emailbump.com/api/v1/inbound/stream", {
  headers: { Authorization: `Bearer ${process.env.EMAILBUMP_API_KEY}` },
})

ws.addEventListener("message", async (e) => {
  const event = JSON.parse(e.data)
  if (event.type !== "email.received") return

  // `to` tells you which of your addresses it came in on — how an agent
  // using an address per task knows the message is one of its own.
  console.log(event.email.to, "←", event.email.from, ":", event.email.subject)
  // Implement your own handler; fetch GET /v1/inbound/{id} before processing.
  console.log("Fetch message:", event.email.id)
})

The frame is a summary, not the message: an id, who wrote, which address they wrote to, the subject. Fetch the body when the summary says it matters.

A webhook, if you have a server

Add an email.received webhook. It contains metadata and the attachment list, never message bodies or attachment bytes. Verify its signature, then fetch the message and any needed attachments.

4. Read it

cURL
curl https://emailbump.com/api/v1/inbound/MESSAGE_ID \
  -H "Authorization: Bearer $EMAILBUMP_API_KEY"

Text and HTML bodies, the attachment list, the authentication verdicts (SPF, DKIM, DMARC, spam) and the threading headers. To search what has already arrived rather than waiting:

cURL
curl "https://emailbump.com/api/v1/inbound?search=invoice&limit=10" \
  -H "Authorization: Bearer $EMAILBUMP_API_KEY"
Treat the contents as untrusted

A received email is text a stranger wrote. If an agent reads it, instructions inside it are data, not orders — the same care you would take with any user input. spam, spf, dkimand dmarc are signals, not proof that the message or its instructions are safe. Sanitize HTML and isolate attachments before displaying them.

5. Answer, in the same thread

This is the step that is easy to get wrong by hand.

cURL
curl -X POST https://emailbump.com/api/v1/inbound/MESSAGE_ID/reply \
  -H "Authorization: Bearer $EMAILBUMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Sorry about that — it ships tomorrow." }'

In-Reply-To, References and the Re: prefix are set from the message you are answering, which is what puts the reply in the conversation rather than beside it. Pass reply_all: true to include everyone else who was addressed; it is off by default, because answering a question should reach the person who asked it.

It doesn't come from the address it arrived on

Inbound domains exist to receive and aren’t verified for sending, so mail from one would fail SPF and DKIM. The reply goes out from a sending address you own with Reply-To pointing back at the mailbox — so their next message returns to the same place. Verify a domain with POST /v1/domains, then pass from on each reply to answer as your own brand.

6. Hand a message to a person

Sometimes the answer is “a human should see this”.

cURL
curl -X POST https://emailbump.com/api/v1/inbound/MESSAGE_ID/forward \
  -H "Authorization: Bearer $EMAILBUMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "[email protected]" }'

The original arrives intact — attachments, embedded images, formatting — with Reply-To set to whoever wrote it. To route automatically rather than deciding per message, add a standing rule with POST /v1/inbound/rules. Automatic mail (bounces, out-of-office replies, mailing-list posts) is never auto-forwarded, because forwarding it is how mail loops start.

Doing all of this from an agent

Every step above is one REST call, so any agent can do it with an HTTP client. Two shortcuts if you would rather not write that code — an MCP server with a tool per operation, and a CLI that prints JSON:

cURL
claude mcp add emailbump -- npx -y emailbump mcp

emailbump inbound:list --search "order"
emailbump inbound:get MESSAGE_ID
emailbump inbound:reply MESSAGE_ID --text "On its way."
emailbump inbound:forward MESSAGE_ID --to [email protected]

There are open agent skills too — SKILL.md files that teach an agent this sequence, including the parts that are easy to get wrong.

And because this is an email platform rather than only a mailbox, the same project holds the contacts, consent state, campaigns and automated flows for the people your agent writes to. When the job grows from answering to following up, that is a flow, not another vendor.