Threads and Conversation Context
A thread in mailbot is the persistent context for a back-and-forth exchange. When a customer replies, mailbot does not start a new conversation. It resolves the reply to the existing thread so your code, your agent, and your dashboard all see one coherent history.
Threading algorithm
When mailbot receives a message (inbound) or sends one (outbound), it tries to attach it to an existing thread in this order:
In-Reply-Toheader — RFC 5322 reply pointer. If the value matches aMessage-IDmailbot already knows, the new message attaches to that thread.Referencesheader — full chain of priorMessage-IDvalues. mailbot walks this chain right-to-left and attaches to the first known message.- Subject match within 7 days — if neither header resolves, mailbot looks for a thread with the same normalized subject in the same inbox in the last 7 days.
- New thread — if no match, a fresh thread is created.
This order is deliberate. Headers are authoritative. Subject match is a recovery path for clients that strip headers.
Header preservation on outbound replies
When you reply to a message via POST /v1/messages/:id/reply, mailbot:
- generates a new
Message-IDfor your reply - sets
In-Reply-Toto the original message'sMessage-ID - prepends the original
Message-IDtoReferences - preserves the original subject with a single
Re:prefix
This means downstream clients (Gmail, Outlook, Apple Mail) thread your reply correctly without you having to pass any header yourself.
Persistent context across replies
Threads carry context that persists across every message in the conversation:
- labels — labels applied to the thread are inherited by new messages joining it
- assignment — if you tag a thread with a handler (operator, agent, queue), that tag survives replies
- engagement — open and click counts are per-message, but reply behavior on the thread itself is visible at the thread level
- direction history — every message records
inboundoroutbound, so an agent reading the thread can reconstruct who said what
An AI agent reading a thread does not need to re-derive context from scratch. It can fetch the thread, walk messages in order, and act on the latest inbound state.
Thread identifier vs message identifier
Two identifiers matter:
thread_id— stable across the lifetime of the conversationmessage_id— unique per message; equals the emailMessage-IDheader
Use thread_id for context. Use message_id when you need to act on a specific message (reply, fetch, replay).
Edge cases
Subject-only match limitations
The 7-day subject match is a fallback. It will not attach a reply if:
- the subject changes meaningfully
- more than 7 days have passed since the prior message
- the subject is too short to be distinctive (single word, all whitespace, etc.)
If you operate on long-running conversations, encourage upstream callers to preserve In-Reply-To and References rather than depending on subject match.
Reply-to-self prevention
When mailbot sends an outbound reply, the to field is computed from the inbound message's from, never echoed back to your inbox address. This prevents the reply-to-self loop where an automated reply triggers another inbound, which triggers another reply, and so on.
Multi-recipient threads
If a thread has multiple external participants, replies go to the original sender by default. To reply to all, pass an explicit to array. mailbot will not auto-broadcast to every prior recipient.