You built the outbound half of an email agent. It sends a well-crafted message, the recipient writes back six hours later... and your agent has no idea. The reply either gets ignored or — arguably worse — gets treated as a brand-new conversation, and the agent reintroduces itself to someone it emailed yesterday.

That gap between "can send" and "can converse" is where most email agents stall. Closing it takes four pieces: detection, context, routing, and a threaded response. Here's each one, using a Nylas Agent Account (in beta) as the mailbox — a hosted address the agent owns outright.

Step 1: know a reply when you see one

Every message.created webhook payload carries a thread_id. If the agent sent the original message, that thread already exists in your state store. So detection is a lookup, not a parsing exercise:

app.post("/webhooks/nylas", async (req, res) => {