Lesson 9 of 14
The Meta Pixel alone used to be the whole implementation. After iOS App Tracking Transparency and browser tracking-prevention started blocking or dropping it, the server-side Conversions API became the required complement — and the two now have to be deliberately deduplicated so the same purchase isn't counted twice.
13 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
The Meta Pixel is a browser-side snippet: it loads fbevents.js, calls fbq('init', '<pixel-id>'), and then fires standard events (PageView, ViewContent, AddToCart, Purchase) or custom ones as the visitor acts. For years this was the entire implementation — one snippet, done.
Two separate things broke that:
_fbp/_fbc cookies the Pixel uses, on every platform, not just iOS.Both together mean a meaningful, unpredictable slice of real conversions simply never reaches Meta from the browser alone — not because the purchase didn't happen, but because the client-side signal describing it got blocked, dropped, or expired before it could fire.
Conversions API (CAPI) is the fix: your own server sends the same events directly to Meta's servers, using data you already have first-party (the order that just completed, the email on the account) instead of relying on the browser to successfully deliver a client-side event. It doesn't replace the Pixel — a server-side event has no browser-side signals like scroll depth or on-page behavior, and Meta explicitly recommends running both together for the fullest picture.
event_idRunning Pixel and CAPI together creates an obvious new problem: if both successfully report the same purchase, Meta now sees it twice. The fix is a shared event_id on both the client and server event for the same real-world action — Meta matches on event_name + event_id and, within its deduplication window, keeps one and discards the duplicate.
<!-- Browser: Meta Pixel base code -->
<script>
!function(f,b,e,v,n,t,s){/* ... fbevents.js loader ... */}
(window, document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
</script>
// Browser: fire Purchase with an event_id the server will reuse
const eventId = crypto.randomUUID(); // generate once, pass to your order-confirmation handler
fbq('track', 'Purchase', { value: 49.99, currency: 'USD' }, { eventID: eventId });
// Server: send the same event_id via the Conversions API
await fetch(`https://graph.facebook.com/v21.0/YOUR_PIXEL_ID/events?access_token=${TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
data: [{
event_name: 'Purchase',
event_id: eventId, // must match the browser event exactly
event_time: Math.floor(Date.now() / 1000),
action_source: 'website',
user_data: { em: hashedEmail }, // first-party data, SHA-256 hashed before sending
custom_data: { value: 49.99, currency: 'USD' },
}],
}),
});
event_name + event_id together, not event_id alone — reusing an ID across different event types, or generating a fresh ID per side instead of sharing one, breaks it silently."Why isn't the Pixel alone enough anymore?" tests whether a candidate's ad-tracking knowledge is current or frozen at whatever they last touched before 2021 — the honest answer names ATT and browser tracking-prevention as two distinct causes of the same symptom, not a vague "privacy stuff." Following up with how event_id deduplication actually works shows you've implemented the fix, not just heard the term CAPI in a meeting.