The Conversions API rebuild that lowered CPA without touching an ad
A DTC pet-supplements brand on Shopify, spending around $22,000 a month, hired us in January 2026 convinced their creative had fatigued. Their reported ROAS said 3.1; their bank account disagreed. We did not open the creative library for the first three weeks. The entire engagement to that point happened inside Events Manager.
The numbers, before and after
| Metric | Before | After (week 6) |
|---|---|---|
| Event Match Quality, Purchase | 4.9 / 10 | 8.2 / 10 |
| Server-side share of Purchase events | 0% | 54% |
| Duplicate Purchase events | 9.4% of total | 0% (verified) |
| Reported ROAS (standard attribution) | 3.1 | 2.6 |
| Cost per acquisition, deduplicated | $47 | $40 |
Read the fourth row again. Reported ROAS went down, from 3.1 to 2.6, because 9.4% of the "purchases" the account had been optimizing toward were the same orders counted twice. The brand had been paying Meta to chase ghosts and paying itself compliments for it.
What the audit found
The setup was a browser Pixel installed years earlier plus a Shopify app that had quietly started sending its own server events with no event IDs. Without shared IDs, Meta cannot deduplicate, so both copies counted. Match quality sat at 4.9 because the events carried almost no hashed customer parameters: no email, no phone, no external ID. Delivery was optimizing on a blurry, inflated picture.
None of this is exotic. Sofia Marchetti has scored event pipelines on every audit since the iOS 14.5 reset, and duplicate-event inflation shows up in roughly a third of the Shopify accounts she reviews. It hides well because it makes the dashboard look better, not worse.
The rebuild, week by week
- Week 1: event map and payload review. Every Purchase, Add-to-Cart, and Lead event traced to its source. Duplicates documented and shown to the client before anything changed.
- Week 2: proper Conversions API from the Shopify backend with shared event IDs, hashed email, phone, and external ID on every event. The legacy app's events retired.
- Week 3: seven-day live comparison in the test-events tool, then the dedup overlap report. EMQ on Purchase closed at 8.2.
From week 4 the account ran on clean data with the same ads and the same budget. CPA drifted from $47 to $40 by week 6, a 15% improvement in line with Meta's published expectation of roughly 13% lower cost per action when CAPI joins the Pixel with strong match quality.
The conversation nobody enjoys
Week 3 included the meeting where we told a founder their real return was 2.6, not 3.1, and that the difference had been funding a planned budget increase. That meeting is the reason this engagement exists as a write-up: the deflating number changed three decisions inside a month. The budget increase was postponed until CPA stabilized. A "winning" creative that had ridden the duplicate counting was retired after re-scoring. And the brand's finance lead got read access to the weekly report, which is the cheapest trust-building we know.
The supplement category also sits one shelf away from Meta's January 2025 health-event restrictions, so the build documented exactly which events the brand may send and under what classification. Getting that wrong is how a tracking project becomes a policy problem.
Why this is the first job, not the last one
Every later decision in an account leans on these events. Creative tests are judged by them, budgets scale on them, and Advantage+ campaigns steer by them at auction time. Fixing the pipeline first meant the creative overhaul that followed, four fresh concepts a month on the management cadence, was measured against numbers worth trusting.
The build that did this is productized: fixed scope, fixed $3,400, three weeks. Details on the measurement service page, and the wider question of believable return targets is covered in what counts as a good ROAS on Meta.
If your ROAS looks great and your bank statement disagrees, start with the event pipeline.
Book a working session