22 leads at ₹10 each, and nobody home
A campaign ran for 20 hours and produced the cheapest conversations the account had ever bought. Every one was dropped — because a campaign has four parts and we launched one.
A festive-season cruise campaign went live and performed immediately: 22 WhatsApp conversations in 20 hours at about ₹10 each — the best acquisition cost the account had ever recorded.
Not one of those conversations reached the automated responder. Not one reached the team’s channel. Twenty-two people asked to buy something and were answered by silence.
Three gates, three independent failures
The leads had to pass three checkpoints in the intake pipeline, and each one failed on its own:
- The tag pattern that recognises campaign codes didn’t know the new campaign’s prefix.
- The ad-ID map that links an ad click to a campaign had none of the new ads in it.
- The classifier that routes a conversation to the right sales persona had no token for the new campaign.
Any one failing would have degraded the launch. All three failing meant the campaign was invisible — and the account had made the identical mistake on a previous launch, documented in the code comments, which I re-read only after it happened again. A written warning nobody is forced past is not a control.
A campaign is four pieces
The durable lesson is definitional. On this pipeline, “a campaign” is not the ads. It is four things that only work together: the ads, the knowledge document the responder answers from, the persona that does the selling, and the classifier that routes leads to both. The campaign is live when the last of the four is live — before that, you are paying to generate leads into a void.
And there’s an ordering constraint with teeth: the classifier’s default route pointed at an older campaign. Fixing it first would have been worse than the outage — leads would have received confident, wrong answers, quoted prices for a different product. Connect the pipe before you open the tap: land the classifier last.
The detector that costs nothing
The failure was invisible because each component looked healthy alone. What exposes it is reconciliation between two counters that should agree: the ad platform’s conversation count, and the intake queue’s own record — grep the queue for the campaign’s opening message. Platform says 22, queue says 0: leads are falling between two systems that are each, individually, fine.
Same method as reconciling a bank statement. Two ledgers, one reality, and the discrepancy is the finding.
The salvage
The 31 leads dropped before the fix were reconstructed from the raw message log — recoverable only because one layer of the pipeline records everything before any filtering happens. Filters change, and every filter is eventually wrong; keep one layer that never discards, and your worst launches stay refundable.