How to Deduplicate Meta Pixel and Conversions API (CAPI)
Learn the exact method for generating and passing event_ids to ensure Meta doesn't double-count your conversions when using both browser and server side tracking.
The Problem Frame
When you implement the Meta Conversions API (CAPI) alongside the browser pixel, you pass the exact same event (like a Purchase) twice. If you don't properly deduplicate these events, Meta's algorithm will count two purchases instead of one. This ruins your ROAS reporting, messes up the optimization algorithm, and causes you to overspend on campaigns erroneously.
Engineering The Solution
1. Create a Unique Event ID variable in GTM
Use a Custom JavaScript variable or a community template in Google Tag Manager to generate a unique hash for each event that occurs on the page. It must be unique per user action, not just per page load, especially for single-page applications.
2. Add the Event ID to the Browser Pixel Tag
In your Meta Pixel tag (usually the official template), find the 'More Settings' -> 'Event ID' field and map it to your new variable. Every time a standard or custom event fires, it will now carry this ID.
3. Pass the Event ID to the Server Container
If you're using GA4 data stream to transport data to the Server container, ensure you add a parameter (e.g. `event_identifier`) to your GA4 config or event tag. It must transmit over the network to the server.
4. Map the Event ID in the Server-Side CAPI Tag
Within the Server Container, intercept the request and map your `event_identifier` to the `event_id` field in the Meta CAPI tag. Now, both the browser payload and server payload arrive at Meta with matching IDs.
QA Checklist
Common Questions About This Approach
Deduplication itself shouldn't drop EMQ. However, if your server events lack user parameters (like email, phone) that the browser pixel had access to, Meta may prioritize the browser event, and flag the server event as low quality.
Meta always prioritizes the first event it processes (usually the browser pixel due to latency). If the IDs match perfectly, the second one is always dropped.