Thread Tracking

Automatic email threading with reply, reply-all, and forward support.

How Threading Works

Agent Email automatically tracks email threads using the In-Reply-To and References headers defined in RFC 2822. When you reply to a message, the correct headers are set automatically so email clients display the conversation as a thread.

Original email (msg_001)
  └── Reply from recipient (msg_002, In-Reply-To: msg_001)
       └── Agent reply (msg_003, In-Reply-To: msg_002)
            └── Another reply (msg_004, In-Reply-To: msg_003)

Each message in a thread shares a threadId for easy grouping.

List Threads

Retrieve all threads for a mailbox.

const threads = await tx.agentEmail.threads.list({
  mailbox: mailbox.id,
  limit: 20,
  sort: 'last_message_at:desc',
});
 
// Response
{
  data: [
    {
      id: 'thd_xyz789',
      subject: 'Research Request',
      messageCount: 4,
      participants: ['user@example.com', 'agent@agentmail.usetransactional.com'],
      lastMessageAt: '2025-01-10T14:30:00Z',
      unreadCount: 1,
    },
    // ...
  ],
}

Get Thread Messages

Retrieve all messages in a thread in chronological order.

const thread = await tx.agentEmail.threads.get(threadId);
 
for (const message of thread.messages) {
  console.log(`${message.from} at ${message.receivedAt}`);
  console.log(message.textPreview);
}

Reply

Reply to a specific message. Threading headers are set automatically.

await tx.agentEmail.reply({
  messageId: 'msg_002',
  html: '<p>Here is the updated analysis you requested.</p>',
  text: 'Here is the updated analysis you requested.',
});

The reply is sent to the original sender with the correct In-Reply-To and References headers.

Reply All

Reply to all participants in a thread.

await tx.agentEmail.replyAll({
  messageId: 'msg_002',
  html: '<p>Sharing this update with everyone on the thread.</p>',
});

This sends the reply to the original sender and all CC recipients.

Forward

Forward a message to a new recipient.

await tx.agentEmail.forward({
  messageId: 'msg_002',
  to: 'colleague@example.com',
  html: '<p>FYI — see the thread below.</p>',
});

Forwarded messages include the original message content and any attachments.

Thread Context for Agents

When building conversational agents, use thread context to maintain conversation history.

// Get full thread context for an incoming message
const message = await tx.agentEmail.inbox.get(incomingMessageId);
const thread = await tx.agentEmail.threads.get(message.threadId);
 
// Build context for your LLM
const conversationHistory = thread.messages.map((msg) => ({
  role: msg.from === mailbox.address ? 'assistant' : 'user',
  content: msg.textBody,
}));
 
// Generate response with context
const agentResponse = await llm.chat({
  messages: conversationHistory,
});
 
// Reply with agent's response
await tx.agentEmail.reply({
  messageId: incomingMessageId,
  html: agentResponse.html,
  text: agentResponse.text,
});

Next Steps