How I Stopped Missing Leads by Building a $0 CRM Automation in n8n
automation

How I Stopped Missing Leads by Building a $0 CRM Automation in n8n

A $4,000 project slipped through my fingers because I missed a contact form email. Here's the n8n automation I built to make sure that never happens again — and it cost nothing to run.

2026-04-05
9 min read
How I Stopped Missing Leads by Building a $0 CRM Automation in n8n

How I Stopped Missing Leads by Building a $0 CRM Automation in n8n#

In February I got an email from someone who had filled out my contact form six weeks earlier. They'd moved on and hired someone else. They were writing to let me know, not to give me another chance.

The project was a website redesign — they'd mentioned a €4,000 budget in the form. I'd never seen the original submission.

It wasn't that the form broke. The submission came in, it generated an email, and that email got buried in my inbox during a particularly busy week. By the time I came up for air, it had scrolled out of view. I never saw it. They assumed I wasn't interested.

That was expensive silence.

I spent the following weekend building a system that makes it impossible for me to miss a lead. It's been running for two months now. I've responded to every single inquiry within a few hours.


The Real Problem Wasn't Missing the Email#

My first instinct was "I should check my email more often." But that wasn't the real problem.

The real problem was that my "system" for managing leads was my inbox. Incoming leads lived alongside newsletters, client emails, invoices, Slack notifications, and GitHub alerts. There was no differentiation. Important signals were drowning in noise.

What I needed wasn't more email checking — it was a dedicated pipeline where leads went the moment they came in, with explicit stages and follow-up reminders.

I also needed a log. If a lead comes in and nothing happens for 3 days, something should remind me.

The system I built has four components:

  1. Capture: Automatically pull leads from every source into one place
  2. Enrich: Automatically gather information about the lead
  3. Alert: Notify me immediately, through a channel I actually watch
  4. Follow-up: Remind me if I haven't responded within 48 hours

Component 1: The Capture Layer#

My leads come from three places:

  • A contact form on my website (Tally.so)
  • Direct emails to my work address
  • Occasional LinkedIn messages

I built a separate n8n trigger for each source.

Tally.so Contact Form#

Tally has excellent webhook support. In Tally, go to your form settings → Integrations → Webhooks → add your n8n webhook URL.

The webhook fires instantly when someone submits the form. My n8n workflow receives all the field values: name, email, company, project description, budget range, timeline.

Gmail Trigger for Direct Emails#

Not everyone uses a form. Some people just email me directly. I set up an n8n Gmail trigger that watches for emails with specific characteristics:

Gmail Trigger:
  Label: "New Lead" (I manually apply this label)

Wait — that still requires manual action. I didn't want that.

The better solution: an n8n workflow that scans my inbox every 30 minutes and identifies potential leads based on content:

Schedule Trigger (every 30 min):
→ Gmail node (search unread emails from last hour)
→ AI Node (Ollama):
  Prompt: "Is this email from someone inquiring about hiring me for work?
           Reply with JSON: {isLead: true/false, reason: '...'}"
→ IF node: isLead = true
→ Continue to CRM creation

The AI classification isn't perfect — it catches maybe 85% of leads correctly. But combined with my Tally form, it covers most cases.

LinkedIn DMs#

LinkedIn's API is restrictive, so I don't have a fully automated solution here. My workaround: a simple n8n Form accessible from my phone. When I get a LinkedIn DM that looks like a lead, I tap the form link, fill in the basics (name, company, what they want), and it feeds into the same pipeline as everything else. Takes 30 seconds.

Not ideal, but better than losing them in LinkedIn's notification mess.


Component 2: Enrichment#

For every captured lead, I automatically gather additional context before creating the CRM record.

Email enrichment with Hunter.io / Apollo.io:

// HTTP Request to Apollo.io enrichment API
const apolloResponse = await httpRequest({
  method: 'GET',
  url: `https://api.apollo.io/v1/people/match?email=${lead.email}`,
  headers: { 'X-Api-Key': credentials.apolloApiKey }
});

// Extract useful fields
const enriched = {
  ...lead,
  jobTitle: apolloResponse.person?.title,
  companyName: apolloResponse.person?.organization?.name,
  companySize: apolloResponse.person?.organization?.estimated_num_employees,
  linkedinUrl: apolloResponse.person?.linkedin_url,
  companyIndustry: apolloResponse.person?.organization?.industry
};

Apollo.io has a free tier that gives you 50 enrichments per month — enough for a freelancer's lead volume.

Lead scoring:

After enrichment, a Code node calculates a lead score from 0-100:

let score = 0;
const lead = $json;

// Budget signals from the form
if (lead.budget === '5000+') score += 35;
else if (lead.budget === '2000-5000') score += 20;
else if (lead.budget === '1000-2000') score += 10;

// Project type
if (lead.projectType === 'ongoing') score += 25;
else if (lead.projectType === 'new-website') score += 15;
else if (lead.projectType === 'redesign') score += 15;

// Company size (from enrichment)
const employees = lead.companySize || 0;
if (employees > 50) score += 20;
else if (employees > 10) score += 12;
else if (employees > 1) score += 5;

// Timeline urgency
if (lead.timeline === 'immediately') score += 15;
else if (lead.timeline === '1-month') score += 8;

// Penalize incomplete submissions
if (!lead.email) score -= 20;
if (!lead.message || lead.message.length < 50) score -= 10;

return [{ json: { ...lead, score, priority: score >= 60 ? 'hot' : score >= 30 ? 'warm' : 'cold' } }];

Component 3: The CRM (Notion Database)#

Every lead creates a page in a Notion database with this structure:

Properties:

  • Name (title)
  • Email
  • Company
  • Lead Source (form/email/linkedin)
  • Score (number)
  • Priority (hot/warm/cold — select)
  • Status (New → Contacted → In Discussion → Proposal Sent → Won → Lost)
  • Budget Range
  • Project Type
  • Timeline
  • LinkedIn URL
  • Company Size
  • Industry
  • Date Received
  • Last Contacted
  • Notes

Body of the page: Their original message, plus the AI-generated summary.

The Notion node to create this:

Notion node:
  Resource: Database Item
  Operation: Create
  Database ID: [leads database]
  Properties:
    Name: {{ $json.name }}
    Email: {{ $json.email }}
    Score: {{ $json.score }}
    Priority: {{ $json.priority }}
    Status: New
    [... all other fields]
  Content:
    ## Original Message
    {{ $json.message }}
    
    ## AI Summary
    {{ $json.aiSummary }}

Component 4: The Alert System#

This is the part that changed everything. I used to rely on email notifications for leads. Email is where leads go to die, as I learned the hard way.

Now, every new lead immediately triggers:

Slack notification (I watch Slack closely):

🔥 New Lead — {{ $json.priority }} priority (score: {{ $json.score }}/100)

👤 {{ $json.name }} — {{ $json.companyName || 'Unknown company' }}
💼 {{ $json.projectType }} | Budget: {{ $json.budget }}
⏰ Timeline: {{ $json.timeline }}
🔗 {{ notionPageUrl }}

"{{ $json.message | truncate(200) }}"

Hot leads get a ping in a different Slack channel where I have push notifications enabled. Warm and cold leads go to a quieter channel I check twice a day.

The follow-up reminder workflow:

This is what would have saved me from the €4,000 miss. A separate n8n workflow runs every morning:

Schedule Trigger (9 AM daily):
→ Notion node: fetch leads where Status = "New" AND Date Received < (today - 2 days)
→ IF node: any results?
→ Yes: Slack alert "⚠️ You have {{ count }} leads older than 48h with no response"
       List each one with name, company, score, and Notion link

If I haven't touched a lead in 48 hours, I get reminded. Every morning until I either respond or update the status.


What Actually Happened in the First Two Months#

In the first two months after building this:

  • 14 leads captured (across form, email, and LinkedIn)
  • Response time: 100% within 24 hours (down from "sometimes never")
  • 3 converted to projects
  • 2 are in active discussion

I can't prove the automation directly caused the conversions — I would have responded to some of these manually. But I know I didn't miss any. That's a different kind of certainty than I had before.


The One Thing I Changed After Building It#

My initial Slack notification was too verbose. I was showing the full lead score breakdown, all the enriched company data, and the complete message. It was overwhelming at a glance.

I simplified it to the essential "should I respond now or later?" information:

  • Name and company
  • Priority level (one word)
  • What they want (two sentences max)
  • Direct link to Notion page

Less information, faster decision. Now I can scan a lead notification in 5 seconds and decide whether to respond immediately, add it to my afternoon task list, or mark it as not a fit.


The Cost#

Running this system costs me nothing I wasn't already spending:

  • n8n: already running on my VPS
  • Notion: free plan (plenty of capacity for leads)
  • Apollo.io: free tier (50 enrichments/month)
  • Ollama: local model, no API cost
  • Tally.so: free plan

Total additional monthly cost: €0.

The time to build it: about 5 hours across a weekend.

The cost of not building it: at least €4,000 that I know of.


Frequently Asked Questions#

Do I need a paid CRM to manage leads as a freelancer?#

No. A Notion database combined with n8n automation covers everything a paid CRM provides for lead management. Paid CRMs add sales team features (pipelines, dashboards) that most freelancers don't need.

How do I automatically enrich lead data in n8n?#

Use the HTTP Request node to call an enrichment API like Apollo.io or Clearbit with the lead's email. These return company size, industry, LinkedIn profile, and more. Apollo.io has a generous free tier and good data quality.

What is the best contact form tool to use with n8n?#

Tally.so is most popular with n8n users — free, clean webhook payloads, no submission limits on the free plan. Typeform works but has submission limits on the free tier. Any form tool that supports webhooks works with n8n.

How do I prevent duplicate leads in my Notion CRM?#

Before creating a new entry, query your database to check if a record with the same email already exists. Use the Notion node with "Get Many" and an email filter. If found, use an IF node to route to "update existing" instead of "create new."

Frequently Asked Questions

|

Have more questions? Contact us