A practical, no-fluff guide for performance teams and agencies.
Paid media reporting across four platforms is four exports, four metric dialects and one Sheet that's supposed to make them comparable. Automating it well is mostly about pull discipline — each platform fetched with the settings pinned and the quirks handled — plus one normalization layer that makes a column mean the same thing in every row. This guide is the channel-by-channel version.
Meta — act_<id>/insights with explicit fields, the attribution setting pinned per request (e.g. 7d_click/1d_view), country breakdowns where the report needs them, async jobs for big accounts. Meta credits conversions to impression date: re-pull a trailing ~7 days every run or last week never settles.
Google — GAQL per 10-digit customer ID under the MCC: SELECT campaign.name, metrics.cost_micros, metrics.conversions, segments.date FROM campaign. Divide micros by 1,000,000; remember conversions are modeled onto the click date and restate — trailing re-pull again.
TikTok — Reporting API per advertiser_id at campaign/ad-group grain; self-reported conversions run on TikTok's windows and SKAN on iOS, so they're an optimization signal, not your denominator.
Snapchat — stats at campaign/ad-squad grain; swipe-up vs view-through conversions reported separately, and view-through is generous — keep them labeled.
The MMP — AppsFlyer for the outcome series: installs and KPI events at your grain, deduplicated, SKAN separate. This is what CAC and ROAS compute on.
One mapping, written down: each platform's fields → your columns. spend is universal; results means your conversion event from the MMP; platform-claimed conversions get their own labeled column for reconciliation; currencies convert from one FX source; every date resolves in the report's timezone. The test of good normalization: a new analyst can read any row without asking which platform's dialect it's in.
| Channel | Spend | Results (MMP) | 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% |
One block per period, appended under the current section — never a per-platform tab nobody reconciles.
Weekly is the workhorse cadence; add a daily pacing view (spend vs budget by campaign) where flighting is tight, and a monthly close that runs after the restatement window settles. Each run: schema re-validated → pinned pulls → normalization → reconciliation → previewed append → summary with exception flags.
Attribution settings drifting between weeks (trend breaks that aren't real), platform conversions summed with MMP events (double-counting), micros un-divided (a fun morning), timezone mismatches at week boundaries, and the universal one: the report shipping late because four exports queued behind one person's Monday.
While the channel list or the conversion definition is still moving monthly. Pin those, then schedule.
Paid media reporting automation is exactly this: pinned per-platform pulls, your normalization map stored once, reconciliation built in, appended on schedule.
"Update the paid media report with this week's spend, CAC and ROAS by channel."
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.
A 45-minute teardown of how you report today: we map every step, mark what Opera automates, and send you the written spec — useful whether or not you buy.