Three entry doors, four steps in the engine, two destinations — and the retry that leaves no lead behind. The complete attribution mechanics.
ctwa_clid · leadgen_id · utm_* → Graph API → CRM + database · retry every 5 min · revenue per ad
PostepTrack stamps every lead, the moment it lands in the CRM, with the exact origin of the click: campaign, ad set and ad — name and ID. Not “came from Meta”. It's “came from ad X, ad set Y, campaign Z”.
We've already covered why each client gets their own instance and which pitfalls this pipeline hides. This post is the missing piece: the mechanics. What happens, in the order it happens, from click to stamped lead.
Every lead arrives through one of three paths, and each one drops a different identifier. The rest of the system exists to turn that identifier into attribution.
the customer clicks the ad and lands straight in WhatsApp. The first message carries the click identifier, delivered by the WhatsApp Business webhook
the customer fills the form without leaving Instagram/Facebook. The leadgen webhook delivers the generated lead's ID
the click reaches the site with tracking parameters in the URL, which travel along when the lead is submitted
→ Three different formats, one destination: the webhook hits the client's Edge Function in real time.
Each client has a dedicated Edge Function running on Supabase (Deno). It answers Meta in milliseconds and processes in the background. The real work is four steps:
Step b is the heart: it's Meta's Graph API that answers which ad that click came from. PostepTrack just asks the right question, with the right token, at the right time — and stores the answer where it's worth money.
The same attribution is written to two places, because it serves two different audiences:
And there's the timing race: sometimes Meta's webhook arrives BEFORE the CRM creates the lead. If step c finds nobody, the event isn't dropped — it goes to a recovery queue and an automatic retry runs every 5 minutes until it matches.
No click gets lost because the CRM took ten seconds. That queue (recovery_pending) was born from a real incident — not from paranoia.
When the client's CRM supports outbound webhooks, PostepTrack goes beyond the lead: it closes the loop all the way to revenue.
→ The question changes from “how many leads did this ad bring” to “how much revenue did this ad generate”. ROI per ad, not per channel.
Each client runs a dedicated, isolated instance — nothing shared. Four pieces:
The client's own app on Meta, with a System User token (never expires). Receives the CTWA and Lead Ads webhooks and authenticates the Graph API queries.
Serverless function (Supabase/Deno) exclusive to the client. Answers the webhook in milliseconds and does the heavy lifting in the background.
Postgres with ~30 attribution columns, protected by RLS. It's the base for dashboards and cost-per-lead analysis.
Kommo (API v4), Clint or Ploomes (OData, with outbound webhook for revenue). Custom fields created on the client's CRM lead.
campaign · ad set · ad (name + id) · event source · utm_source/medium/campaign/content · ctwa_clid / leadgen_id / fbclid · normalized phone · timestamps · deal_id (for revenue)