Guide

Facebook pixel event deduplication with the Conversions API

Facebook pixel event deduplication: how Meta pairs Pixel and CAPI events on event_name and event_id within 48 hours, and the mistakes that break it.

By Simone Manto, founder of DropCPL · Published

Facebook pixel event deduplication is how Meta recognises that a Meta Pixel event and a Conversions API event describe the same action, so it counts one. Meta pairs them by name and ID: when the pixel’s eventID equals the server’s event_id and the event names match within 48 hours, it keeps the first copy and discards the rest.

Get it wrong and every lead reported by both channels is counted twice. Double-counted leads lower the cost per lead Meta shows you, so a broken setup looks like a good week. Meta’s help center article about deduplication warns that artificially high conversion numbers “can mislead optimization and budget allocation decisions”.

Why you need deduplication at all

Meta recommends what it calls a redundant setup: the Conversions API alongside the Meta Pixel, sending the same events through both (Meta’s guide to handling duplicate events). The pixel relies on the browser, and the same help center article notes that browser data can be blocked or lost to browser settings or connectivity issues. The server sends what the browser drops. Meta even sets a target in its article on server event details: the Conversions API should cover 75% of your pixel events.

Redundancy creates the problem this guide is about. Send the same event from both sides and you have to tell Meta which copies belong together. Send different events from each side (PageView from the browser and Lead from the server, for instance) and there’s nothing to deduplicate.

For lead gen, take a clear line: send the Lead from the server every time, keep the pixel’s Lead as the redundant copy, and give both the same ID. The server event is the one you control, which is the whole point of server-side tracking. The browser event is the one that may or may not arrive.

How Facebook pixel event deduplication works

The rule: event_name plus event_id

Meta treats two events as identical when both conditions hold:

  1. the pixel’s eventID matches the Conversions API event_id;
  2. the pixel’s event name matches the Conversions API event_name.

On the pixel, eventID goes in the fourth argument of the fbq call. For a Lead with no value or currency:

fbq('track', 'Lead', {}, {eventID: 'lead_3f9c2a7e-1b4d-4c8e-9a51-0d6e2f7b8c14'});

The 48-hour window, and which copy Meta keeps

Events are deduplicated only if they arrive within 48 hours of the first event Meta received with that event_id. Inside the window, Meta generally prefers the event it received first when the two don’t differ meaningfully in content. Its server event reference adds that when a browser event and a server event arrive within 5 minutes of each other, the browser event is favoured.

The same logic covers repeats from a single source. According to Meta’s guide to using the API, when the same event_id and event_name arrive more than once, Meta keeps only the first copy, which makes retries safe.

What that means in common cases (example timings):

CaseResult
Pixel Lead and server Lead, same event_id, 10 seconds apartcounted once; the browser copy is favoured
Same pair, server event sent 3 hours later from a queuecounted once; the first copy received is kept
Same pair, server event sent 3 days latercounted twice: outside the 48-hour window
Server retries a Lead with the same event_idcounted once
Pixel and server each generate their own IDcounted twice
Pixel sends no eventID at allcounted twice, unless the fallback below catches it

The fallback: fbp or external_id

Meta has a second method. If the browser and server events carry the same event_name plus the same fbp and/or external_id, Meta compares the server event with a browser event sent earlier. Its own guide lists the limits:

  • it generally works only when the browser event is sent first and the server event follows;
  • “Server events will not be discarded if a browser event has not been received in the past 48 hours, even if an identical browser event arrives after the server event”;
  • it doesn’t deduplicate within one source: two identical browser events, or two identical server events, are both kept.

That last point is the opposite of the event_id method. Treat fbp and external_id as a safety net and event_id as the key; it’s also the method Meta marks as recommended.

MethodKeysWorks whenFails when
event_name + event_id (recommended)eventID on the pixel, event_id on the serverboth copies carry the same name and ID within 48 hoursthe IDs differ, or one side sends none
event_name + fbp / external_idthe same fbp and/or external_id on both sidesthe browser event arrives firstthe server event arrives first, or only one source sends the event

A server Lead event with event_id

The pixel half is the fbq call above. The server half is a POST to https://graph.facebook.com/<API_VERSION>/<PIXEL_ID>/events carrying the same ID. Example payload for a Lead from a landing page form:

{
  "data": [
    {
      "event_name": "Lead",
      "event_time": 1793787302,
      "event_id": "lead_3f9c2a7e-1b4d-4c8e-9a51-0d6e2f7b8c14",
      "action_source": "website",
      "event_source_url": "https://offer.example.com/free-quote",
      "user_data": {
        "em": ["10928b45363b7d849e040470c3277657f8177ef5a953a092b4302f149757a02e"],
        "ph": ["75565655f639ba28fbb0a88254e0d01fad0a351049bde96a286e336219a33e5f"],
        "client_ip_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
        "client_user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
        "fbc": "fb.1.1793787151204.IwAR2F4-dbP0l7Mn1IawQQGCINEz7PYXQvwjNwB_qa2ofrHyiLjcbCRxTDMgk",
        "fbp": "fb.1.1793787151880.1684203391"
      }
    }
  ]
}

What to check in it:

  • event_name is Lead, written exactly as on the pixel.
  • event_id is the string the pixel sent as eventID.
  • event_time is in Unix seconds (here 4 November 2026, 10:15:02 UTC). Meta rejects the whole request if any event in it is more than 7 days old.
  • action_source is required, and event_source_url is required for website events.
  • em and ph are SHA-256 hashes of the normalised email and phone, while fbc (which carries the fbclid), fbp, the IP and the user agent go in clear. The Event Match Quality guide covers the hashing, and _fbc and _fbp cookies, explained covers the two cookie values.

DropCPL sends the Lead event to Meta from the server with an event_id for deduplication, plus fbc and fbp. Your CPL is computed on the leads your server received, so a deduplication slip on Meta’s side never inflates the number you decide on. Start free →

Where the event_id should come from

One ID per lead, generated once, used by both sides. For a form on a landing page the simplest flow is:

  1. When the visitor submits, the browser generates the ID. A UUID is fine: Meta accepts any unique string.
  2. The pixel fires Lead with that ID as eventID.
  3. The same ID travels to your server inside the form POST, as a hidden field for example.
  4. Your server sends the Lead through the Conversions API with that ID as event_id, and stores it with the lead.

If JavaScript didn’t run, the pixel never fired either, so the server can generate its own ID with no risk of a duplicate. The reverse flow works too: the server creates the lead, returns its ID, and the confirmation screen fires the pixel with it. Meta’s own examples of event_id are order numbers and transaction IDs, and for events without one, “a random number (so long as the same random number is sent between browser and server events)”.

Facebook pixel event deduplication mistakes

MistakeWhat happensFix
Different event names (Lead on the pixel, lead or a custom FormSubmit on the server)no pair is found; both events countthe same standard event name, formatted identically on both sides
event_id generated separately in the browser and on the servertwo random IDs never matchgenerate it once and pass it to the server
Only one side sends the ID (a plugin or a hard-coded pixel without eventID)those events can’t be pairedfind every pixel source; each one passes the shared ID
One event_id reused for different leads (a constant, the form’s ID)real leads arriving within 48 hours are discarded as duplicatesone ID per lead
Browser and server send to different pixel IDsno deduplication across the two datasetsthe same pixel ID on both sides; easy to miss when an agency runs several clients
Server events held in a queue for daysoutside the 48-hour window, both copies countsend events as they happen; Meta asks for “ideally within an hour”
Relying on fbp alone while the server event goes firstthe server copy is keptadd event_id

Meta’s own troubleshooting list, in the same help center article, puts event_id consistency first and asks you to confirm that event_name and event_id are formatted identically across sources.

How to verify event deduplication in Events Manager

  1. Test one real submission. In Events Manager, open your dataset and the Test events tab, copy the test code and send it as test_event_code at the top level of your server request. Submit the form on your landing page and check that the browser and server Leads both arrive and that one of them is deduplicated; Meta’s help center points to this tool to see which events are received, deduplicated or dropped. Then remove the code. Meta notes that events sent with test_event_code are not dropped: they flow into Events Manager and are used for targeting and measurement, so a test lead is a real Lead as far as Meta is concerned.
  2. Read the Event Deduplication tab. Under the event’s View details, the deduplication keys table shows the share of pixel and server events received with each key, and Overlap shows the share received from both sources. If both sources report event_id and overlap stays low, the IDs aren’t the same strings.
  3. Don’t read Events Received as an alarm. In the Event Overview tab, Events Received is the sum of pixel and server events before deduplication, so it’s supposed to look high.
  4. Compare with the leads you received. Meta’s reported leads and your own count never match exactly, for reasons covered in real CPL vs platform CPL. A Meta count close to double yours, though, points at deduplication first. It’s check number three in CPL: five things to keep in mind.

FAQ

What is the deduplication window for the Meta Pixel and the Conversions API?+

48 hours. Meta deduplicates a browser and a server event with the same event_name and event_id only if they arrive within 48 hours of the first event received with that ID. Outside the window, both copies are counted.

Does Meta keep the browser event or the server event?+

When the two copies don't differ meaningfully in content, Meta generally keeps the one it received first. Its server event reference adds that if they arrive within 5 minutes of each other, the browser event is favoured.

Can Meta deduplicate events without an event_id?+

Partly. Meta can match event_name plus fbp and/or external_id, but this generally works only when the browser event arrives first, and it never deduplicates two events from the same source. Use event_id as the key and treat fbp and external_id as extra keys.

Why does Events Manager show more events after adding the Conversions API?+

Events Received, in the Event Overview tab, is the sum of pixel and server events before deduplication. To judge deduplication, open the Event Deduplication tab: it shows the share of events carrying each key and how much the two sources overlap.

Do I need deduplication if I only send events from the server?+

Not between sources, because there is no browser copy to collide with. Keep a stable event_id anyway: Meta also drops repeated server events with the same event_name and event_id, so a retried request is not counted twice.

Ready to find out what
converts, for real?

Free to start.

Start free →