I’m building a cold email follow-up workflow in n8n using Gmail API.
Problem: When I send a follow-up email, it shows as a reply in MY sent box (same thread), but in the CLIENT’s inbox it appears as a NEW separate email thread.
What I’m doing:
- Storing threadId and Message-ID from first email in Google Sheet
- Using Gmail API POST /messages/send with threadId
- Setting In-Reply-To and References headers with the Message-ID
Encode Email code:
const emailLines = [
`To: ${toEmail}`,
`From: editor.mohammad.faisal@gmail.com`,
`Subject: ${subject}`,
`In-Reply-To: ${lastMessageId}`,
`References: ${lastMessageId}`,
`Content-Type: text/plain; charset=utf-8`,
``,
body
];
The lastMessageId comes from Fetch Previous Email node’s last message id.
How can I make the follow-up appear as a reply in the client’s inbox too?
Describe the problem/error/question
What is the error message (if any)?
Please share your workflow
(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)
Share the output returned by the last node
Information on your n8n setup
- n8n version:
- Database (default: SQLite):
- n8n EXECUTIONS_PROCESS setting (default: own, main):
- Running n8n via (Docker, npm, n8n cloud, desktop app):
- Operating system:
1 Like
The issue is most likely occurring because you are using Gmail’s internal message ID instead of the RFC 2822 Message-ID header. There is a mismatch between Gmail and other email clients. Gmail uses threadId and other clients use, In-Reply-To and References headers against the original Message-ID header value.
Make sure you are grabbing the actual Message-ID header from the sent message(example@example.gmail.com) when you store the Message-ID from the first email. Fetch the sent message and pull from the payload headers array where name === “Message-ID”.
In your follow-up, your In-Reply-To and References should use the exact value including the angle brackets. This is what the recipient’s email client will match against to thread it correctly.
1 Like
Hi Mohammad!
I’ve spent quite a bit of time troubleshooting Gmail API headers and thread logic in n8n, and this specific issue is usually down to how the Subject line or the Message-ID formatting is handled. Even with the right headers, Gmail can be very picky about what it considers a single thread on the recipient’s side.
A few things we could check together:
-
Subject Matching: Gmail often requires the subject to be identical (including the "Re: " prefix) to thread correctly in the client’s inbox.
-
Message-ID Formatting: Ensure the lastMessageId is wrapped in angle brackets < >, as the API can fail to link them otherwise.
-
Thread ID Sync: Sometimes the threadId needs to be passed at the top level of the API request, not just within the encoded raw email.
I’m a developer focused on n8n and technical automation. I’ve built several cold outreach infrastructures and lead-management systems where deliverability and threading were top priorities.
The Details:
Reach me here:
I’d be happy to take a look at your full workflow JSON and help you get those replies nesting correctly!
Best,
Mikhail