Facebook optimises toward whatever you tell it success looks like. Tell it nothing and it will find you the cheapest possible form fills. Notes on sending the truth back.
A lead campaign with a falling cost per lead and flat sales is not a mystery. It is the algorithm doing exactly what it was asked. It was shown which people submit forms cheaply, so it went and found more of them — and people who submit forms cheaply are, on average, people who were never going to buy.
The fix is not a better audience or a better creative. It is telling Facebook which leads turned into money.
Lead Ads gives every submission a leadgen_id. That single value is
what lets a server-side event be joined back to the ad, the ad set and the
campaign that produced it — without cookies, without a pixel firing in someone's
browser, and without any identity matching at all.
It is worth appreciating how unusual that is. Most conversion tracking is probabilistic: hashed emails, click ids, attribution windows, best guesses. Lead Ads conversions are deterministic. You are handing back the same identifier Facebook gave you.
| Event | Fires when | Says |
|---|---|---|
| Lead received | The lead reaches you and passes validation. | "This one was real." Filters out the noise that never made it into a system at all. |
| Status changed | The CRM or CPA network moves the order — confirmed, delivered, cancelled. | "This one became money." The signal that actually changes who the algorithm looks for. |
Sending only the first is a common half-measure and it is close to useless: "a lead arrived" is what Facebook already knows. The second event is the one carrying information Facebook does not have, and it is the one that takes days to arrive, because that is how long a real order takes.
A status can move more than once, a dispatcher can re-scan, an order event can be written twice. Send the same conversion twice and you have quietly doubled a number the algorithm is optimising against.
Build one deterministic dedupe key per lead + event type, put a unique constraint on it, and hand that same key to Facebook as the event id. Then duplicate suppression exists in two independent places: your database refuses to record the second send, and Facebook discards it even if one slips through. Two cheap guards beat one clever one.
Not immediately. The optimisation needs enough conversion events to learn from, which means the feedback loop is bounded by your real order volume and your real fulfilment time, not by how quickly you ship the integration. The honest expectation is weeks, not days.
What changes when it works is the shape of the account rather than a single number. Cost per lead usually goes up. Cost per order goes down. If you are still judging the account on cost per lead at that point, the integration will look like it made things worse.
Which is the same lesson as everywhere else in this documentation: the metric has to be the one you would defend, not the one that looks best.
The loop only closes if the earlier links hold. Leads have to actually arrive (Lead Ads reliability), delivery has to be judged honestly rather than by status code (custom destinations), and order status has to come back from the destination at all — which for CPA networks means polling their status endpoints and mapping each network's own vocabulary onto one canonical set of states.
All of it runs at Targenix, free — the whole feature list is on the platform overview, the destinations are at targenix.uz/integrations, and the reasoning for charging nothing is at targenix.uz/pricing.