Skip to main content
Threads group related messages into conversations. When a new message arrives, Nuntly automatically determines whether it belongs to an existing thread or starts a new one.

Threading algorithm

Nuntly uses the following logic to match incoming messages to threads, evaluated in order:
  1. In-Reply-To header. If the incoming message has an In-Reply-To header, Nuntly looks for a message in the same inbox with a matching Message-ID. If found, the new message joins that thread.
  2. References header. If no match is found via In-Reply-To, Nuntly checks the References header for any matching Message-ID in the same inbox.
  3. Subject matching. If no header match is found, Nuntly normalizes the subject line (stripping prefixes like Re: and Fwd:) and looks for a thread in the same inbox with a matching normalized subject that had activity within the last 7 days.
  4. New thread. If none of the above produce a match, a new thread is created.

List threads

You can list threads for a specific inbox. Filter by read status or spam flag.
import { Nuntly } from '@nuntly/sdk';

const nuntly = new Nuntly({
  apiKey: process.env.NUNTLY_API_KEY,
});

// List all threads in an inbox
const threads = await nuntly.inboxes.listThreads('ibx_01kabn43yqyxn2bx4ve84mczd3');

// Filter unread threads
const unreadThreads = await nuntly.inboxes.listThreads('ibx_01kabn43yqyxn2bx4ve84mczd3', {
  isRead: false,
});

// Filter spam threads
const spamThreads = await nuntly.inboxes.listThreads('ibx_01kabn43yqyxn2bx4ve84mczd3', {
  isSpam: true,
});

Available filters

ParameterDescription
isReadFilter by read status (true or false).
isSpamFilter by spam flag (true or false).
cursorCursor for pagination.
limitMaximum number of results to return (1-30, default 30).

Thread fields

FieldDescription
idThe unique thread identifier.
domainNameThe domain name.
inboxIdThe inbox this thread belongs to.
subjectThe original subject line.
lastMessageAtThe timestamp of the most recent message.
messageCountThe number of messages in the thread.
isReadWhether the thread has been read.
isSpamWhether the thread is marked as spam.
agentIdThe AI agent identifier, or null.

Retrieve a thread

Get the full details of a single thread. Retrieving a thread automatically marks it as read.
const thread = await nuntly.threads.retrieve('thr_01kabn43yqyxn2bx4ve84mczd3');

console.log('Subject:', thread.data.subject);
console.log('Messages:', thread.data.messageCount);
console.log('Last activity:', thread.data.lastMessageAt);
Retrieving a thread automatically sets isRead to true. If you need to mark it as unread again, use the update endpoint.

List thread messages

Retrieve the messages in a thread. Messages are returned in chronological order (oldest first).
const messages = await nuntly.threads.listMessages('thr_01kabn43yqyxn2bx4ve84mczd3');

for (const message of messages.data) {
  const direction = message.direction === 'received' ? 'Received' : 'Sent';
  console.log(`[${direction}] ${message.fromAddress}: ${message.subject}`);
}

Update a thread

Update thread properties such as read status, spam flag, or agent assignment.
// Mark as unread
await nuntly.threads.update('thr_01kabn43yqyxn2bx4ve84mczd3', {
  isRead: false,
});

// Mark as spam
await nuntly.threads.update('thr_01kabn43yqyxn2bx4ve84mczd3', {
  isSpam: true,
});

// Assign an AI agent
await nuntly.threads.update('thr_01kabn43yqyxn2bx4ve84mczd3', {
  agentId: 'my-support-agent',
});

Update request fields

FieldDescription
isReadSet to true or false to mark as read or unread.
isSpamSet to true or false to mark as spam or not spam.
agentIdThe AI agent identifier. Set to null to remove the agent.

Next steps