Adding Meta-reported conversions to Google-reported conversions double-counts because each platform claims credit for the same user under its own attribution window, model, and identity graph. A buyer who clicked a Meta ad on Tuesday and a Google ad on Thursday shows up as one conversion in each interface, so the sum reports two sales where one happened. The numbers are answers to different questions, and different questions do not share a total.
This is the single most common measurement mistake I see in cross-channel reporting, and it usually hides in a spreadsheet cell labeled "Total conversions" that a client dashboard has faithfully summed for months. This post covers why the numbers are incompatible, where GA4 and MMPs fit, and how the Claude Ads attribution audit handles the problem: it refuses the sum outright until the inputs are actually comparable.
Each platform answers a different question
Every ad platform is a self-graded exam. Meta reports conversions it attributes to Meta touchpoints under Meta's rules. Google does the same under Google's rules. Neither can see the other's ads, and both are structurally incentivized to claim as much credit as their model allows.
The incompatibilities stack up across several dimensions at once:
| Dimension | Meta (platform-reported) | Google Ads (platform-reported) | GA4 |
|---|---|---|---|
| Attribution scope | Meta touchpoints only | Google touchpoints only | All tracked channels |
| Window | Short click and view windows (seven-day click in the canonical example) | Longer click windows (thirty-day click in the same example) | Its own lookback settings |
| View-through | Counts view-through under its rules | Varies by campaign type | Generally click and interaction based |
| Identity | Logged-in Meta identity graph | Google identity and signals | Cookies, user IDs, Google signals |
| Modeled data | Models conversions lost to consent and platform privacy limits | Models conversions under its own methodology | Applies behavioral and conversion modeling |
| Credit model | Platform's own model | Configurable per conversion action | Data-driven attribution by default |
A Meta seven-day conversion count and a Google thirty-day conversion count are not two measurements of the same thing at different precision. They are different metrics that happen to share a column name. Summing them is a category error before it is an accuracy error.
The overlap problem is not hypothetical
The user journeys most worth paying for are exactly the ones both platforms touch. Prospecting on Meta, brand search on Google, retargeting on both: the higher your cross-channel investment, the more your platform-reported numbers overlap, and the worse the naive sum gets. Double counting is not random noise that averages out. It scales with the behavior you are trying to grow.
Where GA4 and MMPs fit
GA4 is often proposed as the referee, and it helps, but it is not neutral ground truth either. GA4 sees the journey across channels, which the platforms cannot, but it applies its own attribution model, its own lookback windows, and its own consent-driven modeling. GA4 will typically report fewer conversions per paid channel than the platforms claim, because credit is split across touchpoints instead of fully awarded to each. That gap is not an error in either system. It is two different rulebooks scoring the same game.
Mobile measurement partners such as AppsFlyer, Adjust, Branch, and Singular add a fourth rulebook for app campaigns. An MMP deduplicates installs across networks under its own last-touch logic and its own windows, which again produces numbers that disagree with both the ad platforms and GA4 by design. On iOS, AdServices and AdAttributionKit introduce their own privacy-constrained counting on top of that.
So a typical account has four or five sources reporting "conversions," each internally consistent and mutually incompatible. The failure mode is not having multiple sources. It is treating any arithmetic across them as meaningful without normalization.
How the attribution audit handles this
The Claude Ads attribution skill treats aggregation as something you must earn, not something a spreadsheet grants by default. When you run it, the audit starts by declaring the business conversion, the value definition, the data window, timezone, currency, and the decision the analysis needs to support. Then it inventories every attribution source you have, browser, server, platform, analytics, MMP, offline, and app, along with each source's identity, counting, deduplication, and privacy rules.
/ads attribution
The core mechanism is a comparability gate. The audit rejects any aggregation until the sources share, or are explicitly normalized to, the same conversion event and value definition, attribution window, click and view scope, counting method, deduplication identity, timezone, currency, attribution model, and modeled-data treatment. Until every one of those matches, the audit reports the values side by side with their definitions attached and refuses to compute a total. Meta seven-day conversions plus Google thirty-day conversions is the canonical rejected request: reconcile windows and definitions first, then aggregate the newly comparable dataset. That attribution-window check is also part of a Meta ads audit, which reviews attribution settings and iOS attribution windows from current account evidence rather than assumed defaults.
Two other rules matter in practice:
- No source is assumed to be ground truth. Not the platforms, not GA4, not the MMP. Each is a lens with documented distortions.
- Measurement quality is scored separately from platform-reported performance. A campaign can look great in its own interface while the tracking underneath is broken, and the audit keeps those two judgments apart.
When comparable events disagree, the audit explains the difference in terms of specific causes: eligibility rules, view-through treatment, consent gaps, modeled data, conversion lag, reporting thresholds, or plain scope mismatches. The output flows through the same JSON contract as the rest of the audit pipeline: findings, contradictions, confidence per finding, missing evidence, and a measurement improvement plan, all rendered into the run bundle rather than a loose narrative.
A practical reconciliation approach
You do not need perfect attribution to make good budget decisions. You need numbers whose definitions you can state. The working process I recommend, and the one the audit formalizes:
- Pick one business conversion definition and one value definition. Write them down with timezone and currency.
- List every source that reports that conversion and record its window, model, view-through rule, identity basis, and modeled-data behavior.
- Report side by side, labeled. "Meta-attributed purchases (7-day click)" next to "Google-attributed purchases (30-day click)" next to "GA4 purchases (data-driven)" is honest. One merged column is not.
- Reconcile the gaps and explain each one with a named cause. Unexplained gaps are findings, not rounding errors.
- Only total what you have normalized. If you need one cross-channel number, derive it from a single source of truth such as backend transactions, and treat platform numbers as directional signals of each channel's contribution.
The Meta platform audit pairs naturally with this work, since Pixel and Conversions API health, deduplication, and attribution settings on the Meta side determine whether the Meta column in your side-by-side view is even internally trustworthy before you compare it to anything else. The server-side tracking audit guide covers that layer step by step: sGTM, browser and server event paths, and event_id deduplication verified by behavior rather than configuration.
Try it
The attribution audit ships as part of the Claude Ads plugin, alongside the platform workers and the full audit pipeline. Install it in Claude Code with two commands:
/plugin marketplace add AgriciDaniel/claude-ads
/plugin install claude-ads@ai-marketing-hub-claude-ads
Then run /ads attribution against your own stack. The first thing it will probably tell you is which of your dashboard totals should never have been totals. See the installs page for setup details and the rest of the 33 skills in the plugin.