The moment you add the Meta Conversions API on top of your pixel, you risk counting every purchase twice. Meta's deduplication is what stops that, and most setups get it subtly wrong.
Why you need both, and why that creates a problem
The browser pixel is easy to lose. ITP, ad blockers, consent tools, and dropped connections all eat events before they reach Meta.
The Conversions API sends the same events server-to-server, so they arrive anyway. Run both and coverage jumps.
Run both without deduplication and Meta sees two Purchase events for one order, inflating conversions and training optimization on noise. The whole point of adding CAPI is more complete data, so getting the dedup wrong turns an upgrade into a downgrade.
How Meta Conversions API deduplication works
Meta deduplicates on two fields together: event_name and event_id.
If a pixel event and a CAPI event share the same event_name (say, Purchase) and the same event_id, Meta keeps one and drops the other, within a matching window Meta documents at around 48 hours.
The fbp and fbc cookies and external_id improve matching, but the deduplication key is event_id plus event_name. Miss the shared id and nothing dedupes.
Two more fields matter for pairing: action_source should be website on both sides, and event_time should be close, because an event that lands days apart from its twin falls outside the window and counts on its own.
Setup, step by step
First, fire the pixel with an explicit event ID:
fbq('track', 'Purchase', {value: 49.00, currency: 'USD'}, {eventID: 'order_10432'});
Second, send the CAPI event with the identical event_id and event_name:
curl -X POST \
"https://graph.facebook.com/v20.0/<PIXEL_ID>/events?access_token=<TOKEN>" \
-d '{
"data": [{
"event_name": "Purchase",
"event_time": 1699999999,
"event_id": "order_10432",
"action_source": "website",
"user_data": {
"em": "<sha256_email>",
"fbp": "fb.1...",
"fbc": "fb.1..."
},
"custom_data": { "value": 49.00, "currency": "USD" }
}]
}'
Third, pass user_data to lift match quality. Fourth, confirm in Events Manager: the event shows as received from both the pixel and the server and marked deduplicated.
Use your order ID as the event_id. It's stable and unique per order, unlike a random value generated twice on two different systems.
Verify before you trust it
Open the Test Events tab in Events Manager, run a real purchase, and confirm the same event arrives from both the browser and the server under one entry.
In the live diagnostics Meta reports how many events were deduplicated over the last few days, which is the fastest way to catch a broken event_id in production before it skews a week of optimization.
Match quality is the other half
Deduplication stops double counting, but match quality decides how many of those events Meta can tie to a person and use for optimization.
Send everything you can in user_data: hashed email (em), hashed phone (ph), first and last name, external_id, plus client_ip_address and client_user_agent from the request. Hash PII with SHA-256 after lowercasing and trimming, or Meta rejects the match.
Watch the Event Match Quality score in Events Manager and treat a low score as a bug, not a cosmetic warning, because it directly caps how much of your CAPI data actually works.
Where it breaks
- Different or missing event_id on one side, so nothing matches and both count.
- Server event_time far outside the window, so Meta can't pair the events.
- Only Purchase sent through CAPI while everything else stays pixel-only, leaving partial dedup and reports nobody trusts.
- No fbp or fbc, so events still dedupe but match quality drops and attribution suffers.
- Unhashed or wrongly normalized PII, so the fields you sent do nothing.
CAPI is a second stream you reconcile with the first, not a switch you flip.
Get the shared event_id right and you gain the coverage for free. Get it wrong and the API you added to fix tracking does the one thing you feared: it counts every purchase twice.
Want a stronger data analyst role or a raise? Grab the FREE Product Analyst Playbook and get the exact roadmap to your next offer.

