Meta Event Deduplication: event_id Done Right | Clikim
Home  /  Blog  /  Event Deduplication
By Yael Rachmut · Pixel & CAPI clinic · Updated August 2026 · 8 min read

Event Deduplication That Actually Passes the Test

Pixel plus CAPI means two copies of every conversion by design — the merge is yours to wire. The four dedup keys in match order, the order-ID golden rule, your platform's version of the classic failure, a video walkthrough, and the verification moment that makes 'done' a fact instead of a feeling.

Meta event deduplication event_id setup
QUICK ANSWER

Meta deduplicates pixel+CAPI copies using event_name + event_id first (then fbp, then external_id) within a ~48-hour window. Golden rule: derive event_id from the ORDER ID so both sides compute the same value independently — separately-generated UUIDs are valid, unique, and match nothing. Verify with one test purchase in Test Events: one merged row with browser+server icons = done; then confirm dedup rate 95%+ in Events Manager (under 80% = double-counting reaching reports AND optimization). Classic real-world breakage: a forgotten second sender — legacy theme snippets, parallel apps. Re-verify after every checkout/app/plugin change.

Key takeaways

• Meta merges pixel+CAPI copies of an event using event_name + event_id first (then fbp, then external_id) inside a ~48-hour window. • The golden rule: derive event_id from the order (order ID/transaction ID) so both sides compute the same value independently — random per-side UUIDs are the classic silent failure. • Verification is a moment, not a vibe: one test purchase → Test Events shows a single merged row with browser+server icons → dedup rate 95%+ in Events Manager. • Dedup failure cuts both ways: unmatched copies double-count (inflated results, corrupted optimization); missing server events under-count (signal loss). • Most real-world breakage is a forgotten second sender — legacy theme snippets and parallel apps — not the primary integration. • Re-verify after ANY checkout, app or plugin change; tracking rots at the speed of updates.

How the merge actually works

Four keys, one window, one rule — the mechanics behind every dedup rate you'll ever read.

Four keys, one window, one rule — the mechanics behind every dedup rate you'll ever read.

Running the pixel and the Conversions API together means Meta receives two copies of every conversion by design — the browser's version and your server's. The merge that turns two copies into one counted event checks, in order: event_name + event_id (the pair you control — identical values on both sides collapse into one event, with the richer data kept), then fbp (the browser cookie, when your server event carries it), then external_id (your hashed customer identifier). The window is roughly 48 hours; the first-arriving copy establishes the event. Meta's developer documentation covers the parameters exhaustively, but the entire practical craft compresses to one sentence: derive event_id from something the order already owns — the order ID — so browser and server compute identical values without ever coordinating. Every elegant failure we've audited generated valid, unique, beautiful UUIDs… separately, per side, matching nothing.

Your platform's version of the same mistake

Platform
Where event_id comes from
The classic failure
The fix
Shopify (native Meta app)
Handled automatically — order ID based
A SECOND sender (old theme snippet, extra app) firing without matching IDs
One integration owns Purchase; remove legacy snippets after checkout-extensibility migration
WooCommerce (official plugin)
Plugin-generated; versions have regressed
Plugin update breaks server events → browser-only or mismatched IDs
Pin known-good versions; verify after every update; PixelYourSite-class alternatives if chronic
Custom / GTM web + server
YOU wire it — dataLayer order ID to both tags
Each side generating its own random UUID
One generation point (dataLayer), both tags read the SAME value
Direct API (developer)
Your backend sets event_id explicitly
Sending order_id on server but transaction hash on pixel
Same source field, same casing, both sides

Every platform's failure is the same failure wearing different clothes: two senders, two ID schemes, zero matches.

The visual walkthrough

For the click-by-click version — pixel setup, event_id wiring, and the Test Events verification — this walkthrough covers the full 2026 flow:

Conversions API + event_id + deduplication, walked through end to end.

The verification loop (the part everyone skips)

Code shipping is the midpoint, not the finish. The loop: (1) Events Manager → your dataset → Test Events tab, test code active on your site session. (2) Buy something cheap — a real test order, not a pageview stare. (3) Watch for the moment that matters: one Purchase row wearing BOTH browser and server icons, dedup indicated. Two rows = IDs aren't matching (log both payloads; find the scheme mismatch). One row, one icon = a side isn't firing (blocked pixel or dead server call). (4) Production check 24–48h later: the event's dedup rate in Events Manager — 95%+ is healthy, under 80% means real double-counting is reaching reports and optimization (the exact inflation anatomy from the Meta-vs-Shopify guide). (5) Re-run the single test purchase after ANY change to checkout, apps, themes or plugins — the audits we see fail were all "verified once, in 2024."

Why this is worth an afternoon: the two-sided tax

Broken dedup taxes in both directions at once. Unmatched double-fires inflate reported results 30–100% on the affected event — which doesn't just embarrass reconciliations, it trains delivery on fiction: optimization learns conversions are cheap and plentiful, bids accordingly, and spends into audiences that never earned it. Meanwhile, running pixel-only to "avoid duplicate risk" — a genuinely common panic response — trades the inflation for under-counting: 30–50% of conversions lost to blockers, iOS and consent, with delivery starved of exactly the signal it needs. The only correct posture is both senders, matched IDs, verified merge — an afternoon of work that most accounts recoup inside the month, in steadier CPAs and dashboards that survive audits.

One test purchase, one merged row, one number above 95% — deduplication is the rare tracking problem with a definite done-state.

One test purchase, one merged row, one number above 95% — deduplication is the rare tracking problem with a definite done-state.

Why media buyers run on Clikim
9,800+
accounts under management
$490M+
in ad spend processed
<3 min
average rep reply
0%
top-up & spend fees
Trusted by 1,200+ media buyers scaling 7–8 figures on whitelisted Meta & TikTok accounts.

Frequently asked questions

What should I use as the event_id?+
The order ID (or transaction ID) — unique per conversion and, critically, identical on both browser and server sides of the same order without coordination. For non-purchase events, any stable per-event identifier both sides can derive (form submission ID, lead ID) plays the same role.
Where do I see my deduplication rate?+
Events Manager → your dataset → select the event (e.g., Purchase) → the deduplication details show what share of browser/server pairs merged. 95%+ is healthy; 80–95% deserves a look; under 80% is active double-counting.
What does 'missing deduplication parameter' mean in Events Manager?+
Your server events are arriving without an event_id (or without one matching any browser event). Meta is warning you it can't merge — fix by wiring the shared ID; until then, affected events risk double-counting.
Why do I see two Purchase rows in Test Events?+
Both senders fire but their IDs don't match: different schemes (order ID vs hash), different casing, or per-side random generation. Log both payloads side by side — the mismatch is always visible in the event_id field.
Does deduplication happen across different event names?+
No — event_name is part of the key. A browser 'Purchase' and a server 'purchase' (case differences) or 'CompletePayment' won't merge. Identical names, identical IDs, both sides.
What happens if only my pixel fires (no CAPI)?+
No dedup problem — and a bigger one instead: browser-only tracking loses 30–50% of conversions to blockers, iOS and consent, and starves optimization. Dedup anxiety is never a reason to skip server events; it's a reason to wire them properly.
Can duplicate events affect optimization, not just reporting?+
Directly: delivery learns from the event stream, so double-counted purchases teach the system conversions are cheaper and more common than reality — bids and audience selection follow the fiction. Accounts often see CPA stability improve within weeks of fixing dedup.
Shopify handles this automatically — am I safe?+
The native integration is, by itself. The Shopify failures we audit are almost always a SECOND sender: a theme snippet from an old tutorial, a tracking app running parallel Purchase events, or a post-checkout-extensibility leftover. One test purchase reveals the whole cast.
The WooCommerce plugin keeps breaking my dedup — options?+
A known pattern — official-plugin releases have regressed server events more than once. Pin a known-good version and verify after updates, or move to an alternative sender (PixelYourSite-class plugins, or sGTM) — with ONE sender owning each event either way.
Is there a dedup window — can late server events still merge?+
Roughly 48 hours: copies arriving within it (matching keys) merge; beyond it they count separately. Batch-sending server events daily is fine; weekly is asking for phantom duplicates.
Do I need external_id if event_id is set up correctly?+
Not for dedup — event_id does that job. external_id (hashed customer ID) still earns its place for match quality: it helps Meta connect events to users, which lifts EMQ and attribution coverage. Send both; they solve different problems.
How often should I re-verify?+
One test purchase after any change to checkout, theme, apps, or tracking plugins — and a monthly 30-second glance at the dedup rate. Every broken setup we see was 'verified once' before an update quietly changed the cast of senders.

Clean events deserve clean accounts

Whitelisted infrastructure — stable, history-rich rails under your newly-honest signal.