Skip to content
All articles
6 min read

Facebook CAPI Deduplication: event_id, Pixel and Server Events

Browser and server event signals meet at one guarded event identity before entering an attribution ledger

Facebook CAPI deduplication prevents one real conversion from being counted twice when the browser Pixel and the server-side Conversions API both report it. The core contract is simple: the browser and server copies of the same event need the same event name and the same event_id.

The implementation becomes difficult when teams confuse four separate identities:

  • fbclid / fbc: Meta click context;
  • fbp: browser context;
  • internal click_id: your tracker’s visit key;
  • event_id: the identity of one conversion event sent through two channels.

They should be connected in one click record, but they should not be collapsed into one generic ID.

What deduplication does—and does not do

ProblemCorrect mechanism
Pixel and CAPI send the same PurchaseMatching event name + matching event_id
A network retries one postbackStable network transaction ID / tracker idempotency
Registration and deposit happen on one clickDifferent event types and usually different event IDs
Meta must match the event to an ad clickfbc/fbclid, fbp and other permitted match keys
Tracker must attach revenue to a visitInternal click ID returned in the postback

Meta’s official deduplication documentation should remain the source of truth for the current API contract. Operationally, do not use match keys as a substitute for event identity.

A correct browser and server pair

Browser Pixel example:

<script>
fbq("track", "Purchase", {
  value: 42.50,
  currency: "USD"
}, {
  eventID: "purchase_conv_98211"
});
</script>

Server CAPI event for the same purchase:

{
  "event_name": "Purchase",
  "event_time": 1786957000,
  "event_id": "purchase_conv_98211",
  "action_source": "website",
  "custom_data": {
    "value": 42.50,
    "currency": "USD"
  }
}

The browser SDK spells the option eventID; the Conversions API payload uses event_id. The values must match exactly for the same business event.

How to generate event IDs

An event ID needs two properties:

  1. stable for retries or multiple delivery copies of one event;
  2. unique across different business events.

A network conversion ID is often the best seed because it already identifies the transaction:

Purchase:network_conv_98211

If no transaction ID exists, generate the ID once at the event source, persist it with the conversion record and reuse it for both browser and server delivery. Do not let the browser and server independently generate random IDs after the event occurs.

Avoid these patterns:

  • one event_id per user for their entire lifetime;
  • one event_id equal to the campaign ID;
  • timestamp-only IDs created independently on browser and server;
  • using the internal click ID for registration, deposit and every later purchase without an event-specific suffix.

Event name must match too

Matching IDs do not repair a semantic mismatch such as:

browser: Purchase / purchase_conv_98211
server:  Lead     / purchase_conv_98211

Define one conversion registry before implementation. Decide which raw postback status becomes Lead, CompleteRegistration, Purchase or a custom event, and use the same mapping on every delivery path.

If browser and server are intentionally reporting different funnel moments, they should not be deduplicated. Give them different event names and IDs.

Where fbclid, fbc and fbp fit

fbclid is appended to a landing URL after a Meta click when available. Integrations can preserve it and construct the expected fbc click context for server-side delivery. fbp carries browser context.

These values help Meta match the server event to an ad interaction. They do not tell Meta whether the browser and server payloads are duplicates. That is the job of the shared event identity.

Keep the model explicit:

click_id → our exact visit
fbc/fbp  → Meta matching context
event_id → one conversion delivered through one or more channels
tx_id    → one partner/business transaction

The Click ID vs Sub ID guide maps these identifiers in more detail.

The postback-to-CAPI boundary

In affiliate traffic, the decisive conversion often happens on the advertiser or network side. The browser may never see the deposit. A postback returns the event to the tracker:

https://tracker.example/postback?click_id={aff_sub}&status=deposit&payout={payout}&transaction_id={conversion_id}

Only after the tracker validates the click, status and transaction should it construct the server event for Meta. This order prevents an unknown or duplicate callback from becoming a false advertising signal.

Read how affiliate conversions return to Facebook for the complete delayed-conversion path and Pixel vs CAPI vs postback for the ownership boundary.

Pass/fail verification table

TestPass condition
Browser payloadCorrect event name and a non-empty event ID are visible
Server payloadSame business event uses the same name and exact ID
Event dataValue and currency agree across duplicate copies
Click contextfbc/fbp are present when legitimately captured
Tracker eventServer event originates from a known conversion and click
Partner retrySame transaction does not create another tracker conversion
Meta diagnosticsEvent is accepted and not reported as an unresolved duplicate
Final countOne business conversion remains one counted Meta event

Do not sign off from Ads Manager totals alone. Use a controlled event whose browser payload, server request, platform response and tracker conversion can all be inspected.

Common failure modes

Same event, different IDs

Pixel and CAPI both count because each channel generated its own identifier. Generate once and transport the value.

Same ID, different event names

One copy is Purchase, the other CompleteRegistration. Fix the event registry, not the identifier.

One click ID reused as every event ID

Real repeat purchases can collapse or diagnostics become ambiguous. Add transaction or event scope.

CAPI fires before the postback is validated

An unknown click, unmapped status or partner retry reaches Meta as a real conversion. Validate and deduplicate at the tracker boundary first.

Match quality is confused with deduplication

Good fbc, fbp, IP, user agent or permitted hashed customer data can improve matching, but duplicate copies still need coordinated event identity.

Durable implementation rule

Model the business conversion first, then deliver it:

validated conversion record
├── browser Pixel copy (when applicable)
└── server CAPI copy

Both copies reference the same event record and therefore share one identity. This design is easier to test than trying to infer duplicates after two independent pipelines have already fired.

  • facebook capi deduplication
  • facebook conversions api deduplication
  • meta event id
  • pixel and capi
  • event_id