Guide By finedesignz

How to Give Your AI Agents a Real Email Address (Complete Guide)

Most AI agent frameworks skip email entirely. Here's how to wire up programmatic email — create inboxes, send messages, handle replies, and react to events in real time.

Email is one of the most useful communication channels for AI agents — but most frameworks treat it as an afterthought. IMAP is a nightmare. SMTP requires MIME construction. And per-inbox SaaS pricing kills the unit economics of high-volume agent workloads.

Here’s how to give your agents real email addresses and handle the full send/receive/webhook lifecycle.

The architecture

A solid email-capable agent needs four things:

  1. An inbox — a real email address that can send and receive
  2. An outbound path — reliable SMTP or API-based sending
  3. An inbound path — a way to receive and store incoming messages
  4. Event notification — real-time notification when something arrives

IMAP polling handles #3 badly. It’s slow, resource-intensive, and not designed for programmatic use. Webhooks are the right primitive — push notification the moment an email arrives.

Step 1: Provision an inbox

import httpx

client = httpx.Client(
    base_url="https://api.emails4agents.com",
    headers={"X-API-Key": "e4a_your_key"}
)

# Create inbox
inbox = client.post("/v1/inboxes", json={
    "username": "research-agent",
    "domain_id": "your-domain-uuid",
    "display_name": "Research Agent"
}).json()

print(inbox["address"])  # [email protected]

Step 2: Register a webhook

webhook = client.post("/v1/webhooks", json={
    "url": "https://your-agent-server.com/webhooks/email",
    "events": ["message.received", "message.bounced"]
}).json()

Step 3: Handle incoming mail

Your webhook endpoint receives a POST with the full message:

from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/webhooks/email")
async def handle_email(request: Request):
    event = await request.json()
    if event["event"] == "message.received":
        message = event["data"]
        # Route to your agent
        await process_with_agent(
            inbox_id=message["inbox_id"],
            thread_id=message["thread_id"],
            from_address=message["from_address"],
            subject=message["subject"],
            body=message["text_body"],
            classification=message.get("classification"),
        )
    return {"ok": True}

Step 4: Send a reply

async def process_with_agent(inbox_id, thread_id, from_address, subject, body, classification):
    # Your agent logic here
    response_text = await your_llm(body)

    # Find the original message to reply to
    messages = client.get(f"/v1/threads/{thread_id}").json()
    original_id = messages[0]["id"]

    # Reply in-thread
    client.post(f"/v1/messages/{original_id}/reply", json={
        "text": response_text
    })

Using classification to route messages

If you’ve configured the AI classifier on the inbox, you get an intent label on every inbound message before your webhook fires:

if classification == "support_request":
    await route_to_support_agent(message)
elif classification == "sales_lead":
    await route_to_sales_agent(message)
elif classification == "spam":
    pass  # ignore

The classifier runs via OpenRouter so you can pick any model — fast/cheap for volume, powerful for complex routing.

What to avoid

  • Don’t poll — use webhooks for real-time notification
  • Don’t parse raw MIME — the API returns structured JSON fields for every message component
  • Don’t use shared inboxes — give each agent its own address for clean threading and attribution
  • Don’t skip idempotency keys — if your agent retries send operations, use idempotency_key to prevent duplicate emails

See the full API reference for all available endpoints.

Tags:

#ai-agents #email #tutorial #webhooks

Found this helpful?

Share it with someone who needs to read this.

finedesignz

Founder

AI agent infrastructure Email deliverability FastAPI / Python
View full profile →

Ready to Get Started?

Contact us today — we're here to help.

Ready to get started?

Start your free trial today. No credit card required.