A practical, no-fluff guide for performance teams and agencies.
Cross-platform reporting fails at a vocabulary level before it fails anywhere else: "conversions," "results" and even "spend date" mean different things on each platform. One source of truth isn't a bigger export — it's a normalization layer: an explicit mapping from each platform's dialect to your columns, applied identically every period. This guide builds that layer.
Sum the platforms' claimed conversions and you double-count (each claims the overlapping user). Compare CACs computed under different attribution settings and the "winner" is a settings artifact. Mix account timezones and the week's edges smear. None of these are exotic — they're the default outcome of pasting four exports side by side.
One table, owned like code:
| Your column | Meta | TikTok | Snap | Source of truth | |
|---|---|---|---|---|---|
| Spend | spend | cost_micros ÷ 1e6 | spend | spend | platform |
| Results | — | — | — | — | MMP event, deduplicated |
| Platform conv. | actions[purchase], 7dc/1dv | conversions (action-scoped) | conversions | swipe + view (labeled) | platform (claim) |
| CPM/CPC | computed | computed | computed | computed | derived |
Two rules carry most of the value: Results come from the MMP (one referee, no double-counting), and platform conversions survive as labeled claims for reconciliation — never summed, never silently substituted.
One period definition — last full ISO week — resolved per source in its timezone (Meta's ad account, AppsFlyer's app) and landed in the report's. One FX source for multi-currency accounts, applied at pull time, noted in the header. Trailing windows re-pulled so Meta's impression-date credit and Google's modeled restatements converge instead of haunting WoW deltas.
Per period, one normalized block — channel rows, identical columns — appended under the current month:
| Channel | Spend | Results | CAC | ROAS | Platform conv. | Var. |
|---|---|---|---|---|---|---|
| Meta | $13,900 | 1,012 | $13.74 | 1.9 | 1,388 | +37% |
| $17,800 | 998 | $17.84 | 1.6 | 1,205 | +21% | |
| TikTok | $9,400 | 571 | $16.46 | 1.7 | 833 | +46% |
| Snap | $7,100 | 376 | $18.88 | 1.4 | 512 | +36% |
The test of the layer: a new analyst reads any row without asking which platform's dialect it's in.
A good normalization layer makes channel five a map extension, not a report redesign: add the column mappings, add the pull, the block format doesn't change. (This is also the argument against per-platform tabs — every new channel forks the truth again.)
Single-channel accounts. The layer earns its keep the day channels start competing for budget on these numbers.
Cross-platform ad reporting stores your map once and applies it every run: pinned pulls, MMP-denominated results, labeled claims, reconciliation, one appended block. The multi-platform integration is the wiring.
"Build this week's cross-channel report: spend, results, CAC and ROAS by platform — reconciled against AppsFlyer."
See this running on your own reports.A 45-minute workflow audit maps your current process and shows exactly what Opera automates — step by step.
Three minutes: a plain-language request, a Sheet schema read, an AppsFlyer pull, a previewed append, a Slack summary — then a paused campaign launch.