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 takes about five minutes and no browser.
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 -X POST https://emailbump.com/api/v1/signup \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "accept_terms": true }'{ "api_key": "ebk_…", "account_key": "ebk_…", "email_verified": false }Store api_key — that is the project key everything below uses. Then read the code out of the email and confirm:
curl -X POST https://emailbump.com/api/auth/verify-email/code \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "code": "9MT89W" }'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 https://emailbump.com/api/v1/inbound/address \
-H "Authorization: Bearer $EMAILBUMP_API_KEY"{
"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 — and use it immediately. There is no limit and nothing to clean up afterwards. To receive on your own domain instead, publish the MX record this endpoint returns; we check it for you before you go hunting for mail that never came.
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.
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)
await handle(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 and we POST the message to you, body and attachment list included. Better when the thing that reacts is a backend rather than a long-running agent.
4. Read it
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 "https://emailbump.com/api/v1/inbound?search=invoice&limit=10" \
-H "Authorization: Bearer $EMAILBUMP_API_KEY"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_verdict and the authentication fields tell you how much to trust the sender’s identity, not their intentions.
5. Answer, in the same thread
This is the step that is easy to get wrong by hand.
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.
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 -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:
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.