Meta Pixel and Conversions API: how to prevent duplicate events
You stop them by sending the same event_id and the same event name from both the browser and the server. The value must match character for character. When Meta Pixel and the Conversions API work together, every order goes out twice: once from the browser, once from the server. Meta merges them only if both carry the same event_id. If they do not, the account counts every purchase twice, the return looks twice as good, and budget decisions rest on an invented number. You check it in Events Manager: open the dataset, look at how many events are reported as duplicated and follow the event match quality (EMQ) score on a scale from 0 to 10.
My name is Hristiyan Panov — a performance marketing consultant with over 5 years’ experience and over €2 000 000 Managed advertising budgets for over 90 companies on Google and Meta. Below is a guide on how to check for deduplication in ten minutes and what to do if it’s not working properly.
Why are both channels needed at all?
Because the browser is no longer reliable. Ad blockers, restrictions in Safari and cookie refusals are eating into the number of events. The server is not dependent on the browser and transmits the rest.
The aim is not to have more events. The aim is the same events delivered via two routes, at least one of which is taken.
How to tell that one of the paths is missing: in Events Manager every event carries a source — browser only, server only, or both. If the server row is empty for Purchase, CAPI is not connected and all the reporting hangs on the browser. The opposite also happens: the server works, but the pixel does not fire because consent was declined, and bidding is left without the signals from the session.
The order of the check is short. Open the dataset, filter by Purchase, look at the distribution by source for the last few days, then compare it with the real orders. The two channels are not added together — they overlap. That is why the next step is deduplication, not adding yet another event.
How exactly does deduplication work?
The two events must match in two respects: the event name (Purchase) and event_id. Meta maintains a 48-hour window and accepts the first to arrive, rejecting the second.
The most reliable value for `event_id` in a shop is the order number. It is unique, exists on both sides, and does not depend on randomly generated numbers that the server is not aware of.
The match is literal. It is compared character by character — including upper and lower case, leading zeros and prefixes. If the browser sends one form of the number and the server sends the same number with a prefix added, there is no merging.
Which one arrives first makes no difference to the result. Usually it is the pixel, because it fires from the thank-you page, while the server event goes through the platform. So do not try to solve the problem by delaying one of them — a delay does not help when the identifier is different.
In the pixel the value is passed as the event identifier in the Purchase call. In the server event it sits in the event_id field. The two places are read side by side, not separately.
How can you check whether deduplication is working?
В Events Manager → your dataset → Overview. Under the ‘Purchase’ event, there is a row showing duplicate events and the deduplication percentage.
Three quick checks:
- Place a test order and see for yourself at Test Events whether two records with the same identifier are received.
- Compare the ‘Purchase’ figure in Meta with the actual orders in the system for the same period. A difference of around twofold is a tell-tale sign in itself.
- Please check that the total value of orders in Meta is not exactly double that shown in the accounts.
What is EMQ and how good is it?
Event Match Quality is a score from 0 to 10 that measures how well Meta manages to link an event to a real person. It depends on how many identifiers you send — email, phone number, name, city, IP address, browser ID.
A score below 5 means you’re losing attributions. A score above 7 is a good result for a Bulgarian shop. The quickest way to improve it is to add a hashed email address and phone number to the server event.
What are the three most common mistakes?
All three are found on the same screen and fixed in the same place — in the event setup, not in the campaigns.
- A random event_id generated by the browser. The server generates its own and the two never match. Use the order number. You can tell by the deduplication rate sitting at zero while both sources report Purchase.
- Various names for the event. “Purchase” from the pixel and “purchase” from the server are not merged. The same applies to a custom name set by a plugin — it appears as a separate event in the list and is not counted toward the standard one.
- Automatic event detection (automatic advanced matching / auto config). The pixel sends additional events that nobody ordered, and they enter the report. It is switched off in the dataset settings, after which you check whether the manually configured events continue to arrive.
After every change, wait for a new real order and follow it end to end. The report does not confirm the fix until an event created after it has passed through.
What about the value of the order?
It must be the same amount and in the correct currency. In shops that are in the process of switching from the lev to the euro, I have seen the client send an amount in one currency, whilst the server sends it in the other. The result is a return rate inflated by nearly twofold, without a single duplicate transaction.
Check not only the number but also the total value against the actual turnover.
Deduplication does not look at the amount. It matches the name and event_id, so a mismatch in value passes without warning and does not appear anywhere in the report as a duplicated event.
So fix the rule and keep to it on both sides: the same basis — with or without tax, with or without shipping — and the same currency field. The amount is passed as a number, with no currency symbol in the field itself.
The check is simple. For the same period, take the total value of Purchase and compare it with the revenue in the order system. If the ratio resembles the exchange rate between the two currencies, look for the error in the currency field, not in the event count.
FAQ — Frequently Asked Questions about Pixel and CAPI
Can I use CAPI on its own?
Technically, yes, but it is not recommended. Pixel adds signals from the browser that improve matching and optimisation.
Do I need a dedicated server?
Not necessarily. The platforms’ ready-made integrations do the job. Having your own GTM server gives you more control and better EMQ, but it’s an additional cost.
How long does it take for the amendment to take effect?
Events are deduplicated immediately, but the reports take 24–48 hours to provide a complete picture. Historical data remains inaccurate.
Will my conversion rates drop following the update?
The reported figures — yes, and that’s the good news. Actual sales remain unchanged; you stop making decisions based on inflated figures.
Does consent to cookies make a difference?
Yes. If the user opts out, the pixel is not triggered; the server-side event must also respect this choice. Please check that your integration does this.
Conclusion
Duplicate events are not just a technicality. They make a losing campaign look like a winning one — and the longer they remain, the more of the budget is channelled in the wrong direction with complete confidence.
If the figures in Meta do not match those in your bank account, start by arranging an independent review.
Request a quote for a digital audit →
Related articles: server-side tracking · Consent Mode v2 · ROAS and margin thresholds


