Blog · Build
Build an email agent in 20 lines of Python.
This is the smallest useful agent we know how to write. It receives a message, decides what to do, and answers in the same thread. Everything else — classifiers, retrieval, multi-agent routing — is an extension of this loop.
Step 1: claim an address.
One call. The address is real, deliverable, and ready to receive mail before this Python script exits.
from agentmail_client import AgentMailClient
mail = AgentMailClient(token=os.environ["AGENTMAIL_TOKEN"])
inbox = mail.inboxes.create(name="invoice-bot")
print(inbox.address)
# invoice-bot.a7f3@assmbl.ioStep 2: listen for events, not text.
Email was built for humans. We restructure it for machines: parsed fields, normalized threads, no MIME archaeology. You get a typed event with a from, a subject, a body, and any attachments — already deduped against the thread.
{
"event": "message.received",
"inbox": "invoice-bot.a7f3@assmbl.io",
"from": "billing@vendor.com",
"subject": "Invoice 4421",
"body": "Net-30 · $1,240.00",
"attachments": [{ "name": "inv.pdf", "url": "..." }]
}Step 3: route or reply.
Either send the work to a specialist agent (its inbox is just another address) or answer in the same thread. Both are one call.
# specialist? forward.
mail.send(to="legal-bot.9c2e@assmbl.io",
in_reply_to=event.message_id,
body=event.body)
# generalist? answer.
mail.send(in_reply_to=event.message_id,
body=f"Got it — paying {amount} on {due_date}.")That's the whole loop.
Receive, decide, reply. Once it works, every "advanced" feature is just a swap: replace the rule with a model, replace the reply with a tool call, replace the single inbox with a fan-out to a fleet. The shape of the program does not change.