Cold email outreach at scale requires personalization that actually converts. Generic templates get ignored. Manual research takes hours per prospect. This n8n agent solves both problems by combining AI-powered prospect research with automated, personalized email sequences that feel human-written. You'll learn how to build a complete cold outreach system that researches prospects, generates custom emails, and manages follow-up sequences automatically.
The Problem: Cold Email Outreach That Doesn't Scale
Current challenges:
- Manual prospect research takes 15-30 minutes per lead
- Generic email templates achieve <2% response rates
- Follow-up sequences require constant manual tracking
- Personalization at scale is nearly impossible without a large team
- CRM data entry and campaign management consume hours daily
Business impact:
- Time spent: 20+ hours/week on outreach for 100 prospects
- Cost: $2,000-4,000/month for VA or SDR time
- Conversion loss: 60-80% lower response rates with generic emails
- Missed opportunities: 70% of prospects never receive follow-ups
Manual cold email processes create a bottleneck between lead generation and actual conversations. Sales teams either sacrifice personalization for volume or spend unsustainable time researching each prospect.
The Solution Overview
This n8n agent automates the entire cold email workflow from prospect intake to follow-up sequences. It uses AI to research each prospect's company and role, generates personalized email copy based on custom templates, and manages multi-touch follow-up campaigns automatically. The system integrates with your CRM, email provider, and AI research tools to create a hands-off outreach machine that maintains the personal touch of manual research. Built entirely in n8n, this workflow handles everything from data enrichment to delivery tracking without requiring custom code.
What You'll Build
This cold email agent delivers complete outreach automation with AI-powered personalization:
| Component | Technology | Purpose |
|---|---|---|
| Prospect Intake | Google Sheets/Airtable | Centralized lead list management |
| AI Research | OpenAI GPT-4 | Company and prospect background analysis |
| Email Generation | Custom Prompts + GPT-4 | Personalized email copy creation |
| Email Delivery | Gmail/SendGrid | Automated sending with tracking |
| Follow-up Logic | n8n Schedule + Function Nodes | Multi-touch sequence management |
| CRM Sync | HubSpot/Salesforce | Contact and activity logging |
| Response Detection | Email Webhook | Automatic reply monitoring |
Key capabilities:
- Automatic prospect research using AI web scraping
- Custom email generation based on industry and role
- Multi-step follow-up sequences (3-5 touches)
- Response tracking and campaign analytics
- CRM integration for seamless data flow
- Personalization variables (company name, role, pain points)
- A/B testing support for email variants
Prerequisites
Before starting, ensure you have:
- n8n instance (cloud or self-hosted version 1.0+)
- OpenAI API account with GPT-4 access
- Gmail account with App Password or SendGrid API key
- Google Sheets or Airtable for prospect management
- CRM account (HubSpot, Salesforce, or Pipedrive)
- Basic understanding of email deliverability best practices
- Domain with proper SPF/DKIM/DMARC records configured
Step 1: Set Up Prospect Data Source
Configure your prospect intake system to feed leads into the automation workflow.
Create the prospect spreadsheet:
- Set up Google Sheets with these required columns:
Email,First Name,Last Name,Company,Title,LinkedIn URL,Status,Last Contact Date - Add optional enrichment columns:
Company Size,Industry,Pain Points,Recent News - Create a "Status" column with values:
New,Researched,Email Sent,Follow-up 1,Follow-up 2,Responded,Unsubscribed
Node configuration:
{
"name": "Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "read",
"sheetId": "YOUR_SHEET_ID",
"range": "A:H",
"options": {
"headerRow": 1
}
}
}
Why this works:
Google Sheets provides a simple interface for sales teams to add prospects while giving n8n structured data to process. The status column enables the workflow to track each prospect's position in the outreach sequence and prevent duplicate emails. Using a spreadsheet instead of direct CRM integration allows for easy manual review and editing before automation kicks in.
Step 2: AI-Powered Prospect Research
Build the research engine that gathers personalized context about each prospect.
Configure the research workflow:
- Add an HTTP Request node to scrape the company website using Apify or Bright Data
- Connect an OpenAI node with a custom research prompt
- Set up a Function node to extract and structure key insights
- Add error handling for prospects with limited online presence
Research prompt configuration:
// Function node to prepare research prompt
const companyName = $input.item.json.Company;
const prospectTitle = $input.item.json.Title;
const linkedinUrl = $input.item.json['LinkedIn URL'];
const researchPrompt = `Research this prospect and company:
Company: ${companyName}
Prospect Title: ${prospectTitle}
LinkedIn: ${linkedinUrl}
Provide:
1. Company's main product/service (1 sentence)
2. Recent company news or achievements (last 3 months)
3. Likely pain points for someone in the ${prospectTitle} role
4. Relevant industry trends affecting this company
5. Personalization angle for cold outreach
Format as JSON with keys: product, news, painPoints, trends, angle`;
return {
json: {
prompt: researchPrompt,
prospectEmail: $input.item.json.Email
}
};
OpenAI node settings:
{
"model": "gpt-4",
"temperature": 0.7,
"maxTokens": 500,
"messages": [
{
"role": "system",
"content": "You are a B2B sales research assistant. Provide concise, actionable insights for cold email personalization."
},
{
"role": "user",
"content": "={{ $json.prompt }}"
}
]
}
Why this approach:
AI research replaces 15-30 minutes of manual work per prospect. The structured prompt ensures consistent output format that downstream nodes can parse reliably. Using GPT-4 instead of GPT-3.5 improves research quality significantly—it better understands company contexts and identifies relevant pain points. The JSON output format makes it easy to inject research findings directly into email templates.
Step 3: Generate Personalized Email Copy
Create the email generation system that turns research into compelling outreach messages.
Build the email template system:
- Create a Function node with your base email template structure
- Add dynamic variables for research insights
- Connect to OpenAI for final copy polish
- Include A/B testing logic for subject lines
Email generation function:
// Extract research data
const research = JSON.parse($input.item.json.researchOutput);
const firstName = $input.item.json['First Name'];
const company = $input.item.json.Company;
// Base template with personalization
const emailTemplate = `Subject: Quick question about ${company}'s ${research.product}
Hi ${firstName},
I noticed ${research.news} - congratulations on that milestone.
Given your role as ${$input.item.json.Title}, I imagine ${research.painPoints} might be on your radar.
We've helped similar companies in ${research.trends} by [YOUR VALUE PROP]. Specifically, [SPECIFIC BENEFIT].
Would it make sense to explore how this could work for ${company}? I have a 15-minute slot [DAY] at [TIME] if you're open to it.
Best,
[YOUR NAME]
P.S. ${research.angle}`;
return {
json: {
emailBody: emailTemplate,
prospectEmail: $input.item.json.Email,
firstName: firstName,
company: company
}
};
Polish with AI:
{
"name": "Polish Email Copy",
"type": "n8n-nodes-base.openAi",
"parameters": {
"model": "gpt-4",
"temperature": 0.8,
"messages": [
{
"role": "system",
"content": "You are an expert cold email copywriter. Make this email more conversational and compelling while keeping it under 150 words. Maintain all personalization elements."
},
{
"role": "user",
"content": "={{ $json.emailBody }}"
}
]
}
}
Why this works:
The two-stage approach (template + AI polish) balances consistency with natural language. Your template ensures key messaging stays on-brand while AI polish removes robotic phrasing. The research variables inject genuine personalization that recipients can verify—not generic flattery. Keeping emails under 150 words dramatically improves mobile readability and response rates.
Step 4: Email Delivery and Tracking
Configure the sending infrastructure with proper deliverability and tracking.
Set up Gmail sending:
{
"name": "Send Email",
"type": "n8n-nodes-base.gmail",
"parameters": {
"operation": "send",
"to": "={{ $json.prospectEmail }}",
"subject": "={{ $json.emailSubject }}",
"message": "={{ $json.polishedEmail }}",
"options": {
"sendAsHtml": false,
"ccList": "your-tracking-email@company.com"
}
}
}
Add tracking pixel:
// Function node to add tracking
const trackingId = `${$json.prospectEmail}-${Date.now()}`;
const emailWithTracking = $json.polishedEmail + `
<img src="https://your-tracking-domain.com/pixel/${trackingId}" width="1" height="1">`;
return {
json: {
finalEmail: emailWithTracking,
trackingId: trackingId,
prospectEmail: $json.prospectEmail
}
};
Update CRM and spreadsheet:
{
"name": "Update Status",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "update",
"sheetId": "YOUR_SHEET_ID",
"range": "G{{ $json.rowNumber }}",
"options": {
"valueInputMode": "USER_ENTERED"
},
"dataToSend": "defineInNode",
"fieldsUi": {
"values": [
{
"fieldId": "Status",
"fieldValue": "Email Sent"
},
{
"fieldId": "Last Contact Date",
"fieldValue": "={{ $now.toISO() }}"
}
]
}
}
}
Critical configuration:
- Sending limits: Cap at 50 emails/day per Gmail account to avoid spam flags
- Delay between sends: Add 2-5 minute random delays using Wait node
- Reply-to address: Use a monitored inbox, not a no-reply address
- Unsubscribe link: Include in email footer for compliance
Step 5: Automated Follow-Up Sequences
Build the multi-touch follow-up system that increases response rates by 3-5x.
Schedule node configuration:
{
"name": "Daily Follow-up Check",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 24
}
]
},
"triggerTimes": {
"item": [
{
"hour": 9,
"minute": 0
}
]
}
}
}
Follow-up logic:
// Function node to determine follow-up stage
const lastContactDate = new Date($json['Last Contact Date']);
const daysSinceContact = Math.floor((Date.now() - lastContactDate) / (1000 * 60 * 60 * 24));
const currentStatus = $json.Status;
let followUpAction = null;
if (currentStatus === 'Email Sent' && daysSinceContact >= 3) {
followUpAction = 'Follow-up 1';
} else if (currentStatus === 'Follow-up 1' && daysSinceContact >= 5) {
followUpAction = 'Follow-up 2';
} else if (currentStatus === 'Follow-up 2' && daysSinceContact >= 7) {
followUpAction = 'Follow-up 3';
}
if (followUpAction) {
return {
json: {
...($json),
nextAction: followUpAction,
sendFollowUp: true
}
};
}
return { json: { sendFollowUp: false } };
Follow-up email templates:
const followUpTemplates = {
'Follow-up 1': `Hi ${firstName},
Following up on my email from ${daysSinceContact} days ago about ${company}'s ${research.product}.
I know inboxes get busy. If this isn't a priority right now, just let me know and I'll check back in a few months.
Still interested in that 15-minute chat?
Best,
[YOUR NAME]`,
'Follow-up 2': `${firstName},
Last one from me - I promise!
I've attached a quick case study showing how [SIMILAR COMPANY] solved [PAIN POINT] in just 6 weeks.
Worth 15 minutes to see if this applies to ${company}?
[YOUR NAME]`,
'Follow-up 3': `Hi ${firstName},
I'll take your silence as a "not right now" and close my loop.
If anything changes, here's my calendar link: [LINK]
Best of luck with ${company}'s growth!
[YOUR NAME]`
};
Why this approach:
The 3-5-7 day cadence balances persistence with respect. Each follow-up adds new value (case study, different angle) rather than repeating the same ask. The final "breakup" email often triggers responses from prospects who were interested but busy. Automated follow-ups recover 40-60% of responses that would otherwise be lost.
Workflow Architecture Overview
This workflow consists of 24 nodes organized into 5 main sections:
- Data ingestion (Nodes 1-4): Reads prospect list from Google Sheets, filters for "New" status, validates email format, and prepares data structure
- Research phase (Nodes 5-10): Scrapes company websites, calls OpenAI for prospect research, parses JSON responses, handles API errors, and stores research data
- Email generation (Nodes 11-16): Applies email templates, injects personalization variables, polishes copy with AI, generates subject line variants, and adds tracking pixels
- Delivery system (Nodes 17-20): Sends emails via Gmail, updates CRM records, logs activity in Google Sheets, and implements sending delays
- Follow-up automation (Nodes 21-24): Runs daily schedule checks, identifies prospects needing follow-ups, generates follow-up emails, and manages sequence progression
Execution flow:
- Trigger: Manual execution for initial send, scheduled daily for follow-ups
- Average run time: 45-60 seconds per prospect (including AI calls)
- Key dependencies: OpenAI API, Gmail API, Google Sheets API
Critical nodes:
- OpenAI Research Node: Handles prospect and company research with GPT-4
- Email Polish Node: Refines copy for natural language and tone
- Follow-up Logic Function: Determines next action based on days since last contact
- Status Update Node: Prevents duplicate sends by tracking campaign progress
The complete n8n workflow JSON template is available at the bottom of this article.
Key Configuration Details
OpenAI API Settings
Required fields:
- API Key: Your OpenAI API key from platform.openai.com
- Model:
gpt-4(not gpt-3.5-turbo for research quality) - Temperature: 0.7 for research, 0.8 for email polish
- Max Tokens: 500 for research, 300 for email generation
Common issues:
- Using gpt-3.5-turbo → Results in generic, low-quality research
- Temperature above 0.9 → Creates inconsistent, sometimes inappropriate copy
- Insufficient max tokens → Truncates research output mid-sentence
Gmail Integration
Authentication setup:
- Enable 2-factor authentication on your Google account
- Generate App Password at myaccount.google.com/apppasswords
- Use App Password (not regular password) in n8n credentials
- Set sending limit to 50 emails/day maximum
Deliverability configuration:
- Warm up new sending accounts: Start with 10 emails/day, increase by 10 every 3 days
- SPF record: Add
v=spf1 include:_spf.google.com ~allto DNS - DMARC policy: Set to
p=noneinitially, monitor for issues - Custom tracking domain: Use subdomain like
track.yourdomain.comfor pixel tracking
Variables to customize:
followUpDelay: Change from 3-5-7 to 2-4-6 for faster cadence or 4-7-10 for slowermaxFollowUps: Adjust from 3 to 2 (less aggressive) or 5 (more persistent)emailTemplate: Modify base template to match your value proposition and toneresearchPrompt: Add industry-specific research questions for better personalization
Testing & Validation
Test the research phase:
- Add a single test prospect to your Google Sheets with complete data
- Run the workflow manually and examine the OpenAI research output
- Verify JSON parsing works correctly—check for malformed responses
- Review research quality: Does it identify real pain points and recent news?
Validate email generation:
- Send test emails to your own address with different prospect profiles
- Check personalization variables populate correctly (no
undefinedornull) - Review AI-polished copy for tone and length (should be <150 words)
- Test on mobile devices—80% of prospects read emails on phones
Monitor deliverability:
- Check spam folder placement using mail-tester.com (aim for 8/10+ score)
- Track open rates—healthy cold email campaigns achieve 40-60% opens
- Monitor bounce rates—above 5% indicates list quality issues
- Watch for spam complaints—above 0.1% requires immediate investigation
Common troubleshooting:
| Issue | Cause | Solution |
|---|---|---|
| Emails not sending | Gmail API rate limit hit | Add Wait node with 3-5 min delay between sends |
| Generic research output | GPT-3.5 instead of GPT-4 | Switch to gpt-4 model in OpenAI node |
| Follow-ups not triggering | Schedule node timezone mismatch | Set timezone to your local time in Schedule node |
| Duplicate emails sent | Status not updating | Add error handling to Status Update node |
Deployment Considerations
Production Deployment Checklist
| Area | Requirement | Why It Matters |
|---|---|---|
| Error Handling | Retry logic with exponential backoff on API failures | Prevents data loss when OpenAI or Gmail APIs timeout |
| Rate Limiting | 50 emails/day per Gmail account, 2-5 min delays | Maintains sender reputation and avoids spam flags |
| Monitoring | Daily email report of sent/failed/responded counts | Detects issues within 24 hours vs discovering after campaign ends |
| Backup | Weekly export of prospect data and email logs | Enables recovery if Google Sheets is accidentally deleted |
| Compliance | Unsubscribe link in footer, honor opt-outs within 24 hours | Meets CAN-SPAM requirements, avoids legal issues |
| Documentation | Node-by-node comments explaining logic | Reduces troubleshooting time from hours to minutes |
Scaling considerations:
- Multiple sending accounts: Rotate between 3-5 Gmail accounts for 150-250 emails/day capacity
- Dedicated IP: Switch to SendGrid with dedicated IP at 500+ emails/day for better deliverability control
- Research caching: Store company research for 30 days to avoid duplicate OpenAI calls for repeat prospects
- Batch processing: Process prospects in groups of 25 to prevent workflow timeouts on large lists
Real-World Use Cases
Use Case 1: SaaS Sales Team
- Industry: B2B SaaS selling to marketing teams
- Scale: 200 prospects/week, 3-person sales team
- Modifications needed: Add LinkedIn Sales Navigator integration for prospect enrichment, customize research prompt for marketing pain points, integrate with HubSpot for deal tracking
- Results: 18% response rate (vs 4% with generic emails), 60% time savings on outreach
Use Case 2: Agency New Business
- Industry: Digital marketing agency targeting e-commerce brands
- Scale: 500 prospects/month, 1 BD person
- Modifications needed: Research focuses on website performance and ad spend, email templates emphasize ROI case studies, follow-up sequence includes free audit offer
- Results: 12% response rate, 8 qualified calls/week, $40K in new business first quarter
Use Case 3: Recruiting Outreach
- Industry: Technical recruiting for software engineers
- Scale: 1,000 candidates/month, 2 recruiters
- Modifications needed: Research pulls GitHub activity and tech stack, emails emphasize company culture and growth, shorter follow-up cadence (2-3-5 days)
- Results: 25% response rate, 15% conversion to phone screen, 40% reduction in time-to-hire
Customizations & Extensions
Alternative Integrations
Instead of Gmail:
- SendGrid: Best for high-volume sending (500+ emails/day)—requires 8 node changes to swap Gmail nodes for HTTP Request nodes with SendGrid API
- Mailgun: Better deliverability analytics and webhook support—swap Gmail nodes, add webhook listener for opens/clicks
- Amazon SES: Lowest cost at scale ($0.10 per 1,000 emails)—requires AWS credential setup, similar HTTP Request node configuration
Instead of Google Sheets:
- Airtable: Better for team collaboration with rich field types—change Google Sheets nodes to Airtable nodes, add view filtering for campaign segments
- PostgreSQL: Best for 10,000+ prospects with complex querying—requires database setup, SQL query nodes replace spreadsheet reads
- HubSpot Lists: Direct CRM integration eliminates sync step—use HubSpot nodes for both read and write operations
Workflow Extensions
Add LinkedIn automation:
- Connect to Phantombuster or Apify for LinkedIn profile scraping
- Extract recent posts and engagement data
- Reference LinkedIn activity in email personalization
- Nodes needed: +4 (HTTP Request for Phantombuster, Function for data parsing, Set for variable storage)
Implement A/B testing:
- Create subject line variants (3-5 options)
- Randomly assign prospects to test groups
- Track open rates by variant
- Auto-select winning subject line after 50 sends
- Nodes needed: +6 (Function for random assignment, Split in Batches, Merge for results, IF for winner selection)
Add response classification:
- Set up Gmail webhook to catch replies
- Use OpenAI to classify response sentiment (Positive/Neutral/Negative/Out-of-office)
- Auto-create tasks in CRM for positive responses
- Pause follow-up sequences for any reply
- Nodes needed: +8 (Webhook trigger, OpenAI classification, Switch for routing, CRM task creation)
Scale with multi-channel outreach:
- Add LinkedIn connection requests after email 1
- Send LinkedIn message after email 2 if no response
- Include SMS for high-value prospects after email 3
- Coordinate timing across channels
- Performance improvement: 35-50% higher response rates with multi-channel
- Nodes needed: +12 (Phantombuster for LinkedIn, Twilio for SMS, complex timing logic)
Integration possibilities:
| Add This | To Get This | Complexity |
|---|---|---|
| Clearbit Enrichment | Company size, tech stack, funding data | Easy (3 nodes) |
| Calendly Integration | One-click meeting booking in emails | Easy (2 nodes) |
| Slack Notifications | Real-time alerts for responses | Easy (2 nodes) |
| Zapier Webhook | Connect to 3,000+ apps | Medium (4 nodes) |
| Custom AI Training | Fine-tuned model on your best emails | Advanced (requires OpenAI fine-tuning) |
Get Started Today
Ready to automate your cold email outreach?
- Download the template: Scroll to the bottom of this article to copy the complete n8n workflow JSON
- Import to n8n: Go to Workflows → Import from File, paste the JSON
- Configure your services: Add API credentials for OpenAI, Gmail, and Google Sheets
- Test with 5 prospects: Verify research quality and email generation before scaling
- Deploy to production: Set your daily schedule and activate the workflow
This agent transforms cold outreach from a time-consuming manual process into a scalable, personalized system. The AI research ensures every email feels custom-written while the automated follow-ups recover responses you'd otherwise miss.
Need help customizing this workflow for your specific outreach strategy? Schedule an intro call with Atherial at https://atherial.ai/contact.
