The business story
Why this system exists
A B2B company I ran marketing for captured leads from a website form, LinkedIn Lead Gen Forms, WhatsApp, and event lists. Before this pipeline, that meant four disconnected streams: the same prospect arriving twice became two records, sales followed up on stale duplicates, and the channel report credited most revenue to “direct” — because the form couldn't see the ad click that actually started the relationship. You cannot decide where next month's budget goes when your best channel is invisible.
What I built (the production original)
A single serverless capture endpoint behind every channel: rate-limited, honeypot-guarded, input-sanitized. Each lead got one canonical source, resolved by strict signal priority — ad-platform click IDs beat UTMs, UTMs beat referrers — then flowed to the CRM as the primary system, with a database shadow copy, an instant email alert to sales, and server-side conversion events back to the ad platforms so bidding learned from real leads instead of ad-blocked pixels. It ran in production on a live company website; the alert-to-follow-up gap is where deals actually started.
The judgment calls
- Click IDs outrank UTMs. A forwarded newsletter URL can carry stale UTMs; a gclid is stamped by the platform at click time. When they conflict, trust the machine, not the label.
- Never auto-merge on name + company. Two people at one company must stay two records. A false merge silently destroys a lead; a duplicate just costs a human five seconds. Email and phone are the only merge keys.
- Fill blanks, never overwrite. A re-submitted form with a typo must not corrupt verified CRM data. First touch is immutable — it answers “which channel created this relationship.”
- Imported lists route to a hold queue. A trade-fair CSV has no consent context; it gets a human review, not an automated sequence.
What went wrong along the way
The first version trusted UTMs completely — until a paid lead arrived through a forwarded link tagged utm_source=newsletter and the spend report under-counted the ad channel that had actually paid for the click. That failure produced the strict signal-priority ladder this demo runs. The honeypot's randomized-delay fake success came from watching bots adapt to instant rejections.
What I'd change today
Server-side identity should extend beyond email/phone with a privacy-safe fingerprint for the anonymous-visit-to-form gap, and the routing rules belong in versioned configuration a marketer can edit without a deploy — both are noted in the repo as deliberate limitations of this reconstruction.