Back to Alchemy
Alchemy RecipeIntermediateautomation

Sales email outreach sequence from LinkedIn profiles with personalisation

Most sales teams know the drill: find a prospect on LinkedIn, spend 15 minutes researching them, craft a personalised email that references their recent post or job change, send it, then repeat this manually 50 times. By week's end, your sales rep has burned through hours on research and writing whilst actually sending fewer emails than they could have. The result is lower reply rates because the outreach feels generic, or exhausted salespeople who give up on personalisation altogether. What if you could pull prospect data from LinkedIn, generate genuinely personalised emails based on real information about each person, and send them automatically, all without touching a keyboard after the initial setup? This workflow does exactly that. You connect your prospect list to a personalisation engine, feed it into an LLM for custom email generation, and pipe everything into your email platform. The whole sequence runs on a schedule or triggered by a single action. No copy-pasting, no manual sending, no context switching. The difference between a "send the same email to everyone" campaign and this approach is measurable. When your email mentions the prospect's recent career move or a specific project they shared about, reply rates typically climb 20-40%. Automating that personalisation at scale means you get those rates without the time tax.

The Automated Workflow

We'll build this using n8n as the orchestration backbone, since it integrates cleanly with LinkedIn data sources, AI generation tools, and email platforms without needing extensive custom code. If you prefer Zapier or Make, the steps translate directly; I'll call out the differences where they matter. Here's the data flow: 1. Trigger: prospect list (CSV upload, webhook, or database query) 2. Enrich: fetch additional prospect data (optional, via API) 3. Generate: pass prospect details to an LLM for email composition 4. Format: structure the output for email sending 5. Send: deliver via your email platform with tracking

Setting up the trigger

Start with a simple CSV file of prospects. Each row needs at minimum: first name, last name, email, and LinkedIn profile URL.

first_name,last_name,email,company,linkedin_url,recent_activity
Alice,Chen,alice@techcorp.io,TechCorp,linkedin.com/in/alice-chen,Promoted to Senior Engineer
Bob,Martinez,bob@financeplus.com,FinancePlus,linkedin.com/in/bob-martinez,Shared article on AI in banking

In n8n, create a "Read Binary File" node (or use a webhook if you're feeding data from a CRM). Point it to your CSV and set it to trigger on upload or on a schedule.

Node type: Read Binary File
File path: /uploads/prospects.csv
Split into items: true

Enrichment layer (optional but recommended)

If you want to pull additional context about each prospect, use a tool like Hunter or Apollo API to fetch job titles, company details, or recent news. This makes the LLM's output richer. For this example, we'll assume your CSV already contains the key details. If you want to add a scrape step, use an HTTP request node to call an enrichment API:

GET https://api.hunter.io/v2/email-finder?domain={company_domain}&first_name={first_name}&last_name={last_name}
Headers: Authorization: Bearer YOUR_HUNTER_API_KEY

Parse the response and merge it back into your prospect object.

Generate personalised emails with an LLM

This is the core of the automation. You'll feed each prospect's details into Claude Opus 4.6 or GPT-4o, along with instructions for tone and content. Create an "OpenAI" node (or "Anthropic" if using Claude) in n8n:

Model: gpt-4o
Temperature: 0.7
Max tokens: 300 System prompt:
You are an expert sales development representative. Write a short, personalised cold email (3-4 sentences) based on the prospect details below. Be specific, mention something relevant about their company or recent activity, and include a clear call to action. Use a friendly but professional tone. Do not include a subject line. User prompt:
Prospect name: {first_name} {last_name}
Company: {company}
Recent activity or role: {recent_activity}
Your value: [Insert your product's value prop here] Write an email to this prospect now.

Set up the node to loop through each prospect in your list:

Node type: OpenAI Chat Model
Input: {{$node["Read CSV"].json.company}}, {{$node["Read CSV"].json.recent_activity}}
Prompt template variable: {company}, {recent_activity}

The LLM will output something like:

Hi Alice, I noticed you recently moved into a Senior Engineer role at TechCorp. We work with engineering teams to reduce deployment time by 40% on average. Given your new position, I'd love to chat about how we could help you and your team ship faster. Best,
[Your name]

Generate subject lines

Don't forget the subject line. Add a second LLM call specifically for that:

Model: gpt-4o
Max tokens: 10 System prompt:
Write a single compelling email subject line based on the prospect details. Make it specific and curiosity-driven, but not clickbait. No quotes, just the subject. User prompt:
Prospect: {first_name} {last_name} at {company}
Recent activity: {recent_activity}

This prevents generic subject lines and keeps open rates high.

Format and prepare for sending

Add a "Set" node to structure the output data:

email: {prospect_email}
first_name: {prospect_first_name}
subject: {generated_subject_line}
body: {generated_email_body}
sent_timestamp: {{now}}

Send the emails

Connect to Emailit (or your preferred transactional email service) via API. Emailit accepts REST calls:

POST https://api.emailit.io/v1/send
Headers: Authorization: Bearer YOUR_EMAILIT_API_KEY Content-Type: application/json Body:
{ "to": "{{$node['Format Output'].json.email}}", "from": "your-email@yourcompany.com", "subject": "{{$node['Format Output'].json.subject}}", "html": "<p>{{$node['Format Output'].json.body}}</p>", "campaign": "sales-outreach-feb-2026", "track_opens": true, "track_clicks": true
}

Alternatively, use Make or Zapier's native email integrations if you prefer not to handle API keys directly.

Error handling and throttling

Add error handling so one bad email address doesn't halt the entire workflow:

Node type: Try / Catch
Try: Send email via Emailit
Catch: Log error to a backup sheet or Slack channel - Error message: {{$error.message}} - Prospect email: {{$node['Format Output'].json.email}} - Timestamp: {{now}}

Rate-limit your sends. Most email services allow 100-500 per minute; most LLM APIs allow 10-20 requests per second. Add a "Wait" node between batches:

Node type: Wait
Wait: 2 seconds (between each email send)

For a batch of 500 prospects, this adds 16 minutes to execution time but prevents API overages.

Save results to a tracking sheet

After sending, log each email to a Google Sheet or Airtable so you can track opens and replies:

Node type: Google Sheets
Action: Append row
Sheet: Sales Outreach Tracking
Columns: - prospect_name - prospect_email - subject_line - sent_at - campaign_id

This lets you correlate reply rates with LLM-generated copy and iterate on your system prompt over time.

The Manual Alternative

If you want more control over each email before sending, use ColdConvert AI or HyperWrite directly. Both have web interfaces where you paste a prospect's LinkedIn URL and click "Generate Email." You then review, edit, and send manually. This approach suits smaller lists (under 20 prospects per week) or situations where your brand voice needs careful oversight. It's slower but gives you full quality control before anything lands in someone's inbox.

Pro Tips

Keep your system prompt short and specific.

The LLM works best with clear instructions.

Instead of "write a personalised email," say "mention their job title change in the first sentence, include one piece of their recent company news, and end with a specific question about their team size."

Test with a small batch first.

Run the workflow on 10 prospects, review the outputs, and adjust your prompt before scaling to 500. LLM outputs are consistent but not perfect; a tiny tweak to the system prompt often dramatically improves quality.

Monitor your email reputation.

Sending 500 emails from a brand-new domain will trigger spam filters. Use a warm-up service like Lemwarm or GMass to build sender credibility over 2-4 weeks before running large campaigns. Alternatively, spread sends across multiple days.

Set reasonable rate limits to avoid LLM throttling.

If your plan allows 1 million tokens per month, a workflow generating 5-10 tokens per email on 1,000 prospects uses roughly 50,000 tokens. You have room, but check your quota. Batch jobs run cheaper than real-time requests.

Track reply rates by subject line variation.

Modify your system prompt to generate 2-3 subject line options per prospect, then randomly assign them. After 2 weeks, query your email platform's open rates and identify which styles perform best. Feed those insights back into your next batch.

Cost Breakdown

ToolPlan NeededMonthly CostNotes
n8nCloud Professional£401,000 workflow executions/month; each batch of 100 emails = 1 execution
GPT-4o (OpenAI)Pay-as-you-go~£5–15~$0.003 per 1K input tokens, $0.006 per 1K output tokens; 1,000 emails ≈ £10
Claude Opus 4.6 (Anthropic)Pay-as-you-go~£8–20Slightly more expensive per token but often produces longer, higher-quality outputs
EmailitStarter£2010,000 emails/month; includes SMTP and basic tracking
Google Sheets (logging)Free£0Built-in if you use Google Workspace
Optional: Lemwarm (warm-up)Basic£49Necessary only if you're a new sender; speeds up deliverability