How to implement email threading in an AI agent
Use Message-ID, In-Reply-To, and References; webhook the inbox; reply idempotently; Ask on send—and let the inbox API store threads.
Discuss this post in AI
Send a pre-filled prompt to ChatGPT, Claude, Gemini, or Perplexity — get a summary, ask follow-ups, or compare ideas from this guide.
Threading is how email remains a conversation instead of a pile of unrelated messages. AI agents that invent their own subject-line heuristics usually lose. Implement threading with standard headers, an inbox that already stores threads, and a send path gated by Ask.
Headers that matter
- Message-ID — unique id for each message
- In-Reply-To — parent message id
- References — chain of prior ids
Clients and servers use these fields to group mail. If your agent sends a reply without them, counterparties may start a new thread, and your memory model fractures. Prefer APIs that set headers correctly when you reply to a stored message.
Let the inbox API hold the thread
Agent Inbox keeps thread history. Do not reconstruct the entire conversation from raw IMAP-shaped scraping if the inbox already exposes the thread object. Your skill should request the active thread, not re-cluster the mailbox by normalized subject.
from agentinbox import AgentInbox
client = AgentInbox()
inbox = client.inboxes.create(username="desk", domain="agentinbox.space")
After provision, wire webhooks so Neuro OS wakes on new messages for that inbox. On each event: load thread → draft → Ask → send reply to the same thread id.
Idempotent replies
Webhooks retry. Operators click twice. Models get invoked again after a timeout. Store a processed-event key and a send intent id. If the outbound was already approved and sent, do not send again. If Ask is pending, do not open a second identical Ask for the same event.
Ask on send
Even with perfect threading, outbound mail changes the world. Neuro OS defaults sends to Ask. Present the full draft, recipients, and thread context. After approval, send as a proper reply. If policy requires a human to take over, forward the thread rather than summarizing it into a new subject.
Failure modes to test
| Failure | Symptom | Mitigation |
|---|---|---|
| Missing In-Reply-To | Split threads | Reply via inbox thread API |
| Subject rewrite | Human clients fork | Keep subject stable unless required |
| Double send | Duplicate customer mail | Idempotency keys |
| Cross-tenant mix | Wrong customer context | Scoped inbox groups |
| HTML injection | Unsafe render | Sanitize; markdown for model |
Security notes: rendering email safely. Memory notes: email as memory.
Forwarding and threads
Forwarding into the agent inbox should preserve enough headers for the new owner to continue the episode. Forwarding out for Ask review should likewise keep the chain readable. That is how operations move work without breaking the conversation—see you don’t need to receive email anymore.
What not to build
Do not build a private threading engine that ignores Message-ID because “the model can tell.” Do not poll every sixty seconds if webhooks are available. Do not auto-send replies to stay fast. The fast path is a correct draft behind Ask.
Threading is engineering, not prompt poetry. Use the standards, trust the inbox store, and keep humans on the send gate. Broader architecture sits in the definitive guide and build email agents.
Agent Inbox gives each role a mailbox people can reply to, with forwarding into Neuro OS when a human must see the thread. Outbound mail defaults to Ask. Run the role on Neuro OS. To scope the first inbox, get started.