House of MohnyWorkflow spec · v1

The Lead Intake Workflow

Every node, the prompt that does the work, and the three places this breaks if you set it up wrong. Builds in an afternoon if you have the credentials ready.

What it does

Nobody decides what happens next


A lead arrives from any channel. It gets acknowledged, scored, and either booked or routed — before anyone opens a laptop.

The saving is not the typing. The saving is that no human has to decide what happens next, because the decision already lives in the workflow.

The nodes

Nine, in order


What goes in an automated lead intake workflow? Nine nodes, in this order.

1 · Trigger — webhook. One endpoint, every channel posts to it
2 · Normalise — map every payload shape to one: name, contact, message, source
3 · Dedupe — look up the contact. Existing lead → update, don't create
4 · Acknowledge — reply on the channel it came in on. Fires before anything slow
5 · Score — the model reads the message and returns structured JSON
6 · Branch — hot goes to booking, cold goes to nurture, junk stops here
7 · Offer slots — read real calendar availability, send two options
8 · Write CRM — record with source tag and score. Always, every branch
9 · Notify — one message to you, only for hot leads

Node 4 goes before node 5 deliberately. The acknowledgement must not wait on a model call. If scoring is slow or the model is down, the lead still gets a reply.

None of this is tied to one product. The graph runs in any workflow tool that takes a webhook and branches — n8n, Make and Zapier all have every node above — or in a small script on a server you already pay for. Node 5 needs a model with a JSON or structured-output mode; the OpenAI, Anthropic and Google APIs all have one. Node 7 needs a calendar you can read free slots from and write a booking to, which Google Calendar and Cal.com both allow. Node 8 needs somewhere to put the record, and on day one a spreadsheet counts.

Node 5

The only prompt in the whole thing


Ask for structured output, not prose. Everything downstream branches on these fields, so they have to be machine-readable.

Classify this inbound enquiry. Message: {{message}} Source: {{source}} Return JSON only: { "intent": "buying" | "browsing" | "support" | "spam", "urgency": "now" | "weeks" | "someday" | "unknown", "fit": 1-5, "one_line": "<what they actually want, in your words>" } If the message is too short to judge, return "unknown" rather than guessing. A wrong confident score is worse than an honest blank.

Hot = intent buying, urgency now-or-weeks, fit 3 or above. Tune the threshold after a week of real leads, not before — your first guess will be wrong and that's fine.

Failure modes

The three places this breaks


The model returns prose instead of JSON

It will, eventually, on a weird input. If node 6 branches on an unparseable field, the whole lead vanishes silently.

FixWrap the parse in a try. On failure, default to the human branch and notify. Never let a parse error drop a lead.

The webhook fires twice

Retries, double form submits, a channel that acknowledges slowly. Without node 3 you get duplicate records and the lead gets two acknowledgements.

FixDedupe on contact plus a time window, not on payload identity. Payloads differ in ways that don't matter.

Everyone scores hot

The most common failure and the hardest to see. If your threshold is loose, every lead is hot, the notification becomes noise, and within two weeks you stop reading it.

FixScore a hundred real historical leads before you trust it. If more than a third come back hot, the threshold is wrong, not the leads.
Why give away the failure modes

Because they're where the time actually goes. The happy path is an afternoon. The three problems above are the difference between a workflow that runs for a year and one you quietly turn off in month two.

Tell me whether you're building this yourself or want it built. Straight answer either way — if it's a weekend of your time, I'll say that rather than quote you. House of Mohny builds these from Bengaluru, working worldwide.

@houseofmohny on Instagram →