Many marketing teams run reporting through Google Sheets.
The workflow starts as a manual export from each ad platform, then someone builds a script to automate it, and over time the sheet becomes the source of truth for spend, conversions, and performance.
This works until it doesn't.
Why multi-platform reporting is harder than it looks
Each ad platform has its own:
- API authentication method and rate limits
- Date range handling and update windows
- Conversion definition and attribution logic
- Account and campaign hierarchy
- Metric naming conventions
When you pull four platforms into one sheet and put them side by side, every one of those differences is a potential mismatch. Clicks from Google Ads are not the same as clicks from LinkedIn. Conversions from Meta depend on the attribution window you selected. Spend from Bing may be in a different currency.
The sheet looks unified but the data is not.
Platform-specific issues
Google Ads
Google Ads Scripts run inside the Google Ads UI and can write directly to Sheets without a separate API setup. This is the fastest path for single-account reporting. For multi-account or custom metric pulls, the Google Ads API with Apps Script or Python gives more control.
Key issues:
- Google Ads conversion columns depend on which conversion actions are selected in the account. An account pulling "All conversions" gives different numbers than one pulling "Conversions."
- Date ranges for conversion data need lookback for late-attributed conversions.
- Scripts have execution time limits. Large accounts or long date ranges need batching.
Meta Ads
Meta's Marketing API is asynchronous for report requests - you submit a report job, poll until it's ready, then download. Apps Script can do this but the retry pattern is more complex than a synchronous API call.
Key issues:
- Attribution window selection changes the reported numbers. Always store which window was used.
- Rate limits are per-app and per-account. If the same app token is used across many accounts, you will hit limits.
- Meta's API returns data in pages. Scripts that do not handle pagination silently drop rows.
LinkedIn Ads
LinkedIn's API has the tightest rate limits of the common ad platforms. Pulling historical data for many campaigns in one script run will likely hit a limit.
Key issues:
- Metrics like "Clicks" on LinkedIn include both social and website clicks. Make sure you are pulling the right breakdown.
- The API requires campaign IDs to be fetched first before pulling performance data. Two-step scripts are needed.
Bing / Microsoft Ads
Microsoft Ads uses a SOAP API (older) or REST API. The reporting API submits a report request and delivers a download URL. Similar async pattern to Meta.
Key issues:
- Microsoft Ads conversion data depends on Universal Event Tracking being set up correctly.
- Currency handling is important if the account runs in a currency other than the sheet's reporting currency.
Rerun safety
The most common bug in Sheets reporting automation is duplicate data on reruns.
A script that appends rows without checking for existing data will write duplicate rows every time it runs. After a few days, the sheet totals are double or triple what they should be.
The fix is to either:
- Clear the date range before writing (only safe if reruns are expected to be complete)
- Write to a staging sheet and use a formula or script to merge-deduplicate into the reporting sheet
- Use a keyed lookup on date + platform + campaign to prevent duplicate inserts
Option 1 is simplest. Option 3 is safest for incremental workflows.
What the validated workflow looks like
A well-built multi-platform Sheets automation:
- Pulls each platform's data for the defined date range
- Normalizes field names and date formats across platforms
- Validates platform totals against known benchmarks or yesterday's pull
- Writes to a staging area first
- Merges or replaces the reporting range in a controlled way
- Logs the run result (date range, row counts, any errors) to a log sheet
This is more code than a simple append script, but it is the minimum that makes a Sheets workflow trustworthy.
When Sheets stops being enough
Sheets reporting automation is a good fit when:
- Data volume is manageable (under a few thousand rows per report)
- Sources are few and well-defined
- The team reviews and understands the output in Sheets
- A failed run is annoying but not business-critical
It starts to break down when:
- Row counts grow past comfortable spreadsheet use
- Multiple people modify the sheet and break formulas
- You need joins across ad data, CRM data, and order data
- Attribution becomes complex enough that a formula cannot handle it
- Stakeholders need audit trails or point-in-time reporting
At that point, BigQuery with a warehouse model is a more reliable foundation - and Sheets can still be an output layer if the team prefers reviewing data there.
Related project
See the project write-up for Multi-Platform Ads Reporting Automation: Google Ads, Meta Ads, LinkedIn Ads, and Bing/Microsoft Ads reporting into Google Sheets with platform-specific handling and validation.
If your Sheets reporting is working but fragile, I can help audit the script, add validation, or plan a migration to BigQuery if the data has grown beyond what Sheets handles well.