Agent events double-counting: pixel + CAPI dedup for agent conversions
You built the server-side path so agent conversions stop going missing. Now the opposite bug appears: some conversions arrive twice. Here is which agent paths overlap, which are server-only by nature, and how to make each platform keep exactly one copy.
Landscape as of September 2026
Double-counting happens when one action reaches a platform through two paths - a pixel the agent's browser executed, and a server event your capture path sent. The fix is a shared identifier on both copies: the same event_id for Meta pixel + CAPI, the same transaction_id for GA4 purchases. The agent-specific rule: dedup only the overlapping paths. A pure API-side agent action fires no pixel, so its server event is the only copy - a dedup setup that quietly drops unmatched server events will delete the very conversions you built the path to capture.
Where the duplicate comes from
Agent traffic is split-brained by nature. Some agents drive a real browser (operator-style agents like ChatGPT agent's visual browser or the Atlas browser), so your web container runs and the pixel fires. Others act over plain HTTP or APIs, where nothing client-side ever executes. If you followed the server-side capture pattern, your server path is watching both kinds. The result is a matrix, and each row wants a different treatment:
| Agent path | Pixel fires? | Server event? | What you need |
|---|---|---|---|
| Human AI-referral click | Yes | Only if you mirror all traffic server-side | Standard dedup, same as any human session |
| Browser-driving agent | Often (JS executes; consent state may block it) | Yes | Dedup required - both copies carry one event_id |
| API-side agent action | Never | Yes - the only copy | No dedup partner. Must NOT be dropped as "unmatched" |
The middle row has one more wrinkle: whether the pixel fired at all can depend on the consent state the agent never interacted with. A consent banner an agent cannot click means the pixel path silently drops out and the server copy becomes the only one - the diagnosis for that case lives at consent banner is blocking agent tracking.
The dedup keys, per platform
- Meta (pixel + Conversions API). Dedup key is
event_name+event_id: when two events with the same pair arrive within the dedup window, Meta keeps one. The pixel'seventIDparameter and the CAPI payload'sevent_idfield must be generated once and shared - not generated independently on each side. - GA4 (gtag/GTM + Measurement Protocol). Purchases deduplicate on
transaction_id. Non-purchase events have no cross-path dedup, so for agent-visible events prefer routing ONE path per event type rather than mirroring everything. - Google Ads. Conversions reconcile on order ID (and hashed user data for enhanced conversions). Same rule: one order, one ID, on every copy.
Generate the identifier at the point of truth - the order or action itself - and let both paths inherit it:
// Shared id: derive from the order, not from the transport
const eventId = 'order_' + orderId; // stable across paths
// Browser (web container): pass to the pixel tag
fbq('track', 'Purchase', {value, currency}, {eventID: eventId});
// Server (sGTM -> CAPI tag): same field, same value
payload.event_id = eventId; // NOT a new uuid here
The temptation to uuid() on each side independently is exactly the bug: two ids, two conversions. Only the ingest path for pageview-type agent hits should mint fresh ids, because there is no second copy to collide with.
Keep the server-only rows alive
Agent-completed conversions are worth protecting: Adobe Analytics measured AI-driven traffic converting 42% better than non-AI in March 2026, and Shopify saw AI-attributed orders grow 11x between January 2025 and March 2026 (commercetools' agentic commerce review). If your pipeline flags unmatched server events as suspicious - some CAPI gateway setups do - whitelist events carrying your agent classification (traffic_type=agent, from the classification ladder) as legitimately partner-less. The platform-by-platform payload details for those server-only conversions are covered at agent conversion signals, and the checkout-specific capture at capturing agent checkout via CAPI.
How to verify it worked
- Overlap case. In a test browser session, complete a conversion with a known order id. Confirm in Meta Test Events that both the pixel event and the server event arrive and one is marked deduplicated; in GA4, confirm exactly one purchase exists for that
transaction_id(Realtime, then the Transactions report next day). - Server-only case. Send a CAPI/MP event with a fresh id and no browser counterpart (replay an agent-classified conversion). The passing result is that it appears as ONE conversion - present, not dropped, not flagged.
- Regression watch. Compare platform-reported conversions to backend orders for a week after shipping. Duplicates show up as platform > backend; over-aggressive dedup shows up as platform < backend concentrated in the agent segment.
Also on this site: the non-agent version of this bug - a pixel firing twice in one browser session - is a different failure with its own fix at Facebook pixel purchase fires twice.
Common questions
Why are my agent conversions counted twice?
Because two collection paths saw the same action: a browser-driving agent executed your pixel, and your server-side path captured the same conversion and sent it via CAPI or Measurement Protocol. Without a shared event identifier on both copies, the platform treats them as two conversions.Do all agent conversions need pixel + server dedup?
No. Pure API-side agent actions never fire a pixel, so the server event is the only copy and needs no dedup partner - deduplicating it away would delete your only record. Dedup is needed exactly where paths overlap: operator-style agents driving a real browser, and human sessions that your server path also captures.What fields drive deduplication on each platform?
Meta deduplicates on event_name plus event_id within a window (event_id must match between pixel and CAPI). GA4 deduplicates purchases on transaction_id. Google Ads enhanced conversions reconcile on order ID and hashed user data. The rule is the same everywhere: both copies of one action must carry the same identifier.How do I test dedup without waiting for real agent traffic?
Replay both paths yourself with a fixed identifier: fire the browser event with a known event_id, send the matching server event with the same event_id, then confirm in Meta Test Events (one event marked deduplicated) or GA4 (one purchase for one transaction_id). Then send a server-only event with a fresh id and confirm it is NOT dropped.
Conversions arriving twice - or not at all?
We audit the full pixel + server path, fix the identifier plumbing, and prove the counts against your backend orders.
Talk to a Google Tag Manager Expert