Skip to main content
Reply tracking lets you connect incoming replies to the emails you sent, for threaded conversations, support tickets, and automated workflows. Lettr’s part is delivery: you send with a reply_to address on your inbound domain, and when someone replies, the reply is posted to that domain’s forwarding URL. Matching the reply to the original email, threading it, and filtering auto-replies all happen in your code.

How Reply Tracking Works

1

Send with Reply-To

Send an email whose reply_to is an address on your inbound domain that encodes a conversation ID.
2

Recipient Replies

The reply goes to that address, and Lettr posts it to your inbound domain’s forwarding URL.
3

Match Reply (your code)

Your handler extracts the conversation ID from the recipient address and looks up the conversation.
4

Thread Together (your code)

Your handler adds the reply to the conversation in your own database.

Variable Reply-To Addresses

The most reliable way to track replies is variable (plus) addressing in the reply_to field. Every address at an inbound domain is forwarded, so you don’t need to create these addresses anywhere:
Here mail.example.com is your inbound domain. When the customer replies, the reply is posted to its forwarding URL:
This example is shortened. See Email Parsing for every field.

Processing Replies

Extract the conversation ID from rcpt_to and match it to the original in your handler:
Anyone can send mail to any address at your inbound domain, including made-up reply+... addresses. Check that the ticket exists and that the sender belongs to it before you add the message, or use an unguessable token instead of a sequential ID.

Using Email Headers for Threading

Standard email headers can help your code group messages into threads: Lettr’s send API returns a request_id, not the Message-ID of the email it sends, and doesn’t let you set Message-ID yourself. So header-based matching works against Message-IDs you have stored from earlier inbound messages, for example the customer’s previous reply in the same conversation:

Building a Conversation Thread

Store and display threaded conversations in your own data model:

Auto-Reply Detection

Out-of-office replies and delivery reports also arrive at your reply addresses. Lettr doesn’t flag them, so detect them in your handler:
Don’t send an automatic response to an auto-reply. Two auto-responders answering each other can loop indefinitely.

Reply Matching Strategies

Mail clients send the reply to the reply_to address, so the ID always comes back in rcpt_to:
Some systems lowercase the local part of an address. If your IDs are case-sensitive, use an encoding that survives lowercasing, such as hex.

Strategy 2: Subject Line Tokens

Most mail clients keep the subject when replying, prefixed with Re::
Recipients can edit the subject, so use this as a fallback rather than your only signal.

Strategy 3: Message-ID Headers

Match In-Reply-To and References against Message-IDs of inbound messages you have stored, as shown in Using Email Headers for Threading. This connects follow-up replies within a conversation. It can’t connect the first reply to your original email, because the send API doesn’t return that email’s Message-ID.

Custom Headers Don’t Come Back

You can add custom headers to outgoing email with the headers field, but mail clients don’t copy them into replies. Don’t rely on headers such as X-Conversation-ID for reply matching; put the ID in the reply-to address instead.

Handling Reply Chains

When several people take part in a conversation:

Complete Support Ticket Example

In production, respond with a 2xx before doing slow work such as sending the acknowledgment, and skip messages whose Message-ID you have already processed. See Best Practices.

Email Parsing

The inbound payload structure

Routing

Route emails to handlers

Metadata

Track emails with metadata