Meta Pixel and CAPI: why purchases are counted twice
How deduplication actually works, what eid looks like in the browser request, and the five mistakes that turn a single order into two conversions.
Running the Pixel and the Conversions API side by side is the setup Meta recommends, and it doubles your purchases the moment deduplication is not quite right. Reporting looks excellent for a week, ROAS looks excellent, and then somebody reconciles against the order table.
How deduplication works
Meta drops the second copy of an event when two things are true at once: both events carry the
same event name, and both carry the same event ID. That is the entire
mechanism. In the browser the ID is the fourth argument to fbq:
fbq('track', 'Purchase', { value: 1648.25, currency: 'TRY' }, { eventID: 'ORD-70412' })
The server event sent through the Conversions API has to carry event_name: "Purchase" and
event_id: "ORD-70412". Same name, same ID, one conversion. Anything else and you have two.
Meta matches the pair inside a 48-hour window, so the halves do not have to arrive together — but they do have to agree.
What the browser request shows
The Pixel sends its event to facebook.com/tr/, and everything interesting is in the query
string:
id— the pixel ID.ev— the event name.Purchaseandpurchaseare two different events to Meta: the second is a custom event and will never deduplicate against the first.eid— the event ID, and the dedup key. If it is missing, deduplication cannot happen at all, whatever the server sends.cd[...]— custom data:cd[value],cd[currency],cd[content_ids]and the rest.ud[...]— user data, hashed.ud[em]should be a SHA-256 digest; if you can read an email address there, you have a much more urgent problem than deduplication.fbpandfbc— the browser ID cookie and the click ID cookie.
Reading eid off the request answers the first question — is the browser half even taking part
in deduplication — in a couple of seconds, without opening Events Manager.
Five ways it breaks
- Only one side sends an ID. The server work was done carefully and the pixel was left
as it was, or the other way round. No
eid, no dedup. - Each side generates its own. A fresh UUID on both sides is two IDs and two conversions. The ID has to come from something both sides already know: the order number.
- The event names differ. A custom
purchasein the browser against a standardPurchaseon the server. Capitalisation counts. - The pixel fires twice. Single-page checkouts re-initialise on a route change and send
a second
Purchasewith a new ID. A customer reloading or bookmarking the confirmation page does the same thing. - Two tags for one event. A GTM tag and a hardcoded snippet in the theme both fire. This is the one that survives every audit, because each tag is correct on its own.
Tag Master lists every Meta request the page made, shows whether eid is present and what it
contains, and flags the same conversion being sent twice — which covers the browser half of all five
cases above.
What the browser can and cannot prove
Being straight about the limit: a browser extension cannot see your server events. It cannot tell you whether the Conversions API call went out, what ID it carried, or whether Meta matched the pair. Events Manager is the only place that reports the dedup outcome, and its deduplication diagnostic is worth reading.
What the browser settles is the half that is usually at fault. Four of the five failures above are browser-side — a missing ID, a random ID, a wrong event name, a duplicate fire — and all four are visible in the request before anyone goes near a server log.
A check routine
- Complete a test purchase with the panel open.
- Find the
Purchaserequest and confirmevis spelled exactly as the server spells it. - Read
eid. It should be there, and it should be recognisable — your order number, not a random string. - Count the Purchase requests. There should be exactly one. Reload the confirmation page and count again.
- Compare
cd[value]andcd[currency]with the order. A deduplicated pair with the wrong value still reports the wrong revenue. - Only now open Events Manager and look at the deduplication rate for that event.
Choosing an event ID
The ID has to be derivable from the same fact on both sides and survive a reload. For a purchase that is
the order number and nothing else comes close. For events with no natural key — a ViewContent,
an AddToCart — generate the ID once, put it in the dataLayer, and have both the pixel and the
server read it from there. An ID invented independently in two places is not an ID; it is two IDs sharing a
field name.
Related guides
- How to debug GTM without Preview mode
- Test Events for TikTok, Snap, UET and five more
- Testing tracking without polluting production analytics
Try it on your own site
Tag Master is free, needs no account, and collects no data.
Add to Chrome — Free