For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
contact@agentmail.ccDiscord
DocumentationAPI ReferenceKnowledge BaseChangelog
DocumentationAPI ReferenceKnowledge BaseChangelog
    • Introduction
  • Getting Started
    • What is AgentMail?
    • What can I do with an inbox?
    • Creating your first inbox
    • Getting your API key
  • Agent Patterns
    • Handling inbound emails
    • Allowlists & blocklists
    • Managing threaded conversations
    • Human-in-the-loop workflows
    • Pods for multi-tenant email
    • Using labels to track state
  • Domains & Deliverability
    • Custom domain setup
    • SPF, DKIM, and DMARC setup
    • Emails going to spam
    • Warming Up
    • MX record conflicts
  • Troubleshooting
    • API 403 error
    • Rate limits
    • Preventing duplicate sends
    • Domain not verifying
    • Emails bouncing
    • Why are my emails not showing up?
  • DNS Guides
    • Cloudflare
    • GoDaddy
    • Route 53 (AWS)
    • Namecheap
LogoLogo
contact@agentmail.ccDiscord
On this page
  • 1. Webhooks (Recommended for Production)
  • 2. WebSockets (Best for Real-Time, No Public URL)
  • Which should I use?
Agent Patterns

How do I handle inbound emails with my agent?

Compare Webhooks and WebSockets for processing incoming emails.
Was this page helpful?
Edit this page
Previous

How do I set up allowlists and blocklists?

Control who your AI agent can send to and receive from.
Next
Built with

AgentMail offers two ways to process incoming emails, each suited to different use cases.

1. Webhooks (Recommended for Production)

Configure a webhook URL and AgentMail will send a POST request to your endpoint whenever an email arrives. This is the most reliable approach for production applications.

Python
1from flask import Flask, request
2from agentmail import AgentMail
3
4app = Flask(__name__)
5client = AgentMail()
6
7@app.route("/webhooks", methods=["POST"])
8def handle_webhook():
9 payload = request.json
10
11 if payload["event_type"] == "message.received":
12 message = payload["message"]
13
14 # Your agent processes the email here
15 reply_text = your_agent.process(message)
16
17 # Reply in the same thread
18 client.inboxes.messages.reply(
19 inbox_id=message["inbox_id"],
20 message_id=message["message_id"],
21 text=reply_text
22 )
23
24 return "OK", 200

Register your webhook via the API:

Python
1client.webhooks.create(
2 url="https://your-domain.ngrok-free.app/webhooks",
3 events=["message.received"],
4)

Always return a 200 OK immediately and process the webhook in the background. If your endpoint takes too long to respond, AgentMail will retry delivery. Also, filter out message.sent events to prevent your agent from replying to its own messages in a loop.

For local development, use ngrok to expose your local server. See the Webhook Setup Guide for full instructions.

2. WebSockets (Best for Real-Time, No Public URL)

Stream email events over a persistent connection. No public URL or ngrok needed, which makes this ideal for local development and desktop agents.

Python
1import asyncio
2from agentmail import AsyncAgentMail, Subscribe, Subscribed, MessageReceivedEvent
3
4client = AsyncAgentMail()
5
6async def main():
7 async with client.websockets.connect() as socket:
8 await socket.send_subscribe(Subscribe(
9 inbox_ids=["agent@agentmail.to"]
10 ))
11
12 async for event in socket:
13 if isinstance(event, Subscribed):
14 print(f"Subscribed to: {event.inbox_ids}")
15 elif isinstance(event, MessageReceivedEvent):
16 print(f"New email from: {event.message.from_}")
17 print(f"Subject: {event.message.subject}")
18
19asyncio.run(main())

The SDK also provides a synchronous client if you prefer:

Python
1from agentmail import AgentMail, Subscribe, MessageReceivedEvent
2
3client = AgentMail()
4
5with client.websockets.connect() as socket:
6 socket.send_subscribe(Subscribe(
7 inbox_ids=["agent@agentmail.to"]
8 ))
9
10 for event in socket:
11 if isinstance(event, MessageReceivedEvent):
12 print(f"New email from: {event.message.from_}")

See the WebSocket Overview for more details.

Which should I use?

MethodBest forRequires public URL?Real-time?
WebhooksProduction applicationsYesYes
WebSocketsLocal dev, desktop agentsNoYes

For most production use cases, webhooks are recommended. They are reliable, event-driven, and integrate well with serverless platforms. If you need real-time events without exposing a public URL, WebSockets are the best option.