An AI agent sends an email, a reply lands three hours later, and the agent has to answer two questions before it can do anything useful: which conversation is this, and what did I last say? Get the first one wrong and the agent's reply shows up in the recipient's inbox as a brand-new message instead of slotting into the existing thread. To the person on the other end, that looks broken — like the agent forgot the conversation it started.

Threading is the part of agent email that's easy to get almost right and quietly wrong. The fix lives in a few email headers most developers never touch, and in the Threads API that groups messages into conversations for you. This post walks through both, from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for when I'm testing a reply loop.

The three headers that make threading work

Threading runs on three email headers, not on subject lines. Every message carries a Message-ID — a globally unique identifier the sending server stamps on it. When someone replies, their mail client adds In-Reply-To (the Message-ID of the message being answered) and References (the full chain of Message-ID values, oldest to newest). Those two headers are how every mail client decides which messages belong together.