How to give an AI agent
its own email inbox.
Not an alias, not a shared mailbox, not your Gmail. A real inbox the agent owns and reads from on its own identity — set up in about a minute.
Giving an agent its own inbox used to be a project: register a domain, configure MX records, stand up a mail server, set up DKIM and SPF, build an IMAP client the agent could use. Modern providers collapse most of this to an API call.
This is the minimum-viable version. At the end, your agent has a real email address, can send DKIM-signed messages from it, and can either poll or receive webhooks for inbound mail.
1. Create an identity
Sign up at console.loomal.ai. Create an identity — this provisions the mailbox, the vault, and the TOTP store under one record. Each identity gets a unique address (e.g. agent-x8k2m@loomal.ai) and an API key (loid-...).
For a custom domain (sales@yourcompany.com), paid plans let you configure your own. Set SPF, DKIM, and DMARC records once; Loomal handles per-identity signing from that point on.
2. Send a first email (sanity check)
Before wiring anything up, confirm outbound works with a one-liner.
curl -X POST https://api.loomal.ai/v0/messages/send \
-H "Authorization: Bearer $LOOMAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["you@example.com"],
"subject": "First email from my agent",
"text": "If you see this, it worked."
}'3. Configure inbound — webhook or poll
Two options. Webhook is better for production: Loomal POSTs to your endpoint the moment mail arrives. Polling is simpler for prototyping: your agent calls mail.list_messages on a schedule.
For webhooks, add the URL in the identity's Webhooks tab and sign the secret into your handler (see the Node.js webhook how-to for the receive-side code).
import os, requests, time
headers = {"Authorization": f"Bearer {os.environ['LOOMAL_API_KEY']}"}
while True:
res = requests.get(
"https://api.loomal.ai/v0/messages",
headers=headers,
params={"labels": "unread", "limit": 10},
)
for msg in res.json()["messages"]:
# msg['extractedText'] is LLM-ready
# Hand it to your agent, then mark read:
requests.patch(
f"https://api.loomal.ai/v0/messages/{msg['messageId']}",
headers=headers,
json={"addLabels": ["read"], "removeLabels": ["unread"]},
)
time.sleep(60)4. Reply in-thread
When the agent responds, use /v0/messages/:messageId/reply instead of /send. Loomal stitches the reply into the original thread automatically — no In-Reply-To or References headers to manage.
curl -X POST https://api.loomal.ai/v0/messages/$MSG_ID/reply \
-H "Authorization: Bearer $LOOMAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Yes, Tuesday at 2pm works. Sending an invite now." }'5. Hand the primitives to your framework
If your agent uses Claude Agent SDK, OpenAI Agents SDK, LangChain, LangGraph, CrewAI, Vercel AI SDK, Mastra, AutoGen, Pydantic AI, or n8n — see the framework guides for the one-config-block MCP setup. The REST approach works everywhere; MCP is shorter where it's supported.
FAQ
Can the agent have a custom address like support@yourcompany.com?
Yes on paid plans. Configure SPF, DKIM, and DMARC records for your domain; each identity you create can use an address on that domain with per-identity DKIM keys.
What happens if someone replies after the agent is off?
The reply lands in the inbox as normal. When the agent comes back online, it picks it up via webhook or the next poll. Mail persists in the mailbox until deleted.
How long are messages retained?
Free tier keeps messages for 30 days; paid plans have longer retention options up to indefinite. Archive to your own storage if you need permanent retention regardless of plan.
Related reading
Last updated: 2026-04-15