Skip to main content
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:
  1. Check In-Reply-To header - If it matches an existing message’s Message-ID, the email joins that thread.
  2. Check References header - If any value matches an existing message’s Message-ID, the email joins that thread.
  3. 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
1

Poll for unread threads

Fetch only threads your agent hasn’t processed yet.
GET /v1/inboxes/:id/threads?is_read=false
2

Process the thread

Fetch messages, run your agent logic, send a reply if needed.
GET /v1/threads/:id/messages
3

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.