Facebook Conversions API Setup: A Practical Walkthrough
What actually needs to be configured to get Conversions API working alongside your pixel, and the deduplication mistakes that silently inflate your reported conversions.
The Conversions API isn’t a replacement for the Meta pixel — it’s a second, more reliable delivery path for the same events, and most setup guides skip the part that actually determines whether it helps or hurts: deduplication. Get that wrong and you’ll see conversion counts that look better in Ads Manager while your actual reported revenue drifts further from reality.
Why CAPI Exists At All
Browser-based pixel tracking depends on a script executing client-side, which means it’s subject to ad blockers, Safari’s Intelligent Tracking Prevention, Firefox’s Enhanced Tracking Protection, and any cookie-consent banner that blocks scripts before a user accepts. Depending on your traffic mix, that can mean 15-35% of real conversions never fire a pixel event at all. The Conversions API sends the same event data from your server directly to Meta, bypassing the browser entirely, which means it isn’t affected by ad blockers or browser privacy settings.
The catch is that server-side events need enough matching data — email, phone, external ID, IP, user agent — for Meta to attribute them to the right ad, campaign, and user. A server event with no matchable identifiers is nearly worthless; it tells Meta a purchase happened somewhere, but not which ad drove it.
The Deduplication Problem
If you run both pixel and CAPI and send the same purchase event twice without deduplication, Meta will often count it as two separate conversions, inflating your reported numbers and making every campaign look more efficient than it is. This is the single most common CAPI mistake, and it’s dangerous precisely because it doesn’t throw an error — your dashboards just quietly get worse.
The fix is an event_id parameter sent identically from both the browser pixel and the server-side CAPI call for the same conversion event. Meta uses this shared ID to recognize the two events as one and only count it once. Your event_id needs to be generated at the point of conversion (an order ID works well for purchases) and passed to both your pixel fire and your CAPI payload — not generated independently on each side, which defeats the purpose entirely.
After implementing this, check Events Manager’s deduplication report, which shows how many events were matched between the two sources. If that number is near zero after a proper implementation, something is broken in how the event_id is being generated or passed — go back and log the actual values sent from both sides for a sample of ten real transactions before assuming the integration works.
A Worked Example of How Duplication Distorts Reporting
Say a store does 400 real purchases in a week, and every one of them fires both a browser pixel event and a server-side CAPI event with no shared event_id. Ads Manager doesn’t see 400 duplicated purchases — it sees somewhere between 400 and 800, depending on how many of those sessions had the browser pixel blocked or delayed, since only the sessions where both events actually landed get double-counted. If 70% of sessions successfully fire both events, that’s 280 purchases counted twice (560) plus 120 counted once, for a reported total of 680 purchases against 400 real ones — a 70% inflation that shows up nowhere as an error, just as an unusually strong week.
The campaign’s reported cost per purchase drops accordingly, from a real $34 down to a reported $20, and if budget decisions get made off that number, spend shifts toward a campaign that looks 41% more efficient than it actually is. The account team celebrates the “improvement,” reallocates budget away from a genuinely better-performing campaign that happened to have cleaner tracking, and the mistake compounds every week it goes unnoticed. This is why the dedup report in Events Manager isn’t an optional health check — it’s the one number that tells you whether every other number in the account is trustworthy.
Setting Up the Server-Side Call
You have three practical paths: build the server call yourself against Meta’s Graph API, use a Meta-approved partner integration if you’re on Shopify or a similar platform, or route events through a server-side tag manager like GTM’s server container. For most teams under 50,000 monthly conversions, a native platform integration or GTM server container is the better time investment — hand-building against the raw API means you own webhook reliability, retries, and payload formatting yourself.
Whichever path you choose, the payload for a purchase event needs, at minimum: event_name (“Purchase”), event_time (Unix timestamp of the actual transaction, not when the API call fires), event_id (matching your pixel), a value and currency, and as many hashed user identifiers as you can legally and practically collect — hashed email, hashed phone, client IP address, and user agent string. Meta requires email and phone to be SHA-256 hashed before transmission; sending them in plaintext will cause the event to be rejected.
Common Edge Cases That Break a Clean Setup
A handful of scenarios don’t fit the standard purchase-event flow and cause more support tickets than everything else combined. Refunds and order edits are the first: if a customer’s order value changes after the initial Purchase event has already been sent and matched, you need a separate mechanism (either a corrected event or an offline conversions adjustment) to keep the reported revenue from silently overstating actual revenue — most teams miss this entirely and only notice when finance’s revenue reconciliation doesn’t match ad platform revenue reporting months later.
Guest checkout is the second: if a customer never creates an account or logs in, your server may not have their email or phone available at the moment the order confirmation webhook fires, which caps EMQ for that transaction regardless of how well the rest of your setup works. Collecting email at the point of checkout initiation, rather than only at order completion, closes most of this gap.
Multi-currency and subscription businesses are the third edge case: a subscription renewal charge is a real conversion event but often isn’t routed through the same order-confirmation code path as an initial purchase, so teams that implement CAPI against the checkout flow alone quietly miss every renewal. If recurring revenue matters to your business, audit specifically whether renewal, upgrade, and downgrade events are wired into the same CAPI pipeline as new purchases — in most implementations they aren’t, by default, because they fire from a different part of the codebase (a billing webhook rather than a checkout controller).
Event Match Quality Is the Number That Actually Matters
Events Manager shows an Event Match Quality (EMQ) score for your CAPI events, typically on a scale that treats 6+ as reasonable and 8+ as strong. This number reflects how much matchable data Meta received, not whether the event fired successfully — a technically successful CAPI call with only an IP address and user agent will still show a low EMQ and won’t meaningfully improve attribution.
Push for at least email and phone whenever you legally can, since those are the strongest matching signals and the ones users are least likely to change across sessions or devices. If your checkout doesn’t collect phone number, that’s worth revisiting as a growth lever separate from ad tracking — it also improves SMS remarketing and shipping-carrier communication, so the ask has value beyond CAPI.
Test Events Before Going Live
Meta’s Test Events tool in Events Manager lets you send a live feed of events with a test event code attached, verifying in real time that your payload structure, hashing, and event_id matching are correct before they count toward your actual reporting. Skipping this step and debugging in production is the slow, expensive way to find integration bugs — you won’t know something’s broken until your numbers look off days later, by which point you’ve lost the ability to easily correlate the bad data to a specific fix.
Run at least one full test transaction through checkout with test event code active, and confirm in the tool that the event shows up with the fields you expect: correct value, correct currency, hashed parameters present, and — critically — that it matches to a corresponding pixel event under the same event_id. Then repeat that test transaction under the edge cases above: one guest checkout, one refund, and one subscription renewal if applicable, since a clean standard purchase test tells you nothing about whether those separate code paths are wired correctly.
What Changes in Reporting After a Correct Setup
Expect reported conversions to rise, sometimes 10-25% depending on your prior pixel-only match rate, but that increase should represent conversions that were happening anyway and simply weren’t being counted — not new conversions your ads are somehow causing. If you see a much larger jump, suspect duplication rather than celebrate the lift; go back and check the dedup report before adjusting budgets based on an artificially inflated conversion count.
This is also the point where cost-per-acquisition numbers inside Ads Manager will shift, sometimes significantly, since the algorithm now has more signal to optimize against. Give the algorithm’s learning phase at least a week of stable spend after a CAPI rollout before making budget decisions off the new numbers — Meta’s delivery system needs time to recalibrate to the improved signal, and judging performance during that recalibration window produces noisy, unreliable reads.
How to Verify the Setup Is Actually Working, Not Just Live
“Live” and “working correctly” are different states, and the gap between them is where most CAPI value gets lost. Three checks, run in this order, confirm the second: first, the dedup report should show a match rate close to 90-100% between pixel and CAPI events for standard purchases — anything meaningfully lower means event_ids aren’t lining up consistently. Second, the average EMQ score across your last 500 events should sit at 6 or above; pull the trend rather than a single day’s snapshot, since EMQ can look fine on a slow day and drop when guest checkouts or a traffic spike from a new source dilute the average.
Third, compare total CAPI-reported purchase count against your actual order-management system’s completed order count for the same week — they should be within a few percentage points of each other, not off by 20% or more in either direction. Under-reporting suggests some order types (refund adjustments, subscription renewals, a specific checkout variant) aren’t wired into the pipeline; over-reporting almost always means duplication has crept back in, often after a checkout redesign changed how or when the pixel fires relative to the server-side call.
Maintaining It Over Time
CAPI setups degrade silently when checkout platforms update, when a developer refactors the order confirmation flow, or when a consent-management platform update changes what data is available to hash. Put a recurring check on your calendar — monthly is reasonable — to pull the Event Match Quality trend line and the deduplication report, rather than assuming a working integration stays working. A drop in EMQ or dedup rate is an early warning that something changed upstream of your tracking, and catching it in week one is far cheaper than catching it after a quarter of degraded attribution data has already shaped your budget decisions.
The teams that get real value from CAPI treat it as ongoing infrastructure, not a one-time project. The setup itself is a few hours of work; the discipline to monitor match quality and deduplication rates every month is what keeps that setup actually paying off.
