When you run both a browser Meta Pixel and the Conversions API, the same purchase event gets sent to Meta twice — once from the buyer’s browser and once from your server. Without deduplication, Meta counts it as two conversions. Your reported ROAS doubles, your campaign data becomes unreliable, and Meta’s algorithm optimises based on numbers that do not reflect reality.
Deduplication is the mechanism that prevents this double-counting. It is not optional if you are using both pixel and CAPI — it is essential. This guide explains exactly how Meta deduplication works, how to implement it correctly, and how to verify it is functioning as expected.
Why Deduplication Is Necessary
When a customer completes a purchase on your site, two things happen almost simultaneously:
- Your browser pixel fires a Purchase event from the customer’s browser directly to Meta
- Your server (via CAPI) sends a Purchase event to Meta’s server-side API
Both events arrive at Meta within seconds of each other. Without a way to identify that they represent the same transaction, Meta records them as two separate conversions. The result:
- Your conversion count is doubled
- Your reported ROAS is inflated — your campaigns look more profitable than they are
- Meta’s bidding algorithm over-values the ad placements that generated these “conversions”
- Campaign optimisation goes wrong — the algorithm bids aggressively on customers who may not convert at the rate Meta thinks
How Meta Deduplication Works
Meta uses a parameter called event_id to identify duplicate events. The rule is simple: if Meta receives two events of the same type (e.g., Purchase) with the same event_id within a short time window (typically a few minutes), it keeps only one and discards the other.
For this to work, you must:
- Generate a unique event_id for each transaction on your server
- Pass the same event_id to both your browser pixel and your CAPI payload
The event_id can be any unique string — your order ID works perfectly for Purchase events. What matters is that the browser pixel and the CAPI server event for the same purchase use exactly the same event_id value.
How to Implement event_id: The Correct Approach
The safest and most reliable implementation uses your order ID as the event_id for Purchase events, since it is guaranteed to be unique per transaction and available on both browser and server.
On the browser side (your order confirmation page pixel code):
fbq('track', 'Purchase', {
value: 89.99,
currency: 'GBP',
content_type: 'product',
num_items: 1
}, {
eventID: 'order_12345' // must match the CAPI eventId exactly
});
On the server side (your CAPI payload):
{
"event_name": "Purchase",
"event_id": "order_12345", // same value as browser eventID
"event_time": 1720000000,
"user_data": {
"em": "hashed_email",
"ph": "hashed_phone"
},
"custom_data": {
"value": 89.99,
"currency": "GBP"
}
}
The field name differs slightly between browser and server: the browser pixel uses eventID (camelCase) as the second parameter to fbq('track'), while the CAPI payload uses event_id (snake_case). Both refer to the same deduplication key — Meta normalises them on its end.
What to Use as Your event_id
| Event Type | Recommended event_id | Why |
|---|---|---|
| Purchase | Order ID (e.g., “order_12345”) | Unique per transaction, available on both browser and server |
| Lead | Form submission ID or session ID + timestamp | Unique per submission |
| AddToCart | Session ID + product ID + timestamp | Unique per cart action |
| ViewContent | Session ID + product ID | Unique per product view per session |
For Purchase events, the order ID is the cleanest choice because it exists in both places — the browser confirmation page and your server-side order processing — without any extra data passing required.
The Role of fbp and fbc in Deduplication
Beyond event_id, Meta also uses two browser-set cookies — _fbp (Facebook browser identifier) and _fbc (Facebook click identifier) — to help match browser and server events for the same user.
- _fbp — set by the pixel on first page load; identifies the browser session
- _fbc — set when a user arrives from a Meta ad (contains the fbclid click parameter)
For CAPI, read these cookie values server-side and include them in your CAPI payload under user_data.fbp and user_data.fbc. This helps Meta attribute server-side events to the correct ad click, improving attribution accuracy even independently of deduplication.
For server-side tracking integrations, most CAPI libraries handle fbp and fbc automatically if you provide the request cookies.
How to Verify Deduplication Is Working
In Meta Events Manager, go to your Purchase event’s detail view and look at the Deduplicated column. This shows the percentage of events that were received from both browser and server and successfully matched using event_id.
- Deduplicated percentage is 40–60% — healthy. This means roughly half of your events arrived from both sources and were correctly deduplicated.
- Deduplicated percentage is 0% — deduplication is not working. Your event_ids on browser and server are not matching, or one side is not sending event_id at all.
- Deduplicated percentage is 90%+ — investigate. This might indicate most events are arriving twice due to an overly aggressive retry mechanism on your CAPI implementation.
You can also use the Test Events tool in Events Manager. Complete a test purchase and look at the server event that appears — it should show the same event_id as the browser event. If they match, deduplication will work for real transactions.
Deduplication for Non-Purchase Events
Deduplication is most critical for Purchase events because they carry revenue values. Over-reporting purchases directly inflates your ROAS and misleads your bidding algorithm.
For other events like AddToCart, ViewContent, and PageView, the consequences of over-reporting are less severe — they do not carry revenue values and are used primarily for audience building rather than direct campaign optimisation. However, best practice is to implement event_id on all events you send via both browser and CAPI, not just Purchase.
Common Deduplication Mistakes
- Different event_id formats on browser vs server — for example, the browser sends “12345” and the server sends “order_12345”. These do not match and deduplication will not occur. Use exactly the same string on both sides.
- Missing event_id on the browser pixel — the browser pixel fires without eventID in the second parameter, so Meta has nothing to match against the server event_id
- Generating a new random event_id per request — some implementations generate a random UUID for event_id on both browser and server independently. Since both generate different random IDs, they never match. The event_id must come from a shared source — like the order ID — that both browser and server can access.
- Assuming deduplication works automatically — without explicit event_id implementation, Meta cannot deduplicate. The default behavior is to count all received events, including duplicates.
After implementing deduplication, run a tracking audit to confirm the Deduplicated column in Events Manager is showing non-zero activity within 24 hours of your next real purchase.
Related Articles
- What Is Meta Conversions API? A Complete Guide
- Meta Events Manager: How to Use It to Fix Your Pixel
- Tracking Explained: How Every Ad Platform Tracks Your Ads
- Free Tracking Audit Checklist: Is Your Setup Working?
📋 Not sure where to start? Use our Free Tracking Audit Checklist to find out where your setup is losing data.
Book a free tracking audit → We’ll review your setup and tell you exactly what to fix.