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
  • How threads work
  • Listing threads
  • Per inbox
  • Across your entire organization
  • Getting a full thread
  • Replying in a thread
  • Handling quoted text in replies
  • Using labels to track conversation state
  • Tips
Agent Patterns

How do I manage threaded conversations?

Maintain context across multi-turn email conversations with your agent.

Was this page helpful?
Edit this page
Previous

How do I build a human-in-the-loop workflow?

Keep humans in control of your agent's email communications.
Next
Built with

Threads are how AgentMail organizes conversations. Every time your agent sends a new email, a thread is created. Replies are automatically grouped into the same thread, giving your agent full conversation context.

How threads work

  1. Your agent sends an email, and a new thread is created automatically
  2. The recipient replies, and the reply is added to the same thread
  3. Your agent replies back, and it is added to the same thread
  4. The full conversation history stays organized in one place

You never need to create threads manually. AgentMail handles threading automatically using standard email headers (Message-ID, In-Reply-To, References).

Listing threads

Per inbox

Python
1threads = client.inboxes.threads.list(
2 inbox_id="agent@agentmail.to"
3)
4
5for t in threads.threads:
6 print(f"Thread: {t.subject} ({t.message_count} messages)")

Across your entire organization

Python
1# Get all threads from every inbox in your organization
2all_threads = client.threads.list()

This org-wide query is useful for building supervisor agents that monitor conversations across a fleet of other agents, analytics dashboards, or routing systems that escalate conversations between agents.

Getting a full thread

Retrieve a thread by its ID to access all messages in the conversation:

Python
1thread = client.threads.get(thread_id="thread_abc123")
2
3for message in thread.messages:
4 print(f"From: {message.from_}")
5 print(f"Subject: {message.subject}")
6 print(f"Body: {message.text}")

Replying in a thread

To continue a conversation, reply to the most recent message in the thread:

Python
1# Get the thread and find the latest message
2thread = client.threads.get(thread_id="thread_abc123")
3last_message = thread.messages[-1]
4
5# Reply to continue the conversation
6client.inboxes.messages.reply(
7 inbox_id="agent@agentmail.to",
8 message_id=last_message.message_id,
9 text="Thanks for your message! Here's what I found...",
10 html="<p>Thanks for your message! Here's what I found...</p>"
11)

Always provide both text and html when sending replies. This ensures readability across all email clients and improves deliverability.

Handling quoted text in replies

When people reply to emails, their email client often includes the entire previous conversation as quoted text. AgentMail provides extracted_text and extracted_html fields on received messages, which contain only the new reply content without the quoted history.

Python
1# Use extracted_text to get only the new content
2new_content = message.extracted_text
3
4# Falls back to full text if extraction isn't available
5content = message.extracted_text or message.text

This prevents your agent from re-processing the entire conversation history on every reply.

Using labels to track conversation state

Combine threads with labels to manage your agent’s workflow. For example, you can track which threads need a reply:

Python
1# Find threads that need a reply
2unreplied = client.inboxes.threads.list(
3 inbox_id="agent@agentmail.to",
4 labels=["unreplied"]
5)
6
7for thread in unreplied.threads:
8 thread_detail = client.threads.get(thread.thread_id)
9 last_message = thread_detail.messages[-1]
10
11 # Process and reply
12 reply_text = your_agent.process(last_message)
13 client.inboxes.messages.reply(
14 inbox_id="agent@agentmail.to",
15 message_id=last_message.message_id,
16 text=reply_text,
17 html=f"<p>{reply_text}</p>"
18 )
19
20 # Update labels
21 client.inboxes.messages.update(
22 inbox_id="agent@agentmail.to",
23 message_id=last_message.message_id,
24 add_labels=["replied"],
25 remove_labels=["unreplied"]
26 )

Tips

  • Use threads to maintain context in multi-turn conversations, so your agent can reference what was said earlier
  • Query org-wide threads with client.threads.list() to build dashboards or route conversations between agents
  • Use labels like unreplied, replied, escalated, and resolved to track conversation state
  • Always reply to the last message in a thread to keep email headers correct