Work / Lead & Sales / 01 · Home services & construction
Lead-to-Cash CRM for Three Contractors
Home services · New York · three companies, one owner · 2026
Delivered — figures counted directly from the exported workflow JSON
The shape of it
8 LEAD SOURCES
- Hosted form
- Website form
- Chat widget
- Tracked calls · CallRail
- Calendar bookings
- Facebook Lead Ads
- Social comments · 3 networks
- 8th source, counted — not named in the write-up
ONE HUB
- normalise
- check for a recent duplicate
- mint a reference number
- grade Hot / Warm / Cold
- write the sheet
- email the customer
- text — only with explicit consent
- alert the sales team
STAGE DRIVES EVERYTHING
- webhook for human edits
- direct call for n8n’s own changes
6 AUTOMATION FAMILIES
- Estimate chaseDay 3 / 5 / 7 / 14 / 21 / 30
- Site-visit remindersanchored to the appointment
- Review & referral requestson completion, no gating
- Long-term nurturequiet leads, consent re-checked
- Offline conversionswon jobs → Google Ads · Meta
- Staff dashboardone per company, served from n8n
Drawn from the delivered README and the exported JSON. Endpoint paths, access details and credentials are deliberately absent — they belong in the client’s handover, not on a public page.
Stage Change Router, as exported
Every node with its icon, as on the n8n canvasstarts a runHover a node for its type
-
Stage Change Router
17 nodes · 16 connections · 2 notes · live
two triggers, one bus: webhook for human edits, direct call for n8n’s own changes
482 executing nodes, by type
The gates, 34 If nodes, almost all of them consent and idempotency checks, decide whether anything happens next: a countable part of the system, not a claim about it. 552 objects on the canvas = 482 executing nodes + 70 sticky notes.
Staff dashboard, served straight from n8n
One dashboard per company, so nobody has to open the spreadsheet. Grades are Hot / Warm / Cold; the rules-based score stays in charge and the model writes its own column beside it.
The guards, and what each one prevents
HoverTap a card to read what it prevents.
- Idempotency is written before the action
Last Routed Stage is stamped before downstream actions fire: at-most-once, on purpose. A duplicate review email is worse than a missed automation.
- Race-safe lead IDs
Append first, let the sheet decide the row, then derive the reference from it. Never count the rows and add one — eight sources can land in the same second.
- Consent is an allowlist
The string “no” is truthy in JavaScript. A truthiness check would have opted in every customer who explicitly opted out.
- A texted STOP stops the emails too
Carrier-level blocking does nothing to an email sequence, so the opt-out is written back into the CRM.
- The AI drafts and never sends
A model that invents a price or a warranty in an email from the company is contractual exposure, not a UX bug.
- Money is chased only when it is owed
Reminders fire on explicit invoice statuses. A blank was never invoiced, and a blank is never chased.
Built with
- n8n · in 14 systems
- Google Sheets · in 6 systems
- Gmail · in 5 systems
- Google Ads · in 4 systems
- Meta · in 2 systems
- TwilioTwilio · in 3 systems
- CallRailCallRail · in 1 system