Skip to content
Meta Conversions API

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.

Convs teamPublished: 7 min read
Meta delivery list showing event identifiers and statuses
On this page
  1. Why send the same event twice in the first place?
  2. How Meta matches events: two methods
  3. How do you build a good eventid?
  4. Common mistakes that break deduplication
  5. How do you verify deduplication?
  6. How Convs keeps IDs consistent
  7. Limits
  8. Next step

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 matchevent name and ID: Pixel eventID = API event_idevent name and fbp or external_id
Arrival ordereithergenerally only works when the browser event comes first
Time window48 hours48 hours
Duplicates within one channelnot applicablenot 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:

  1. One per conversion. Two different orders never share an event_id.
  2. Identical on both sides. The browser and the server either derive it independently or one passes it to the other.
  3. 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:

text
purchase_ORDER-123

In the Pixel, pass it as the fourth argument:

js
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 fbp and fbc when 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.

SymptomCauseFix
Every purchase counted twiceThe Pixel sends no eventIDAdd eventID to the fbq call
Some purchases counted twiceBrowser and server generate random IDs separatelyDerive event_id from the order number
Duplicates after outagesServer retries create a new event_idStore the ID once and reuse it on every attempt
No deduplication despite equal IDsEvent names differ between the two sidesUse one event_name
Duplicates on delayed sendsThe server sends after more than 48 hoursSend promptly; Meta recommends real time or within an hour
Duplicates despite a correct PixelTwo server integrations (say, a store plugin and your own adapter) send the same event with different IDsKeep 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:

  1. Send server events in test mode with the code from Events Manager.
  2. Place a test order and note its number.
  3. Confirm the browser and server events carry the same ID.
  4. 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 same event_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_id and 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.
Delivery list with event identifiers and delivery status
Delivery list with event identifiers and delivery status

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 eventID to 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.

See what Meta sees

Connect your ad account and see which forms are ready and which need fixing. Free up to 100 leads a month, no card required.