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

42automations live
73workflows
552nodes
3companies
8lead sources

Stage Change Router, as exported

17 nodes · 16 connections · from the exported JSON

The shape of it

Eight lead sources into one hub; the stage change router fans out to six automation familiesHosted formWebsite formChat widgetTracked calls · CallRailCalendar bookingsFacebook Lead AdsSocial comments · 3 networks8th intake, countednot named in the write-up8 LEAD SOURCESUpdate Leads Sheetsthe only writer to the Leads tabnormalisecheck for a recent duplicatemint a reference numbergrade Hot / Warm / Coldwrite the sheetemail the customertext — only with explicit consentalert the sales teamONE HUBStage Change Routertwo triggers, one buswebhook for human editsdirect call for n8n’s own changesSTAGE DRIVES EVERYTHINGEstimate chaseDay 3 / 5 / 7 / 14 / 21 / 30Site-visit remindersanchored to the appointmentReview & referral requestson completion, no gatingLong-term nurturequiet leads, consent re-checkedOffline conversionswon jobs → Google Ads · MetaStaff dashboardone per company, served from n8n6 AUTOMATION FAMILIES

8 LEAD SOURCES

  • Hosted form
  • Website form
  • Chat widget
  • Tracked calls · CallRail
  • Calendar bookings
  • Facebook Lead Ads
  • Social comments · 3 networks
  • 8th intake, counted — not named in the write-up

ONE HUB

Update Leads Sheetsthe only writer to the Leads tab
  1. normalise
  2. check for a recent duplicate
  3. mint a reference number
  4. grade Hot / Warm / Cold
  5. write the sheet
  6. email the customer
  7. text — only with explicit consent
  8. alert the sales team

STAGE DRIVES EVERYTHING

Stage Change Routertwo triggers, one bus
  • 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.

482 executing nodes, by type

googleSheets 106code 95gmail 47executeWorkflow 40if 34webhook 29scheduleTrigger 16twilio 7errorTrigger 3other 105

34 if nodes, almost all of them consent and idempotency gates — the guards are 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

[COMPANY] · Leads · served by webhooklive
REFSOURCEGRADESTAGELAST TOUCHNEXT DUEOWNER
Client data redacted

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

  • 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