Most accounts now run both the browser pixel and the Conversions API. Two settings decide whether that helps or quietly corrupts your numbers: event deduplication and Event Match Quality. Here is what each one is, how they break, and how to check yours.
Running the pixel and the Conversions API together is the standard setup. Wired correctly it gives Meta a fuller picture of what happens on your site. Wired carelessly it reports every purchase twice, inflates your ROAS, and trains the optimization model on numbers that were never real. The difference between those two outcomes is a matching key and a handful of customer parameters.
The Meta pixel is JavaScript that runs in your visitor's browser. When someone views a product or completes a checkout, the pixel's fbq call sends an event from that browser to Meta, along with whatever the browser can see: the page URL, the referrer, the user agent, the IP address, and Meta's own first-party cookies. Two of those cookies matter more than the rest. _fbp is a browser identifier the pixel writes on first visit. _fbc stores the click ID from the fbclid parameter Meta appends to your ad's landing page URL. Those two are the cleanest link between a click on an ad and an action on your site.
The Conversions API, usually shortened to CAPI, sends the same events from your server to Meta's servers directly. There is no browser in the path. Your backend, your ecommerce platform, a server-side tag manager, or a partner integration authenticates with an access token and posts events to your dataset. Because the request originates from your infrastructure, it is not affected by anything happening in the visitor's browser.
Meta's guidance is to run both and send the same events through each channel. Meta calls this a redundant setup, and redundant is the point. Each channel sees things the other misses. The browser has the cookies and the live page context. The server has reliability, and it has data the browser never handles, such as an order confirmed by your payment processor minutes after the customer closed the tab, a refund, or a lead that only becomes qualified inside your CRM.
A browser-only setup is not broken. It is just partial, and the gap has grown every year.
_fbc left to match on.The server path is immune to all four. If you want the full inventory of what can break on the browser side, the Meta pixel audit guide walks the whole install layer by layer, and Shopify pixel setups have their own specific failure modes because so much of the tracking lives inside a sandbox.
If both channels send the same purchase, Meta has to recognize that they are one event, not two. That is deduplication, and it runs on a simple rule: two events are duplicates when the event name matches and the event ID matches.
In the browser you pass the ID as eventID in the fbq call. On the server you pass the same value as event_id in the payload. The name has to match too, so a browser Purchase pairs with a server Purchase. When Meta receives the pair, it keeps one and drops the other.
The ID must be the same string generated once per event, then shared between the two channels. A timestamp generated independently on each side will not match. Order IDs work well for purchases because both the page and the server already know them. Meta also supports deduplication using fbp plus external_id for some setups, but the event ID method is the explicit one, and it is the one you can verify.
Nothing errors. That is what makes this failure expensive. Meta receives two complete, valid events and counts both.
A partial failure is worse than a total one. If the event ID is present on most events but missing on some, you get a blend of accurate and doubled data with no clean way to correct the reporting after the fact.
Deduplication decides whether an event is counted once. Event Match Quality decides whether Meta can tie that event to a person. Events Manager shows it per event on a 0 to 10 scale, and it reflects how many valid customer information parameters you send and how usable they are for matching.
Matching is the whole mechanism behind attribution. If Meta cannot connect a purchase to an account that saw or clicked your ad, that purchase is not attributed to the campaign, and it does not feed optimization for that audience. More matched events means more attributed conversions and a better training signal.
| Parameter | What it is | Notes |
|---|---|---|
em | Email address | Usually the single strongest identifier you have. Hashed. |
ph | Phone number | Include the country code, digits only, no symbols. Hashed. |
fn, ln | First and last name | Weak alone, useful stacked with location. Hashed. |
ct, st, zp, country | City, state, zip, country | Available from any checkout with a shipping address. Hashed. |
external_id | Your own customer or user ID | Send the same value from both channels so returning customers link up. |
fbp | Browser ID from the _fbp cookie | Read it and pass it on the server event too. Not hashed. |
fbc | Click ID from fbclid, stored in _fbc | The most direct ad-to-conversion link. Not hashed. |
client_ip_address, client_user_agent | Visitor IP and browser string | Required on server events for reasonable matching. Not hashed. |
Personal identifiers are hashed with SHA-256 before they leave your systems, so Meta never receives a raw email or phone number. Normalization comes first and it is where most implementations lose points: trim whitespace, lowercase everything, strip formatting from phone numbers and keep the country code. Hash a string with a stray capital letter or trailing space and it will not match, even though the parameter looks present in your payload. The browser pixel handles this for you when Advanced Matching is enabled. On the server you are responsible for it. The technical identifiers, fbp, fbc, IP, and user agent, are sent unhashed.
First, send more parameters on the events that matter, particularly Purchase and Lead. A checkout already collects email, phone, name, and address. If your server event sends only a value and a currency, you are leaving matching on the table for no reason. Second, pass fbp and fbc from the browser into your server events. Server-side implementations frequently omit them, and they are the fields most directly tied to the ad click.
Everything below lives in Events Manager, takes about fifteen minutes, and requires no developer.
That sequence answers the two questions that matter: is anything being counted twice, and how much of what you send can actually be matched. Our measurement work runs the same checks on a fixed schedule, because tracking does not break on a schedule that suits anyone.
If you want the site side checked before you open Events Manager, our free Meta pixel audit scans your URL in about 20 seconds and reports what is verifiable from outside: whether a pixel is installed and valid, whether the same ID is installed twice across layers, which standard events are wired, whether Purchase carries value and currency, whether Advanced Matching is enabled, whether server-side infrastructure is present, and whether your conversion events carry the eventID keys deduplication depends on. No login and no email.
The scan is explicit about what it cannot see from outside: your Event Match Quality scores and your actual deduplication rates live in Events Manager, not on your website, so it marks the server-side items it detects as needs verification instead of guessing. We document that boundary in full on the audit methodology page. The scan tells you whether the plumbing is there. Events Manager tells you whether it is working.
Meta's own guidance is to run both and send the same events through each channel, which it calls a redundant setup. The browser pixel captures signals only the browser has, such as the _fbp and _fbc cookies and the full client context. The Conversions API sends the same events from your server, where ad blockers and browser privacy rules cannot reach. Running both, with deduplication configured, gives Meta more complete coverage than either one alone.
Open Events Manager, select your dataset, and look at the event detail view. For each event you can see how many were received from the browser, how many from the server, and how many were removed as duplicates. If both channels are clearly firing and a substantial share of events is being deduplicated, the match is working. If the deduplicated count sits near zero while both channels report volume, your event_id values are not lining up and the same conversion is being counted twice.
Events Manager shows Event Match Quality on a 0 to 10 scale per event, and higher is better. Meta does not publish a universal pass mark, and the realistic ceiling depends on how much customer information your funnel legitimately collects. The useful approach is to treat your current score as the baseline, send more valid parameters, and watch the number move. Compare each event against its own history rather than against a benchmark someone invented.
No. Server-only setups lose the browser-side identifiers that improve matching, in particular the _fbp browser ID cookie and the _fbc click ID cookie derived from the fbclid parameter on the ad landing page. The pixel also powers standard website custom audiences and catalog features. Remove the pixel and you usually lose match quality and audience building at the same time. Keep the pixel, add the Conversions API, deduplicate the overlap.
It helps, and it does not undo App Tracking Transparency. The Conversions API gets events to Meta that a browser might block or truncate, which improves the raw signal. Attribution limits still apply: Aggregated Event Measurement caps a domain to eight prioritized conversion events, opted-out users are measured through modeling, and some conversions never resolve to a person. Expect a better and more stable signal, not a return to pre-2021 reporting.
Duplicate purchases and weak match quality are silent problems: nothing errors, the numbers just stop being true. Scan your site free in about 20 seconds, or book a call and we will open Events Manager together.