OpenMail automatically groups related emails into threads using standard RFC 2822 email headers.
How it works
When an email arrives or is sent, we resolve which thread it belongs to:
- Check
In-Reply-To header - If it matches an existing message’s Message-ID, the email joins that thread.
- Check
References header - If any value matches an existing message’s Message-ID, the email joins that thread.
- No match - A new thread is created.
Outbound replies
When you send with a threadId, we automatically set:
In-Reply-To → the Message-ID of the last message in the thread
References → all Message-ID values from the thread
This ensures your reply threads correctly in the recipient’s email client (Gmail, Outlook, etc.).
Thread context
Fetch all messages in a thread via GET /v1/threads/:id/messages. Messages are returned in chronological order, giving your agent the full conversation history to inform its next action.
Read/unread tracking
Every thread has an is_read flag that tracks whether your agent has processed it. This prevents agents from reprocessing the same emails.
How it works
- New inbound threads start as unread (
is_read: false)
- Sending a reply automatically marks the thread as read
- Your agent explicitly marks threads as read via
PATCH /v1/threads/:id
Recommended flow
Poll for unread threads
Fetch only threads your agent hasn’t processed yet.GET /v1/inboxes/:id/threads?is_read=false
Process the thread
Fetch messages, run your agent logic, send a reply if needed.GET /v1/threads/:id/messages
Mark as read
After successful processing, mark the thread as read so it won’t appear on the next poll.PATCH /v1/threads/:id
{ "is_read": true }
If your agent sends a reply, this happens automatically.
If your agent uses webhooks or WebSockets, the same pattern applies — mark the thread as read after handling the event. Then use ?is_read=false as a safety net to catch any events missed during downtime.