Pixel and Conversions API Deduplication: event_id, event_name and the 48-Hour Window
How Meta merges the same event from the Pixel and the Conversions API: event_id, event_name, the 48-hour window, the fbp method, common mistakes and how to check.

On this page
Event deduplication is how Meta recognises that a Purchase from the Pixel and a Purchase from the Conversions API are the same conversion. Without it, every order reported both ways counts twice: reports show more sales than you made, and the delivery system learns from inflated data. This guide covers how Meta matches events, how to build an event_id, the mistakes that break deduplication and how to verify it.
Why send the same event twice in the first place?
Because Meta recommends it. Its documentation explicitly advises running the Conversions API alongside the Pixel, a redundant setup. The Pixel sometimes fails (ad blockers, no consent, a closed tab), and the server sometimes lacks browser signals. Together they give a fuller picture.
The price of redundancy is the risk of double counting. Deduplication removes it, but only if both sides speak the same language. If an event only ever travels through one channel, Pixel deduplication doesn't apply to it, as Meta also notes.
How Meta matches events: two methods
Meta documents two methods. The first is the recommended one.
event_id + event_name (recommended) | fbp or external_id (alternative) | |
|---|---|---|
| What must match | event name and ID: Pixel eventID = API event_id | event name and fbp or external_id |
| Arrival order | either | generally only works when the browser event comes first |
| Time window | 48 hours | 48 hours |
| Duplicates within one channel | not applicable | not removed when using browser-only or server-only |
With the recommended method, Meta deduplicates events received within 48 hours of the first event carrying that event_id. When the browser and server versions don't differ meaningfully, Meta generally keeps whichever arrived first.
The alternative method has a catch: a server event that arrives when no browser event was received in the previous 48 hours is not discarded, even if an identical browser event shows up later. Server-side purchases often arrive before the Pixel does, so this method fails exactly where you need it. The rest of this guide sticks with event_id.
How do you build a good event_id?
event_id is any string you choose. The parameter reference marks it as optional but recommended for deduplication. A good ID meets three conditions:
- One per conversion. Two different orders never share an
event_id. - Identical on both sides. The browser and the server either derive it independently or one passes it to the other.
- Stable across retries. When the server retries after an error, it doesn't mint a new ID.
The easiest approach is to base it on the order or CRM record number, which both sides already know:
purchase_ORDER-123In the Pixel, pass it as the fourth argument:
fbq('track', 'Purchase', { value: 149.99, currency: 'USD' }, { eventID: 'purchase_ORDER-123' });On the server, the same value goes into event_id, together with event_name: "Purchase". The names must match exactly. If the Pixel sends the standard Purchase and the server sends a custom name such as Order, Meta treats them as two different events.
Give both versions full data
Since Meta generally keeps whichever event arrives first, you can't know in advance which version survives. If the Pixel sends only the _fbp cookie and the server sends a hashed email and phone, some of that information may be lost after deduplication. So:
- on the server, also include the browser's
fbpandfbcwhen you've collected them with the customer's consent, - on the Pixel, use advanced matching if your privacy policy allows it,
- send the same order value and currency in both versions.
Different amounts for the same purchase are a sign that something is calculated differently, such as shipping included on one side and not the other. Align that before comparing revenue in reports. Our guide to Event Match Quality covers which customer details help matching most.
Common mistakes that break deduplication
Most double-counting problems come down to one of these.
| Symptom | Cause | Fix |
|---|---|---|
| Every purchase counted twice | The Pixel sends no eventID | Add eventID to the fbq call |
| Some purchases counted twice | Browser and server generate random IDs separately | Derive event_id from the order number |
| Duplicates after outages | Server retries create a new event_id | Store the ID once and reuse it on every attempt |
| No deduplication despite equal IDs | Event names differ between the two sides | Use one event_name |
| Duplicates on delayed sends | The server sends after more than 48 hours | Send promptly; Meta recommends real time or within an hour |
| Duplicates despite a correct Pixel | Two server integrations (say, a store plugin and your own adapter) send the same event with different IDs | Keep one server-side integration per event |
That last one happens more often than you'd think. Store platforms and tag managers frequently ship their own Conversions API connection. Add a second one with a different ID scheme and the two will never deduplicate against each other.
How do you verify deduplication?
Meta surfaces it in Events Manager. Per its verification guide, open the Pixel's Overview, click the event details button for an event and go to the Event Deduplication tab. It shows the percentage of deduplicated events; higher is better, and a warning appears when the rate is too low.
The same area has an Event Freshness tab with the average delay. If server events lag by days, you're at risk of missing the 48-hour window.
A quick pre-launch test:
- Send server events in test mode with the code from Events Manager.
- Place a test order and note its number.
- Confirm the browser and server events carry the same ID.
- After going live, watch the deduplication tab for a few days.
How Convs keeps IDs consistent
Convs can't change the Pixel code on your site, but it keeps the server side predictable:
- Stable
event_id. When a source provides no ID (a Google Sheets row, for example), the hub derives one from the source, the record ID and the status. The same record in the same status always gets the sameevent_id. - Store purchases require
event_id. The store source rejects an order without one, because Pixel deduplication is impossible without it. See server-side Purchase events for online stores. - Retries keep the ID. The queue delivers at least once: after a network error or rate limit it resends with the same
event_id, so Meta can deduplicate. - Deduplication before sending. An event (source + record ID + status) is accepted once. The same combination of dataset, event name,
event_idand mode (test or production) is never queued twice, even from two different connections to the same dataset. - Lead stages from Meta lead forms have a stable ID per lead and stage, and each stage is recorded once.

Test and production are deduplicated separately, so an event sent in test mode won't block the later production send. More on the queue on the Meta Conversions API feature page.
Limits
Deduplication doesn't fix everything:
- The hub can't add
eventIDto your Pixel. If your Pixel installation can't set it, the double-send problem remains. In that case, sending the event through only one channel is the honest option. - It can't see other integrations. The hub deduplicates what it sends. Events from a store plugin or tag manager run alongside, and Meta has to reconcile them.
- At-least-once delivery. The hub doesn't promise exactly-once; Meta has the final say on deduplication.
- Receipt isn't attribution. Meta accepting an event doesn't prove a campaign optimises for it.
Next step
List every event you send from both the Pixel and the server, and for each one check where eventID comes from. To run the server side through Convs, start with a destination in test mode. Plans are on the pricing page, and the basics are in what the Meta Conversions API is.
Frequently asked questions
How long is Meta's deduplication window?
Meta's documentation says events are deduplicated only if they are received within 48 hours of the first event with a given event_id. A matching event that arrives later is counted separately.
Does event_id have to be unique?
Unique per conversion, yes, but identical across the browser and the server and across retries. Deriving it from an order or record number, such as purchase_ORDER-123, works far better than a random number generated separately in each place.
Which version does Meta keep, the Pixel event or the server event?
Meta says that when the two don't differ meaningfully, it generally keeps the one received first. Send full customer information on both sides, since you can't know which one will be kept.
Is deduplication by fbp just as good?
No. The fbp or external_id method generally works only when the browser event arrives first, and it doesn't remove duplicates within a single channel. Meta recommends the event_id method.
Do CRM lead events need deduplication?
Only if you send the same event through two channels. Lead stages such as QualifiedLead usually come only from the server, so Pixel deduplication doesn't apply. They still need a stable event_id so retries don't create duplicates.
How can I check that deduplication works?
In Events Manager, open the Pixel's Overview, the event's details and the Event Deduplication tab. Meta shows the share of deduplicated events there and warns you when it is too low.

