Meta Pixel + Conversion API: deduplication done right
The event_id pattern that stops Meta double-counting when you run pixel and CAPI together — plus how to verify match quality.
Running the Meta Pixel and the Conversion API together is the recommended setup — browser events for coverage, server events for resilience. Run them together without deduplication and every conversion counts twice, your CPA halves overnight, and someone scales a budget based on fiction.
How deduplication works
Meta deduplicates when two events share the same event_name and the same event_id. Generate the ID once, send it down both paths.
Browser side:
const eventId = crypto.randomUUID();
fbq('track', 'Purchase',
{ value: 128.40, currency: 'GBP' },
{ eventID: eventId } // note the capital ID in the pixel API
);
window.dataLayer.push({ event: 'purchase', meta_event_id: eventId });
Server side (via server GTM or direct CAPI call):
{
"event_name": "Purchase",
"event_id": "same-uuid-as-the-pixel",
"event_time": 1739786400,
"action_source": "website",
"user_data": {
"em": ["<sha256 of lowercased email>"],
"client_ip_address": "…",
"client_user_agent": "…"
},
"custom_data": { "value": 128.40, "currency": "GBP" }
}
For purchases specifically, the order ID makes a better event_id than a UUID — it's naturally unique and lets you deduplicate retries too.
Match quality: the metric that pays the bills
CAPI's real value is sending hashed first-party identifiers (email, phone) that the browser pixel increasingly can't. In Events Manager, watch Event Match Quality per event:
- Below 5: you're sending events Meta can't tie to people — optimisation barely benefits.
- 6–7: typical decent implementation.
- 8+: where the CPA improvements clients actually feel.
The fastest EMQ wins: hashed email on every logged-in or post-purchase event, phone number where you legitimately hold it, and fbp/fbc cookies forwarded from the browser.
Verification checklist
- Events Manager → your event → check "Deduplicated" badge shows both Browser and Server bars.
- Total purchases in Meta ≈ real orders (within attribution-window tolerance) — not 2x.
- Test with the Payload Helper before shipping, then re-test after any checkout deploy.
- Alert if the server:browser event ratio drifts sharply — it means one path broke.
Deduplication is thirty minutes of work when designed in, and a month of forensic archaeology when bolted on. Design it in.