Skip to main content

List Threads

curl -X GET "https://inbound.new/api/e2/mail/threads?limit=25&unread=true" \
  -H "Authorization: Bearer YOUR_API_KEY"

GET /api/e2/mail/threads

List email threads (conversations) for your inbox with cursor-based pagination. This is the primary endpoint for building an inbox UI. What is a Thread? A thread groups related emails together based on the In-Reply-To and References headers, similar to how Gmail groups conversations. Each thread contains both inbound (received) and outbound (sent) messages. Use with /mail/threads/:id: Use this endpoint to list threads, then use GET /mail/threads/:id to fetch all messages in a specific thread.

Query Parameters

limit
integer
default:"25"
Maximum number of threads to return (1-100).
cursor
string
Cursor for pagination. Pass the thread ID from pagination.next_cursor of the previous response to get the next page.
Search query to filter threads by subject or participant emails. Case-insensitive partial match.
unread
string
default:"false"
Filter by unread status. Set to true to only return threads with unread messages.
domain
string
Filter threads by domain. Accepts domain ID (e.g., dom_xxx) or domain name (e.g., example.com).Returns threads where any participant email matches the domain.
address
string
Filter threads by email address. Accepts address ID (e.g., addr_xxx) or raw email address.Returns threads where the address is a participant.

Response

threads
array
Array of thread objects matching the query, sorted by last message date (newest first).
pagination
object
Pagination metadata for cursor-based pagination.
filters
object
Applied filters for this query.
{
  "threads": [
    {
      "id": "thread_abc123",
      "root_message_id": "<[email protected]>",
      "normalized_subject": "project update",
      "participant_emails": [
        "[email protected]",
        "[email protected]",
        "[email protected]"
      ],
      "participant_names": [
        "Alice Johnson <[email protected]>",
        "[email protected]",
        "Bob Smith <[email protected]>"
      ],
      "message_count": 5,
      "last_message_at": "2024-01-15T14:30:00Z",
      "created_at": "2024-01-15T10:00:00Z",
      "latest_message": {
        "id": "eml_xyz789",
        "type": "inbound",
        "subject": "Re: Project update",
        "from_text": "Alice Johnson <[email protected]>",
        "text_preview": "Thanks for the update! I have a few questions about the timeline...",
        "is_read": false,
        "has_attachments": true,
        "date": "2024-01-15T14:30:00Z"
      },
      "has_unread": true,
      "is_archived": false,
      "unread_count": 2
    }
  ],
  "pagination": {
    "limit": 25,
    "has_more": true,
    "next_cursor": "thread_abc123"
  },
  "filters": {
    "unread_only": true
  }
}

Get Thread

curl -X GET https://inbound.new/api/e2/mail/threads/thread_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

GET /api/e2/mail/threads/:id

Retrieve a complete email thread (conversation) with all messages. What You Get:
  • Thread metadata (subject, participants, timestamps)
  • All messages in the thread (both inbound and outbound)
  • Messages sorted chronologically by thread position
Message Types:
  • inbound - Emails you received
  • outbound - Emails you sent (includes delivery status)

Response

thread
object
Thread metadata.
messages
array
Array of all messages in the thread, sorted by thread position (chronological).
total_count
number
Total number of messages returned.
{
  "thread": {
    "id": "thread_abc123",
    "root_message_id": "<[email protected]>",
    "normalized_subject": "project update",
    "participant_emails": [
      "[email protected]",
      "[email protected]"
    ],
    "participant_names": [
      "Alice Johnson <[email protected]>",
      "[email protected]"
    ],
    "message_count": 3,
    "last_message_at": "2024-01-15T14:30:00Z",
    "created_at": "2024-01-15T10:00:00Z",
    "updated_at": "2024-01-15T14:30:00Z"
  },
  "messages": [
    {
      "id": "eml_first123",
      "message_id": "<[email protected]>",
      "type": "inbound",
      "thread_position": 0,
      "subject": "Project update",
      "text_body": "Here's the latest update on the project...",
      "html_body": "<p>Here's the latest update on the project...</p>",
      "from": "Alice Johnson <[email protected]>",
      "from_name": "Alice Johnson",
      "from_address": "[email protected]",
      "to": ["[email protected]"],
      "cc": [],
      "bcc": [],
      "date": "2024-01-15T10:00:00Z",
      "received_at": "2024-01-15T10:00:01Z",
      "sent_at": null,
      "is_read": true,
      "read_at": "2024-01-15T10:05:00Z",
      "has_attachments": false,
      "attachments": [],
      "in_reply_to": null,
      "references": [],
      "headers": {},
      "tags": []
    },
    {
      "id": "eml_reply456",
      "message_id": "<[email protected]>",
      "type": "outbound",
      "thread_position": 1,
      "subject": "Re: Project update",
      "text_body": "Thanks for the update! Here are my thoughts...",
      "html_body": "<p>Thanks for the update! Here are my thoughts...</p>",
      "from": "[email protected]",
      "from_name": null,
      "from_address": "[email protected]",
      "to": ["[email protected]"],
      "cc": [],
      "bcc": [],
      "date": "2024-01-15T12:00:00Z",
      "received_at": null,
      "sent_at": "2024-01-15T12:00:00Z",
      "is_read": true,
      "read_at": "2024-01-15T12:00:00Z",
      "has_attachments": false,
      "attachments": [],
      "in_reply_to": "<[email protected]>",
      "references": ["<[email protected]>"],
      "headers": {
        "In-Reply-To": "<[email protected]>",
        "References": "<[email protected]>"
      },
      "tags": [],
      "status": "sent",
      "failure_reason": null
    },
    {
      "id": "eml_reply789",
      "message_id": "<[email protected]>",
      "type": "inbound",
      "thread_position": 2,
      "subject": "Re: Project update",
      "text_body": "Great points! I have a few questions...",
      "html_body": "<p>Great points! I have a few questions...</p>",
      "from": "Alice Johnson <[email protected]>",
      "from_name": "Alice Johnson",
      "from_address": "[email protected]",
      "to": ["[email protected]"],
      "cc": [],
      "bcc": [],
      "date": "2024-01-15T14:30:00Z",
      "received_at": "2024-01-15T14:30:01Z",
      "sent_at": null,
      "is_read": false,
      "read_at": null,
      "has_attachments": true,
      "attachments": [
        {
          "filename": "questions.pdf",
          "contentType": "application/pdf",
          "size": 125678,
          "contentId": null
        }
      ],
      "in_reply_to": "<[email protected]>",
      "references": [
        "<[email protected]>",
        "<[email protected]>"
      ],
      "headers": {},
      "tags": []
    }
  ],
  "total_count": 3
}

Threading Logic

Email threads are created automatically based on standard email headers:

Thread Grouping Rules

  1. In-Reply-To Header: Links a message to its parent
  2. References Header: Contains the full chain of Message-IDs
  3. Normalized Subject: Fallback grouping by subject (with Re:, Fwd: stripped)

Example Thread Structure

Thread: "Project Update"
├─ Message 1 (Inbound) - "Project update"
│  Message-ID: <[email protected]>

├─ Message 2 (Outbound) - "Re: Project update"
│  In-Reply-To: <[email protected]>
│  References: <[email protected]>

└─ Message 3 (Inbound) - "Re: Project update"
   In-Reply-To: <[email protected]>
   References: <[email protected]> <[email protected]>

Building an Inbox UI

Step 1: List Threads

Use /mail/threads to display a thread list (like Gmail’s inbox):
const { threads, pagination } = await inbound.mail.threads.list({
  limit: 25,
  unread: true
})

// Display threads
for (const thread of threads) {
  console.log(`[${thread.has_unread ? '●' : ' '}] ${thread.normalized_subject}`)
  console.log(`   ${thread.participant_names.join(', ')}`)
  console.log(`   ${thread.latest_message.text_preview}`)
  console.log(`   ${thread.message_count} messages, ${thread.unread_count} unread`)
  console.log()
}

Step 2: Display Thread

When user clicks a thread, use /mail/threads/:id to show all messages:
const { thread, messages } = await inbound.mail.threads.get('thread_abc123')

// Display conversation
console.log(`Thread: ${thread.normalized_subject}`)
console.log(`Participants: ${thread.participant_names.join(', ')}`)
console.log()

for (const message of messages) {
  console.log(`[${message.type === 'inbound' ? '→' : '←'}] ${message.from}`)
  console.log(`   ${message.subject}`)
  console.log(`   ${message.text_body}`)
  console.log()
}

Step 3: Reply to Thread

Use /emails/:id/reply to reply within the thread:
// Reply to the thread (uses thread ID)
const reply = await inbound.emails.reply('thread_abc123', {
  from: '[email protected]',
  text: 'Thanks for your questions!',
  html: '<p>Thanks for your questions!</p>'
})

Build docs developers (and LLMs) love