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 scoreWebhookThe web form posts each lead to an n8n webhook.
ValidateA Code node cleans the fields and rejects leads with a bad email.
ScoreA 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 upsertThe lead is added to the CRM, or updated if the email is already there, so there are no duplicates.
Slack alertOnly hot leads go to Slack, as an incoming-webhook message.
ResponseThe form gets the score, tier and reason back.
Demo
Screenshots



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.