Meta Conversions API vs pixel: deduplication, match quality and the system user token
By Matheus Mello, founder of Ads Editor and owner of YEP Agência · Published · 13 min read
The Meta Conversions API sends purchase and lead events from a server, without relying on the customer's browser. It does not replace the pixel: running both, with the same deduplication key and a well kept token for each client, is what lets Meta count correctly and optimize for real sales.
Quick answer
The Meta Conversions API sends events from your server and the pixel sends them from the browser. Run both with the same event_id so Meta counts each purchase once, send normalized email and phone hashed with SHA-256 to raise match quality, and generate the token with one system user per client, assigned only the pixel.
Summary
- The pixel measures in the browser; the Conversions API measures on the server, including sales that happen off the website.
- Meta recommends running both together, with deduplication: same event name and same event_id, within 48 hours.
- Event match quality (0 to 10) goes up when email, phone, name, IP and cookies are sent correctly.
- Email and phone go normalized and hashed with SHA-256; IP, user agent, fbp and fbc go unhashed.
- Agency token: one system user per client, standard role, only the pixel assigned, stored in a password vault.
What does the pixel measure and what does the Conversions API measure?
Both measure the same thing, what the customer does after seeing the ad, but through different paths. The pixel is a script that runs in the visitor's browser and sends the event from there. The Conversions API (CAPI) is your server, or your checkout platform's server, sending the event straight to Meta, without depending on the browser.
| Pixel | Conversions API | |
|---|---|---|
| Where it runs | In the visitor's browser | On the server (website, checkout, CRM) |
| What gets in the way | Ad blockers, cookie restrictions, a page closed before the script loads | A poor integration: events with no customer data, late or duplicated |
| What it knows | Page, click, the _fbp and _fbc cookies | Whatever your system knows: order, value, email, phone, payment status |
| Off-site events | Cannot see them | Sees them: sales over chat or phone, in a physical store, in the CRM |
| Effort | Paste the code or use the site platform's integration | Server integration, a partner or Meta's Gateway |
Meta itself describes the Conversions API as the connection between an advertiser's server, website, app or CRM data and Meta's ad systems, and it processes events received this way just like pixel events. In practice: the pixel sees behavior, the server sees facts. An order placed with a payment method that only confirms later, such as a bank transfer, is a purchase to the pixel; to the server it only becomes a purchase once the money arrives.
Why use both at the same time?
Because each one covers the other's blind spot, and Meta recommends exactly this setup, which it calls redundant: pixel and Conversions API sending the same events. When the browser blocks the pixel, the server still delivers the purchase. When the server integration does not have the click cookie, the pixel still carries the browsing context.
- Pixel only: misses the purchase from anyone using an ad blocker or closing the thank-you page before it loads, and counts orders that were never paid as sales.
- Server only: misses browsing behavior (page views, add to cart) if your backend does not know about it, and usually has fewer cookies to match the event to a person.
- Both, with deduplication: Meta receives the event through two paths and counts it once.
Both without deduplication is worse than one
If the pixel and the server send the same purchase without a shared key, Meta may count it twice. ROAS in Ads Manager goes up, optimization learns from a sale that never happened and the client report is wrong. The next section fixes this.
How does event_id deduplication work?
Meta merges two events when they reach the same pixel with the same event name and the same identifier: the pixel's eventID must match the server's event_id, and the pixel's event must match the API's event_name. According to the documentation, if the same combination arrives from the browser and the server within 48 hours, the later events are discarded.
On the pixel, the identifier goes in the fourth argument of the call:
fbq('track', 'Purchase', {value: 49.90, currency: 'USD'}, {eventID: 'order-48213'});
On the server, the same order-48213 goes in the event_id field of the Purchase event. Meta suggests using the order number or transaction ID when one exists. For events without a natural ID, such as a page view, a random number works, as long as it is the same on both sides, which in practice means generating it in the browser and passing it to the server.
What are the most common event_id mistakes?
- ID generated twice: the browser picks one, the server picks another. Nothing matches and everything is counted twice.
- Different event name:
Purchaseon the pixel andpurchaseorOrderon the server are not the same event. - ID reused across orders: using the product ID instead of the order ID makes Meta discard the second sale of the same product as if it were a copy.
- Server too late: once the 48 hour window has passed, the server event is no longer recognized as a duplicate.
There is an alternative method, based on fbp or external_id, but the documentation itself limits it: it only works when the browser event arrives first. If you control the code, use event_id.
What is event match quality (EMQ)?
It is the score, from 0 to 10, that Meta gives each server event, showing how well the customer data you sent helps link that event to a Meta account. It appears in Events Manager, in the details of each event, and currently applies to website events.
The logic is simple: Meta can only optimize for and attribute the purchase if it knows who bought. A purchase event with no email, no phone and no cookie is a loose number that teaches the algorithm nothing. Meta does not publish an official minimum score; the practical rule is to compare each event's score with the others in the same account and fix first the event the campaign optimizes for, usually the purchase or the lead.
Which user parameters raise the score?
Beyond the required fields, Meta lists email, IP, full name and phone as recommended. Here is what each one requires:
| Parameter | Field | SHA-256 hash? | Normalization before hashing |
|---|---|---|---|
em | Yes | No spaces, all lowercase | |
| Phone | ph | Yes | Digits only, with country code: 12125550147 |
| First and last name | fn, ln | Yes | Lowercase, no punctuation |
| City, state, zip, country | ct, st, zp, country | Yes | Lowercase; country as a 2 letter code (us) |
| Customer ID in your system | external_id | Recommended | The same value in every event |
| IP and browser | client_ip_address, client_user_agent | No | As they came in the request |
| Meta cookies | fbp, fbc | No | Read from the browser, in their original format |
Example: a US phone number
The customer typed (212) 555-0147 at checkout. Normalized, it becomes 12125550147: remove the parentheses, spaces and hyphen, and add the country code 1 in front. Only then do you apply SHA-256. Hashing "(212) 555-0147" produces a code that will never match anyone, and the event arrives with a useless phone number.
Two details lower the score without anyone noticing. First, do not hash IP, user agent, `fbp` or `fbc`: they go as they are. Second, fbp and fbc change; read them from the cookie at the time of the event, not from a value stored months ago. For a sale that arrives by webhook days later, store both with the order at checkout time.
Which fields can a website event not leave out?
event_name,event_timeanduser_datain every event.action_source, required:websitefor a site,business_messagingfor a conversation,physical_storefor a physical store, among others. Meta requires it to be accurate.event_source_url, required for website events: the URL where the action happened.event_timeno more than 7 days in the past. One old event in a batch makes Meta reject the whole batch, and the same goes for any invalid event in a batch of up to 1,000.
Meta recommends sending events as soon as they happen, ideally within one hour. To test, use test_event_code in the test events tool and remove it before going to production.
Which implementation path should you choose?
It depends on where the sale happens, not on technical preference:
| Situation | Path |
|---|---|
| Store or checkout on a hosted platform (Shopify, WooCommerce, a Stripe-based checkout) | Use the platform's own integration or an official plugin, if it offers sending to the Conversions API: the client's token goes there |
| E-commerce on another store platform | The platform's native integration or a partner's |
| Custom site, no developer | Conversions API Gateway, set up from Events Manager |
| Custom site with a developer, CRM, sales over chat or phone | Direct server integration, with a system user token |
The Gateway is Meta's no-code option: it runs in the advertiser's own cloud account (AWS or GCP), receives the pixel events and resends them from the server, generating and propagating the event_id on its own. It requires some technical familiarity and cloud costs, but it solves deduplication without touching the site.
In every case, someone will ask for an access token. This is where agencies usually go wrong.
How does an agency generate the CAPI token with a system user?
A system user is a machine account inside Business Manager (the business portfolio): it is not a person, it does not go on vacation, it does not change passwords and it only sees the assets you assign to it. It is the right way to give an integration access to the pixel without using anyone's personal profile.
There are two official paths. The quick one: in Events Manager, in the pixel settings, the option to generate a token under the manual Conversions API setup. Meta automatically creates an app and a system user for the Conversions API. The controlled one, which we recommend for agencies:
- In the client's business settings, open the system users area and create one, with a name that says what it does, for example
capi-example-store. - Choose the standard (employee) role, not admin. Meta reserves admin for administrative actions and recommends protecting that token with extra care.
- Assign this user only the client's pixel, with permission to manage it. No ad account, Page or catalog if the integration only sends events.
- Click generate token, choose the app and select the minimum permissions the screen asks for. Meta does not require app review for the Conversions API.
- Choose the expiration. Meta offers a token that never expires and a 60 day token, and calls the 60 day one a security best practice.
- Copy the token right away and store it in the agency's password vault. Treat it like a password: whoever has the token can send events on the client's behalf.
- Paste the token into the integration (checkout platform, Gateway or the server's environment variable) and fire a test event with
test_event_code.
Never-expiring or 60 day token?
Meta's documentation puts it this way: the one that never expires suits those who accept the risk of a leak in exchange for continuous access; the 60 day one limits that risk and is the recommended one, but it has to be renewed. In our practice, the rule is: a 60 day token wherever the integration can renew it without interrupting delivery, and a permanent token only with a named owner and a recorded revocation plan.
One system user per client or one for all of them?
One per client, created in the client's Business Manager. Putting every pixel under a single agency system user looks convenient until the day the token leaks: then a single code grants access to every client's pixel. Meta itself recommends creating one system user for each type of access.
- The asset belongs to the client. Pixel, token and system user live in the client's business. If the agency leaves, the client revokes the agency's access and measurement keeps working.
- The damage from a leak stays contained to one client and one pixel.
- Revoking is one click: when the client ends the contract, the agency deletes the token or removes the pixel from the system user.
- Never put the token in browser code, a shared spreadsheet or the team's group chat. It goes into the vault and into an environment variable.
The same logic applies to the team: each person only accesses the accounts they work on. We cover that in how to give access to a Facebook ad account and how to manage multiple Facebook ad accounts.
Token security checklist
Standard role, not admin. Only the pixel assigned. One system user per client. Token stored in a vault, never in front-end code. 60 day expiration when possible. Owner and creation date written down. Revocation on the same day the client leaves.
How do you know the implementation is right?
- In the test events tool, fire a test purchase and check that both the browser event and the server event arrive, and that Meta marks one of them as deduplicated.
- In the purchase event details, look at the event match quality score and which parameters Meta says are missing.
- For one week, compare the purchases in Ads Manager with the paid orders in your store or payment platform. A big gap upward means double counting or unpaid orders; downward means lost events. UTM parameters on your ads give you a third source that does not depend on the pixel or CAPI.
- Remove
test_event_codebefore releasing to production.
Frequently asked questions
Do I need the Conversions API if I already have the pixel?
Yes, if you advertise to sell. Meta recommends running both: the server delivers the event the browser blocked, and event_id deduplication prevents counting it twice.
What happens if I send pixel and Conversions API events without an event_id?
Meta may count the same purchase twice. ROAS gets inflated and the campaign optimizes for sales that never happened.
Which data is hashed in the Conversions API?
Email, phone, name, city, state, zip code and country go normalized and hashed with SHA-256. IP, user agent, fbp and fbc go unhashed.
Does the system user token expire?
It depends on what you choose when generating it: Meta offers a token that never expires and a 60 day token, and recommends the 60 day one for security.
Should an agency use one system user for all its clients?
No. Create one per client, in the client's Business Manager and with only that client's pixel, so a leak stays contained and revocation is simple.
Glossary
- Conversions API (CAPI)
- Sending conversion events from the advertiser's server directly to Meta.
- event_id
- Event identifier that, when identical on the pixel and the server, makes Meta count the conversion once.
- Event match quality (EMQ)
- A 0 to 10 score showing how well the customer data in a server event helps link it to a Meta account.
- System user
- A Business Manager machine account that only accesses the assets assigned to it and generates tokens for integrations.
- SHA-256
- A hash function that turns personal data into an irreversible code before it is sent to Meta.
References
- Meta for Developers: Conversions API. Supports: The Conversions API connects server, website, app or CRM data to Meta's systems, and its events are processed like pixel events.
- Meta for Developers: Handling duplicate Pixel and Conversions API events. Supports: Recommended redundant setup; deduplication by event_id and event_name; 48 hour window; fbq example with eventID; limitation of the fbp/external_id method.
- Meta for Developers: Customer information parameters. Supports: Which parameters require SHA-256 and how each one is normalized; IP, user agent, fbp and fbc unhashed.
- Meta for Developers: Server event parameters. Supports: event_time up to 7 days in the past; action_source required and its values; event_source_url required for website events; order number suggested as event_id.
- Meta for Developers: Using the Conversions API. Supports: Up to 1,000 events per request, whole batch rejected if one event is invalid, ideal sending within one hour and use of test_event_code.
- Meta for Developers: Conversions API best practices. Supports: EMQ is a 0 to 10 score shown in Events Manager, for web events only; recommended parameters; fbp and fbc change and need to be refreshed.
- Meta for Developers: Get started with the Conversions API. Supports: The two token paths (Events Manager, which creates an app and a system user, and a system user in business settings) and no app review required.
- Meta for Developers: System users overview. Supports: A system user only accesses assets it has permission for; difference between admin and standard; one system user per type of access; protect the admin token.
- Meta for Developers: Install apps and generate tokens (system users). Supports: Never-expiring token and 60 day token; expiring token as a security best practice.
- Meta for Developers: Conversions API Gateway. Supports: No-code Gateway hosted in the advertiser's cloud (AWS or GCP), with event_id generated and propagated automatically.
Links opened and checked on Sep 30, 2026.
About the author
Matheus Mello, founder of Ads Editor and owner of YEP Agência. Runs client ad accounts at YEP Agência and built Ads Editor so his own agency could stop publishing ads one at a time. Usage numbers quoted on the blog come from the product activity log. Instagram: @theusm



