Question Posted by the DataCops team

Facebook Conversions API duplicate events: how to dedupe with event_id (and how to audit it)

Short answer

Generate one ID per event and send it from both pixel and server. Double counting comes from two IDs, retries, a second integration or different event names. Audit by comparing a week of orders to reported conversions.

Everyone is thrilled the week they add server-side events. Conversions are up. ROAS is up. Then finance compares it to the bank account.

That's usually double counting, and it's remarkably easy to cause.

Here's how Meta thinks about it. When the same purchase arrives from the browser and from the server, Meta treats them as one event if the event name and the event_id match, and keeps one. If the event_id is missing or different, it counts the sale twice. There's no cleverness. It's an ID comparison.

So the fix is simple in words: generate one ID per event, and send the same ID from the browser and from the server. In practice, where does it go wrong? Four patterns.

Two sources, two IDs. The pixel and the CRM both report the same sale, each with its own ID. Meta sees two different sales.

The retry. A tool retries a failed send and creates a second copy, sometimes with a fresh ID.

The second integration. Two tools both push "Purchase", and nobody remembers installing the second one. This one is common after an agency change.

The renamed event. The pixel sends "Purchase" and the server sends "purchase". Different names, so no dedupe.

For Google Ads, the equivalent habit is sending an order ID (transaction ID) with each conversion, so repeats get ignored.

How do you audit it? A method that takes ten minutes: pick one week. Count the orders in your CRM or shop. Count the conversions the ad platform reports for the same week. Ad platform conversions far above real orders means duplicates. Far below means dropped events. Roughly equal means you're close, though check revenue too, because you can have the right count and the wrong values.

And here's a made-up example to keep it honest. Your CRM shows 50 orders. Meta reports 96. That's nearly 2x, which almost always means every sale is arriving twice with different IDs. The fix isn't in Meta. It's making the browser and the server agree on one ID.

A subtlety: you can have duplicates that don't show up as a bigger count. If the same sale arrives twice with different values, or one copy arrives as a Purchase and the other as a Lead, the totals look plausible and the revenue is wrong. So audit revenue as well as count: the total value the platform reports for the week, against your real revenue.

Also look at the event names in Events Manager. If you see two near-identical names, like Purchase and purchase, that's usually your duplicate source. And check when the duplicates started. If the count jumped on a specific date, look at what you deployed that day: a new plugin, a new integration, a changed workflow. The date almost always points at the cause, because duplicates are introduced by changes, not by drift.

If you send sales through a webhook instead of a pixel, the order ID plays the same role as the event ID. The same order ID arriving twice counts once, which makes retries safe. Set it once, from your own system's order number, and reuse it every time that sale is sent.

The prevention that works: decide who owns the event ID. The simplest rule is that the website generates it at the moment of the action, and every other system reuses it. When two systems each invent their own, you get duplicates. If the CRM event happens later, it needs the original ID, which means storing it on the contact at the time of the action. That one storage step is what makes dedupe possible days later. Skip it, and you'll be reconciling by hand forever.

Has anyone found a clean way to audit this on a regular basis, or is it a manual spreadsheet for everyone?

DataCops in short

For this question: DataCops gives the pixel and server copy the same event ID and counts the same order ID once, so retries and double integrations do not become a second sale.

DataCops is a tool that makes the ads learn from real sales: it sends booked, showed, won and paid stages from your CRM back to your ad platforms, gives every visit a bot verdict with a Real people only switch per platform, warms up new campaigns with your existing customers, and logs every send. It is not an attribution report.

How DataCops does it

  • The sale after the form. HighLevel natively (lead, booked, showed, won with value, paid; cancelled, no-show and lost are never sent), any other CRM through a private webhook, matched to the click by click ID or hashed email and phone.
  • The click is kept on the server. Click IDs are stored for up to 90 days, so a deal that closes weeks later still finds its click.
  • Real people only. Every visit gets a bot verdict against 360+ billion IPs and 350+ monitoring points, with a Real people only switch per ad platform, off by default. CRM events carry no bot flag.
  • Counted once, logged every time. Pixel and server events share an event ID, and a delivery log shows each send as sent, held, skipped or failed, with the reason.
  • One script, one DNS record. Collection runs on your own domain; with DNS on Cloudflare, the free Worker reads the click at the edge before the page loads.

Best for: ad-funded businesses whose sales close in a CRM or on a call: clinics, home services, agencies, B2B and lead gen.

Ads Warmup: tell the ads who pays

Ads Warmup, DataCops' flagship feature, sends customers you already have to Meta, Google Ads and TikTok before a new campaign spends: upload a CSV (only email is required, up to 20,000 rows), see a 0 to 10 match score per person, pick the event, and send. Rows are dated when you send, and Google Ads credits only people who clicked a Google ad. Preview is free; sending needs a paid plan. Check your own consent basis for the list first. See Ads Warmup.

Ways to do this job

OptionBest for
DataCopsCRM stages to Meta and Google Ads, with a bot verdict and a delivery log
Zapier or MakeOne simple CRM-to-ad flow you build and maintain
Direct API uploadTeams with an engineer
Manual CSV uploadOccasional batches

When not to use DataCops

  • You want a reporting dashboard. DataCops cleans and sends what goes into your ads. It is not a multi-touch reporting layer.
  • Your sales never leave one store checkout. If everything happens in one checkout, the platform's own pixel plus server events may be enough.

More on this: Meta offline conversions, and the complete guide to offline conversion tracking.

1 comment

Comments (1)

DataCops team author · 30 Sep 2026

If your results suddenly look better after a tracking change, check for double counting before you celebrate. Conversions doubling while revenue stays flat is the classic tell.

1
Replies from DataCops account holders are coming soon. Until then, questions about your own setup can go to the team.

More threads

See what your own setup is missing

Send CRM sales back to the ad click that started them, logged per send.

Setup in 5 minutes. No credit card.

Live traffic quality

Updated just now

Visits · last 24h

487
Real users
35873.5%
Bots · auto-filtered
12926.5%

Without filtering, 26.5% of your reported traffic is bot noise inflating dashboards and draining ad spend.

Don't trust your analytics!

Make confident, data-driven decisions withactionable ad spend insights.

Setup in 2 minutes
No credit card