> ## Documentation Index
> Fetch the complete documentation index at: https://openmail-docs-reputation-lifecycle-webhooks.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Threading

> OpenMail automatically groups emails into threads by subject and message headers. Learn how threading works and how to read or update thread state.

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.).

We also append a quoted copy of the previous message to the body by default (the familiar `On … wrote:` block with `>`-prefixed lines). Pass `includeQuote: false` to send only your reply text.

## 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

<Steps>
  <Step title="Poll for unread threads">
    Fetch only threads your agent hasn't processed yet.

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    GET /v1/inboxes/:id/threads?is_read=false
    ```
  </Step>

  <Step title="Process the thread">
    Fetch messages, run your agent logic, send a reply if needed.

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    GET /v1/threads/:id/messages
    ```
  </Step>

  <Step title="Mark as read">
    After successful processing, mark the thread as read so it won't appear on the next poll.

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    PATCH /v1/threads/:id
    { "is_read": true }
    ```

    If your agent sends a reply, this happens automatically.
  </Step>
</Steps>

<Tip>
  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.
</Tip>
