Projects / Demo

n8n Lead Capture to CRM

n8n demo · All data is synthetic

I built this as a small demo of something most small sales teams need: getting website form leads out of an inbox and into a CRM, with the good ones flagged right away. I work as a fintech/payments PM and spent years before that as a software engineer at i2c, so I tend to treat a lead form like any other incoming event: validate it, enrich it, store it without duplicates, and only alert on the cases that need a person. A web form posts each lead to an n8n webhook. A Code node cleans and validates it and rejects bad emails. A second Code node scores it from 0 to 100 using rules I can explain line by line: company size, budget, timeline, seniority, business or free email, and intent words in the message. That gives hot, warm, or cold, with a short reason. The lead is then added to the CRM sheet, or updated if the email is already there. Hot leads go to Slack as a proper incoming-webhook message, and the form gets its score back. There were no Google Sheets, Slack, or LLM credentials on the build machine, so the CRM is a local CSV, Slack is a local mock receiver, and the scoring is rule-based. Disabled nodes on the canvas show where each real service plugs in. All of the leads are synthetic and this is a demo, not a production system, and a check script confirms the tiers, the dedupe, the rejected email, and that only hot leads triggered an alert.

The problem

Leads from a website form often sit in an inbox until someone copies them into a CRM. The same person submits twice and ends up as two records, and the leads worth a quick reply wait in the same queue as everyone else.

How it works

Webhook → Validate (Code) → Score 0–100 (Code) → CRM upsert by email → Slack alert (hot only) → Respond with score
Webhook

The web form posts each lead to an n8n webhook.

Validate

A Code node cleans the fields and rejects leads with a bad email.

Score

A second Code node scores the lead from 0 to 100 using rules: company size, budget, timeline, seniority, business or free email, and intent words in the message. The score maps to hot, warm or cold, with a short reason.

CRM upsert

The lead is added to the CRM, or updated if the email is already there, so there are no duplicates.

Slack alert

Only hot leads go to Slack, as an incoming-webhook message.

Response

The form gets the score, tier and reason back.

Demo

Screenshots

n8n workflow canvas for lead capture
The n8n workflow canvas
CRM output with scored leads
The CRM output with scores and reasons
Slack alert for a hot lead on the mock receiver
A hot-lead alert on the mock Slack receiver

Stack

n8n 2.8.4 (self-hosted via npm, SQLite) with a webhook trigger and Code nodes for validation, scoring, the CRM upsert and the Slack message. Python 3 for the synthetic lead generator, the sender, the mock Slack receiver and the checks.

What's real and what's a stand-in

This is a demo on synthetic data. The CRM is a local CSV standing in for Google Sheets, Slack is a local mock receiver, and the scoring is rule-based where an LLM could go. Disabled nodes on the canvas mark where each real service plugs in.

No real leads, customers, Slack workspace or paid API key are used.