Skip to content

Marketing & attribution

Google Ads, Meta and TikTok in one dashboard: cross-channel ad reporting

How to combine spend and results from Google Ads, Meta Ads and TikTok Ads into one report, covering a shared schema, currencies, time zones and retroactive conversion updates, then add backend orders so you see real ROAS.

DATUMPANELPublished Updated 7 min read

Cover for the cross-channel ad reporting article

Every Monday the marketer opens three ad platforms, copies numbers into a spreadsheet, converts currencies and builds a chart. A cross-channel report does all of that automatically. More importantly, it puts real sales from your backend next to the platforms' own "conversions."

A shared schema

Every platform names things differently, so step one is mapping them all into a single table:

FieldGoogle AdsMeta AdsTikTok Ads
datesegments.datedate_startstat_time_day
platformgooglemetatiktok
campaign_id, campaigncampaigncampaigncampaign
adset / ad_groupad groupad setad group
adadadad
spendcost (micros)spendspend
impressions, clicks✓✓✓
platform_conversionsconversionsactions (purchase)conversions
platform_valueconversions valueaction_valuesvalue

Details people trip on:

  • Google Ads reports cost in micros, so divide by 1,000,000.
  • The ad account currency may differ from your reporting currency. Convert at the daily rate.
  • The ad account time zone defines the "day," so align it with your backend.
  • Conversions get updated retroactively, so reload the last 7–30 days on every run.

Adding backend sales

Platform conversions are useful for optimisation. The founder's report needs the truth from your backend:

  1. Store UTMs and click IDs (gclid, fbclid, ttclid) on the order or lead (UTM convention).
  2. Match orders to campaigns by utm_campaign or campaign ID.
  3. Show side by side: spend, platform conversions, backend orders, backend revenue, platform ROAS, backend ROAS.
ChannelSpendPlatform conversionsBackend ordersPlatform ROASBackend ROAS
Google Ads5,2004103406.14.9
Meta Ads6,1005202605.43.2
TikTok Ads1,800140604.02.1

Illustrative. A gap between the columns is normal, and the attribution guide explains why. What matters is that budget decisions use the right-hand side of the table, with MER as the top-level sanity check (ROAS vs POAS).

Report structure

Overview: total spend, MER, new customers and CAC for the week, with comparisons.

Channels: the table above, plus spend and backend ROAS trends over 8–12 weeks.

Campaigns: sortable by spend, ROAS and CPA, with campaigns spending without orders flagged.

Creatives: CTR, CPC and frequency over time. Creative fatigue shows up as rising CPC and frequency.

Pacing: spend against the monthly plan, which matters most for agencies (agency reporting).

Getting the data

OptionProsCons
Native exports (Google Ads → BigQuery Data Transfer)free or cheap, reliableGoogle only
Managed connectorsfast, many platformssubscription, limits
Custom API scriptsflexible, any fieldneeds upkeep when APIs change

In practice I usually mix them: Google Ads via Data Transfer, Meta and TikTok via small custom loaders (pipelines). Access is read-only, and tokens stay on the server.

Alerts that save money

  • A campaign spent more than X with zero backend orders in 3 days.
  • CPC rose more than 30% vs its 2-week average.
  • Daily spend exceeded plan by 50%.
  • An account stopped spending (payment failed, ads rejected).

These alerts work well in chat (automated reports).

Common mistakes

  • Adding up platform conversions and calling them sales.
  • Not reloading history, so last week's numbers drift.
  • Ignoring account currency and time zone.
  • Not normalising campaign names.
  • No link to the backend, so the report only shows how the platforms grade themselves.

Checklist

  • One schema for all platforms
  • Currency and time zone aligned
  • Last 7–30 days reloaded on every run
  • Backend orders and revenue next to platform numbers
  • MER on the overview
  • Alerts for spend without results
  • Read-only API access

Step by step: the unified spend table

Everything in a cross-channel report rests on one table: spend and platform metrics per day, platform, campaign, in one currency and one time zone.

  1. Pull daily campaign stats from each platform's API or a managed connector: date, campaign ID, campaign name, spend, impressions, clicks, platform conversions and value.
  2. Re-pull the last few days on every run. Platforms restate recent days as late conversions and invalid-click adjustments arrive.
  3. Convert currency at a documented daily rate, keeping the original amount.
  4. Align time zones. Each ad account has its own. Note it per account and convert to the business time zone where needed.
  5. Map campaigns to your channel taxonomy with a lookup table (platform + campaign → channel, objective, product line).
CREATE OR REPLACE VIEW mart.ad_spend_unified AS
SELECT day, 'google_ads' AS platform, campaign_id, campaign_name,
       cost_micros / 1e6 AS spend, impressions, clicks, conversions AS platform_conv, conversions_value AS platform_value, currency
FROM clean.google_ads_campaign_daily
UNION ALL
SELECT day, 'meta', campaign_id, campaign_name,
       spend, impressions, clicks, purchases, purchase_value, currency
FROM clean.meta_campaign_daily
UNION ALL
SELECT day, 'tiktok', campaign_id, campaign_name,
       spend, impressions, clicks, complete_payment, complete_payment_value, currency
FROM clean.tiktok_campaign_daily;

Column names differ between platforms and API versions, so check them against your connector. The point is one shape for all.

Worked example: platform claims vs backend reality

Illustrative month, three platforms:

PlatformSpendPlatform-reported conversionsPlatform ROASBackend orders (UTM/click ID)Backend ROAS
Google Ads120,0004104.63603.9
Meta150,0005204.13002.3
TikTok60,0001903.8851.6
Sum330,0001,120—7452.8
Backend total paid orders in month980

The platforms together claim 1,120 conversions in a month with 980 real orders, of which 235 came from non-paid channels. Each platform counts its own view-throughs and longer windows and takes credit for overlapping customers. Neither column is "the truth". Platform columns are useful within a platform for optimisation, and the backend column is the one for budget allocation across platforms. Show both, labelled. More on why in the attribution guide.

A budget pacing view

For anyone managing monthly budgets, a pacing table prevents both overspend and money left on the table:

PlatformMonthly budgetSpent to date (day 16 of 31)Expected at this pointPace
Google Ads120,00066,00061,900107%
Meta150,00063,00077,40081%
TikTok60,00031,50031,000102%

Expected = budget × days passed / days in month (or weighted by your weekday pattern). A pace below 90% or above 110% is worth a look. Show it in the daily Telegram report for whoever owns the budgets.

A common trap: campaign names change

Marketers rename campaigns, and a lookup table keyed on names silently stops matching. Key the mapping on campaign ID and use the name only for display. List new IDs without a mapping in the weekly check, so no campaign falls into "other" unnoticed.

The same applies to UTMs. If campaign names in links are typed by hand, they drift from the platform names within weeks. Generate UTMs from the campaign ID or a template in the builder sheet, and join backend orders to spend on that key, not on a free-text name.

Finally, review the mapping table monthly with the marketer. Ten minutes spent assigning new campaigns to channels and objectives keeps the whole report trustworthy.

FAQ

Can I build this in Looker Studio?

Yes. Google Ads connects natively, and Meta and TikTok need connectors. Do the backend join and the normalisation in a warehouse, then point Looker Studio at the finished tables.

How often should ad data refresh?

Daily is enough for reporting. For alerts on large budgets, go hourly.

Why do yesterday's numbers change today?

Platforms add late conversions and adjust spend after the fact. That's why the pipeline reloads recent days.

Can I add Google Search Console?

Yes, as a separate "organic" block with impressions, clicks and positions by query, next to paid search.

Tags: Google AdsMeta AdsTikTokreporting

Author

DATUMPANEL — Business data analytics

DATUMPANEL is an independent data analyst based in Ukraine. I build dashboards for business owners, set up GA4 and the BigQuery export, and run data pipelines and Telegram auto-reports for e-commerce, service businesses, SaaS and agencies, from data audit to decisions.

Message on Telegram[email protected]Open the demo

Keep reading

  • Marketing & attribution10 min read

    Marketing attribution models: how to measure channels honestly

    How attribution models work (last click, first click, linear, data-driven), why Google Ads, Meta and GA4 all report different conversions, and how to build one channel report you can actually trust.

    Pillar guide

  • Marketing & attribution7 min read

    AppsFlyer attribution: OneLink, SKAN and a revenue dashboard

    How install attribution works in AppsFlyer, what OneLink does for web-to-app journeys, what changed on iOS after ATT, and how to join MMP data with subscriptions and events to get CAC and LTV by channel.

  • Marketing & attribution6 min read

    ROAS vs POAS: break-even ROAS and judging ads by profit

    The ROAS formula, how to calculate break-even ROAS for your store, how ROAS differs from ROI, MER and POAS, and how to move your dashboard from ad revenue to ad profit.

Want this kind of analytics for your business?

Tell me what data you have and which questions it can’t answer yet. I reply the same day with a plan, a timeline and the quick wins.

Or reach me directly:

Open the demo →

Send a request

I reply within one business day.

What are you interested in
Industry
A few more details · optional
Approximate budget · optional
When to start · optional
Data sources you have · optional

By submitting, you agree to the Privacy policy — your contact details are used only to reply to this request.