Fix Facebook CAPI Deduplication: Stop Duplicate Events (2026)
Last Updated: July 12, 2026Question: How do you fix duplicate tracking errors in Meta Ads?
Quick Answer: To fix Facebook CAPI deduplication, pass an identical event_id and an identically-cased event_name from both your browser pixel and your server-side webhook, within a 48-hour window. When Meta receives a matching pair from both sources, it discards the redundant browser payload and records a single, accurate conversion.
Already know you need this fixed and don’t want to hand-build the payload logic? Start with Make.com — it’s the engine every example on this page runs on.
Prefer a visual breakdown?
If you need a full understanding of exactly how the dual tracking trap inflates your ROAS, and how to map the event_id to verify your payloads, watch the architectural teardown from CreatorOpsMatrix below.

The ROAS Lie: Why Duplicate Events Kill Campaigns
After debugging broken backend setups for scaling agencies, the diagnosis is consistent: if your Facebook CAPI deduplication is broken, your ROAS is unreliable. You might look at Ads Manager and see a highly profitable campaign, but you are scaling spend based on duplicated conversions. When you double-count purchases, the algorithm optimises against corrupted signals and actively erodes your real margins while reporting fictional returns.
The root cause is almost always the same. When operators migrate to server-side tracking, standard practice dictates running dual tracking — firing the Meta Pixel from the browser while simultaneously firing a server-side webhook from the payment processor. This redundancy is correct architecture. It ensures conversions are recorded even when ad blockers strip the browser pixel. The problem is that executing dual tracking without proper event_id matching gives Meta two separate signals for the same purchase, which it counts as two conversions.
The financial consequence is not just reporting inaccuracy. Meta’s algorithm uses conversion data to optimise ad delivery toward audiences most likely to convert. When your conversion data is doubled, the algorithm learns from a distorted dataset — it over-bids on audiences and creative combinations based on inflated performance signals. Campaigns that appear to be performing at 4x ROAS may be running at 2x in reality. The deduplication error corrupts the optimisation loop, not just the dashboard numbers.
Do not turn off the browser pixel: The pixel captures real-time behavioural signals — button clicks, scroll depth, add-to-cart events — that server-side tracking cannot observe. CAPI is the failsafe that guarantees conversion recording when the pixel is blocked. Both are required. Proper event_id matching is what prevents the double count, not disabling one of the two streams.
The Core Mechanism: How event_id Deduplication Works
According to Meta’s official Conversions API deduplication documentation, the Graph API relies on a primary matching variable called the event_id. When both the browser pixel payload and the server-side CAPI payload carry an identical event_id string, Meta’s deduplication engine recognises them as the same event and discards the redundant signal, recording a single accurate conversion.
Without an explicit event_id in both payloads, Meta falls back to attempting deduplication via fbc and fbp cookie parameters combined with IP address matching. This fallback is unreliable — it fails entirely for users on VPNs, users who have cleared cookies, users in cross-device journeys, and users whose browsers block first-party cookie storage. The event_id is the only deterministic deduplication signal.
The Two Rules Most Setups Get Wrong
There are exactly two conditions Meta checks, and both have to pass. Most broken setups pass one and silently fail the other.
- The event_id string must match byte-for-byte. A trailing space, a different casing convention, or a truncated string breaks the match with no error thrown — the events simply never merge.
- The event_name must match exactly, including capitalization. A Pixel event fired as
Purchasewill not deduplicate against a CAPI event sent aspurchase. Meta treats these as two distinct event types, so even a perfectevent_idmatch will not save you if the names don’t agree.
Both events also have to land inside Meta’s 48-hour deduplication window. If your server-side event fires more than 48 hours after the browser event carrying the same event_id, Meta no longer merges them — both get counted. In practice this only bites you on delayed-fulfillment flows (offline sales synced later, backorder confirmations), but it’s worth checking if your CAPI events are queued rather than sent in real time.
Implementation: The Exact Code for event_id Matching
The event_id must be generated once per conversion event and passed to both the browser pixel and the server-side API payload simultaneously. The value can be any unique string — a transaction ID from your payment processor, a UUID generated at checkout initiation, or a timestamp-based hash. The only requirement is that both payloads carry the exact same string with no variation in casing or formatting, and the same event_name.
1. The Browser Pixel Payload (JavaScript)
fbq('track', 'Purchase', {
value: 100.00,
currency: 'USD'
}, {
eventID: 'txn_12345'
});2. The Server-Side CAPI Payload (JSON)
{
"data": [
{
"event_name": "Purchase",
"event_time": 1715000000,
"action_source": "website",
"event_id": "txn_12345",
"user_data": {
"em": ["HASHED_EMAIL_SHA256"],
"ph": ["HASHED_PHONE_SHA256"],
"fbc": "fb.1.1715000000.AbCdEfGhIjKlMnOp",
"fbp": "fb.1.1714000000.1234567890"
},
"custom_data": {
"value": 100.00,
"currency": "USD"
}
}
]
}Note that event_name is "Purchase" in both payloads above, matching the Pixel’s 'Purchase' string exactly. This is the detail that breaks silently. The server payload also includes the user_data object with hashed email and phone fields, required for Event Match Quality scoring — see the full EMQ optimisation guide for the correct SHA-256 normalisation sequence. The fbc and fbp parameters come from the browser cookies set by the Meta pixel and should also be passed server-side when available to maximise match rates.
What Event_id Values Are Valid
| Source | Example Value | Notes |
|---|---|---|
| Stripe Charge ID | ch_3Pxxxxxxxxxxxxx | Unique per transaction, available in webhook payload |
| UUID v4 | f47ac10b-58cc-4372-a567 | Generate at checkout initiation, store in session |
| Timestamp + User ID hash | 1715000000_usr_8821 | Deterministic, reproducible from server logs |
| Order Number | order_20260508_4421 | Only valid if orders are never duplicated in your system |
Diagnosing 0% Event Coverage
Operators implementing dual tracking frequently check their Events Manager after deployment and find a 0% Event Coverage warning next to their Purchase event. This warning has a specific meaning: Meta is receiving your server-side CAPI events but cannot find any browser pixel events to match them against. The server stream is working. The browser stream is broken, absent, or firing against stale data.
The standard engineering causes of 0% event coverage are:
- Asynchronous Loading Conflict: If your pixel loads via Google Tag Manager and the
event_idis generated by a separate script, the pixel may fire before the ID is available, sending a nulleventIDvalue to Meta. The pixel fires successfully but without a deduplication key, making it impossible for Meta to match it to the server event. - Performance Plugin Deferral: WordPress optimisation plugins routinely defer JavaScript execution to improve page load scores. If they defer your Meta pixel script, the browser event fires after the user has already left the purchase confirmation page, or does not fire at all.
- Stale Server Cache: If you enable CAPI on a live site without purging the server-side page cache, cached checkout confirmation pages keep serving the pre-CAPI pixel snippet. The server sends events correctly; the browser is silently running outdated code. Clearing the full-page cache after any CAPI configuration change resolves this immediately.
- Hosted Payment Gateway: If your checkout redirects to a third-party payment page and the user does not return to a confirmed Thank You page on your domain, the pixel has no page environment to fire in. The server catches the payment webhook but no browser event is recorded.
- Ad Blocker Rate: In audiences with high technical literacy — developers, SaaS operators, security professionals — ad blocker penetration can exceed 40%. If your audience skews technical, a meaningful percentage of browser events will never fire regardless of implementation quality, resulting in a non-zero but below-par coverage score.
Use the Test Server Events Tool First
Do not wait for live traffic to verify your deduplication setup. Open Meta Events Manager, navigate to your pixel, click Test Events, and trigger a live purchase using a Stripe test card. Verify that the server event indicator appears alongside the browser event indicator with the exact same event_id string and event_name, and that the total event count shows 1 — not 2. This single verification step confirms deduplication is functioning before you scale spend.
Debugging this by hand eats hours you don’t have. The webhook catcher, PII hashing, and event_id/event_name matching logic are already built and tested in production.
Recommended CAPI Stack for 2026
To avoid building custom API routing from scratch and risking implementation errors that break deduplication silently, standardise your execution stack across these three layers. The combination covers pixel firing, server-side routing, and managed attribution without redundant tooling.
- Make.com: The primary logic engine for catching Stripe or Shopify payment webhooks, extracting the transaction ID as the
event_id, normalising and hashing customer PII, and routing the structured JSON payload to the Meta Graph API endpoint. - GTM Server-Side: For operators requiring Google Analytics 4 event routing alongside Meta, a server-side GTM container allows a single server-side tag to distribute event data to multiple ad platforms without duplicate frontend pixel implementations.
- Managed Attribution: If your team lacks the engineering bandwidth to maintain custom webhook routing, a managed attribution platform handles the server-side connection automatically. Review the Hyros alternative guide for a cost comparison between managed and self-built attribution infrastructure.
After Deduplication: Low EMQ Scores
Fixing deduplication resolves the double-counting problem but does not automatically improve Event Match Quality. EMQ scores measure how well Meta can match your server-side events to real Facebook user profiles. A score below 6.0 out of 10.0 means a significant proportion of your server events are landing without being attributed to a known user — reducing the optimisation value of the server-side data.
Low EMQ after fixing deduplication almost always indicates a PII normalisation error. Email addresses passed to the Meta API must be lowercased and stripped of whitespace before SHA-256 hashing. Phone numbers must include the country code prefix and contain only digits. If your Make.com scenario is hashing raw email values without normalising them first, the hashes will not match Meta’s stored user data even when the underlying email address is correct. The full normalisation and hashing sequence is documented in the Facebook CAPI match quality optimisation guide.
Related Attribution Guides
Frequently Asked Questions
Duplicate tracking errors occur when you send data from both the browser pixel and the Conversions API without a matching event_id and event_name in both payloads. Without both matching, Meta has no way to recognise that both signals represent the same conversion event and counts each one independently, inflating your reported purchase volume and corrupting your ROAS data.
A 0% event coverage warning means Meta is receiving your server-side CAPI events but cannot find any corresponding browser pixel events to match against. The server stream is working correctly. The browser pixel is either misconfigured, deferred by a performance plugin, blocked by an ad blocker, serving from a stale server cache, or has no page environment to fire in due to a hosted payment gateway redirect.
Meta’s deduplication window for matching Pixel and CAPI events is 48 hours. If the server-side event for a given event_id fires more than 48 hours after the browser event, Meta will not merge them and both get counted. Server-side events should fire within seconds of the browser event whenever possible.
Yes, and this is the most common silent failure. Meta treats event_name as case-sensitive. A Pixel event named Purchase will not deduplicate against a CAPI event named purchase, even with an identical event_id. Both values must match character-for-character.
The event_id is a unique string generated at the moment of conversion — typically a transaction ID, UUID, or order number. Both the browser pixel payload and the server CAPI payload carry this same string, alongside a matching event_name. When Meta’s deduplication engine receives two events with identical values on both fields within the 48-hour window, it merges them into a single conversion and discards the redundant signal.
Meta attempts to match events using fbc and fbp cookie parameters and IP address signals when event_id is absent. This fallback fails for VPN users, users with cleared cookies, cross-device journeys, and browsers that block first-party cookie storage. Explicitly passing a matching event_id is the only deterministic method to prevent duplicate conversion counting across all user scenarios.
Meta’s deduplication engine processes events in near real-time as they arrive at the Graph API endpoint. The Events Manager dashboard, however, operates on a reporting delay and can take 20 to 30 minutes to update the deduplication charts and event coverage metrics. Use the Test Events tool for immediate verification rather than waiting for the dashboard to refresh during implementation.
No. The browser pixel captures real-time behavioural data — page views, button clicks, add-to-cart events, scroll depth — that server-side tracking cannot observe because these signals occur in the browser before any server interaction happens. CAPI acts as the attribution failsafe that guarantees purchase conversion recording when the pixel is blocked. Running both with proper event_id and event_name matching is the correct architecture.
Low Event Match Quality after fixing deduplication indicates a PII normalisation error in your server payload. Email addresses must be lowercased and stripped of whitespace before SHA-256 hashing. Phone numbers must include the country code prefix and contain only digits with no spaces or formatting characters. If your Make.com scenario hashes raw values without normalising them first, the resulting hashes will not match Meta’s stored user data even when the underlying contact information is correct.
Automate Your CAPI Infrastructure
Stop debugging raw JSON payloads manually. Deploy the complete pre-built Make.com architecture that handles webhook catching, PII hashing, event_id/event_name matching, and Meta Graph API routing in one scenario.
Includes the exact scenario file used to build every example in this guide.