Most. Help

Facebook Pixel and CAPI Event Deduplication: How to Fix Double-Counted Conversions

Published Sep 13, 20268 min readIntermediate
Hand-drawn bridge where two identical paper planes merge into one marked with an orange check, symbolizing event deduplication
What you'll learn
  • What the setup changes in server-side conversion tracking
  • Which identifiers, tokens, and event fields must match
  • How to verify the setup before handing it to automation
Intermediate

Facebook Pixel and CAPI Event Deduplication: How to Fix Double-Counted Conversions

event_id

Related setup guides: event_id and deduplication, pixel warming, Facebook CAPI through Keitaro. Running Meta Pixel and Conversions API (CAPI) side by side gives you better data resilience. But without proper deduplication, every conversion gets counted twice. Your ROAS looks inflated, your optimization signals get noisy, and budget decisions rest on phantom numbers.

This guide walks through exactly how Meta deduplicates events, what breaks the process, and how to verify your setup in Events Manager.

Why Double-Counting Happens

Pixel fires from the browser. CAPI fires from your server. When both send the same event (say, a Purchase) without a shared identifier, Meta sees two independent conversions. The result:

  • Conversion counts roughly 2x reality
  • Cost per acquisition appears halved
  • Ad optimization feeds on duplicate signals

Meta expects a redundant setup. The platform provides a deduplication layer, but it only activates when you pass matching parameters on both sides.

How Meta Deduplication Works

Meta compares incoming events and merges duplicates using two methods.

Primary method: event_id + event_name

The browser Pixel sends eventID and event. The server CAPI sends event_id and event_name. When both values match between the two sources, Meta keeps one event and discards the duplicate.

Parameter (Browser)Parameter (Server)Purpose
eventIDevent_idUnique identifier for the event instance
eventevent_nameThe action type (Purchase, Lead, etc.)

Both fields must match. A mismatch in either one prevents deduplication.

Secondary method: event_name + user identifier

If you cannot share a unique event ID, Meta can also match on event_name combined with fbp (browser ID) or external_id (hashed user identifier). This fallback is less reliable:

  • It fails when the server event arrives before the browser event.
  • Consecutive events from a single source are not deduplicated against each other.

Use the primary method whenever possible.

The 48-hour window

Deduplication only applies within a 48-hour window. If the server event arrives more than 48 hours after the browser event (or vice versa), both are kept. Send server events in near real-time to stay inside this window.

Step-by-Step Fix

1. Generate a unique event ID on the client

Create a UUID at the moment the action occurs. Store it in your data layer so both tags can read it.

javascript
const eventId = crypto.randomUUID();
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ event: 'purchase', eventId: eventId });

2. Pass the ID to Pixel

javascript
fbq('track', 'Purchase', {
  value: 49.99,
  currency: 'USD'
}, { eventID: eventId });

3. Pass the same ID to CAPI

In your server payload, include the identical value:

json
{
  "event_name": "Purchase",
  "event_time": 1721650000,
  "event_id": "<same-uuid-from-step-1>",
  "user_data": { "fbp": "fb.1.1721650000.123456" },
  "custom_data": { "value": 49.99, "currency": "USD" }
}

4. Keep event_name case-consistent

Matching is case-sensitive. Purchase and purchase are different events to the deduplication engine. Pick one casing convention and enforce it across Pixel and CAPI.

5. Send server events promptly

Aim for under 1 minute of latency. Batched or delayed server calls risk falling outside the 48-hour window or degrading attribution quality.

Common Mistakes

MistakeSymptomFix
Missing event_id on one sideDedup rate near 0% in Events ManagerPass the same UUID to both Pixel and CAPI
Case mismatch in event namePartial dedup, some events slip throughStandardize casing in your tag config
Server event sent hours lateDedup works intermittentlyMove CAPI calls to a real-time queue
Different fbp valuesSecondary method failsForward the browser fbp cookie to the server
Hardcoded event IDsAll events collapse into oneGenerate a fresh UUID per event instance

Verifying in Events Manager

  1. Open Events Manager and select your data source.
  2. Go to the Overview tab and find the Deduplication card.
  3. Check the deduplication rate. A healthy Pixel + CAPI setup shows 80-95% for high-frequency events like PageView and Purchase.
  4. If the rate is below 50%, inspect recent events in the Test Events tab. Look for mismatched or missing event_id values.
  5. Use the Payload view to confirm both browser and server events carry identical event_id and event_name fields.

A deduplication rate of 0% almost always means event_id is not being passed at all.

Troubleshooting Checklist

  • Confirm event_id is present in both the Pixel eventID parameter and the CAPI event_id field.
  • Verify the values are identical strings (no extra whitespace, no type coercion).
  • Check that event_name / event uses the same casing on both sides.
  • Ensure server events arrive within 48 hours of the corresponding browser event.
  • If using the secondary method, confirm fbp or external_id is consistent between sources.
  • Review the Events Manager diagnostics tab for warnings about duplicate or unpaired events.

What Happens to Non-Deduplicated Events

When Meta receives two similar events it cannot match, it generally prefers the event received first. The second event still counts toward your totals. This is why your conversion numbers appear inflated rather than simply wrong in one direction.

Key Takeaways

  • Always pass a shared event_id (UUID) from client to both Pixel and CAPI.
  • Keep event_name casing identical across sources.
  • Send server events in real-time to stay within the 48-hour dedup window.
  • Monitor the deduplication rate in Events Manager weekly.
  • A rate below 80% signals a configuration problem worth investigating.

Track your ad funnels and conversion events in one place with MOST. If you need a free manual check before automation, use Pixel Activator to activate and inspect your pixel flow.

Frequently asked questions

Sources

Sources

Was this guide helpful?
Author
Most Team
Справочная служба

Официальные руководства и глоссарий для платформы Most и Активатора пикселей.

Topic
Meta Conversions API: The Complete Guide
Main article of the topic
Related articles

Related guides

Meta Conversions API: The Complete Guide

A single entry point into the Meta Conversions API cluster: what the API does, which credentials and parameters a working event needs, how deduplication and validation fit together, and where each specific failure - a late event, a double count, an error code - has its own deep-dive guide.

10 min

Meta CAPI Batching and Rate Limits: The Delivery Rules

The Conversions API accepts several events in one request - and one bad event can fail the whole batch. This guide covers the documented batching structure, the acceptance rules that decide whether a request survives, what a rejected batch means for retry logic, and the delivery discipline that keeps a busy funnel inside the platform's limits without guessing at undocumented numbers.

6 min

Lead Ads CRM CAPI: Closing the Lead Loop in Meta

A Lead Ads form fills your CRM; the lead that actually buys is the one worth telling Meta about. This guide wires the loop: from the form's instant delivery into your CRM, through confirmation and hashing, to a documented CAPI lead event - with dedup and the seven-day window deciding how late a confirmed lead can still count.

6 min

Limited Data Use Meta: data_processing_options in Server Events

Meta's Limited Data Use flag exists so your server events can carry a US state-privacy signal - and it is three documented fields inside each event. This guide explains what data_processing_options does, the exact LDU values and country and state codes, the empty-array semantics most setups miss, and when sending the flag is the right call.

5 min