Google Ads Attribution Audit
Priority: High
Problem Statement
Google Ads is reporting 22x ROAS for Shiplap ($12,382 claimed on $552 spend) during a week where total store revenue was $26,187. That means Google is claiming 47% of all revenue. This is a textbook Performance Max pattern: PMax bids on branded search terms and retargeting audiences, then claims full credit for orders that were already in the funnel — people who would have bought anyway.
Until we know the real number, the weekly spend/ROAS data is directionally misleading and can't drive good budget decisions.
Goal
Produce a 30-day attribution comparison across all 3 stores:
| Metric | Google Ads Reports | Shopify UTM-Sourced | Gap |
|---|---|---|---|
| Orders attributed to Google CPC | X | Y | X-Y |
| Revenue attributed to Google CPC | $X | $Y | $X-$Y |
| Implied ROAS | Google's # | Real # | Δ |
Key Findings from Research
landing_sitein the Shopify API contains the first-page URL with UTM params if the campaign was tagged. This is the primary data source.- 15-30% data loss is expected — apps, redirects, and payment processors can strip UTMs before the order is written.
referring_siteis a fallback — iflanding_siteis missing UTMs, a Google domain inreferring_siteconfirms the visit was from Google (but can't distinguish paid vs organic).- GCLID is almost certainly not captured — Shopify doesn't do this natively and there's no evidence of a third-party app (Triple Whale, Analyzify) installed.
- Performance Max is the highest-risk campaign type — industry research consistently shows PMax overclaims by capturing brand search and retargeting conversions that would have happened organically. The ANA found 71% of advertisers now prioritize incrementality over reported ROAS specifically because of PMax.
- 30 days is the right audit window — captures Google's full conversion window and reduces weekly variance.
Approach
Method: Shopify API UTM Extraction + Referring Site Fallback
Step 1: Pull 30 days of orders from Shopify API (all 3 stores)
- Use Shopify REST API
/admin/api/2024-01/orders.json - Pull
landing_site,referring_site,total_price,created_at,id - Date range: last 30 days
Step 2: Parse UTM parameters from landing_site
- Extract
utm_source,utm_medium,utm_campaignfrom eachlanding_siteURL - Tag orders as
google_cpcwhereutm_source=google AND utm_medium=cpc
Step 3: Referring site fallback
- For orders with no UTM data in
landing_site: check ifreferring_sitecontainsgoogle.com,googleadservices.com, orgoogle. - Tag these as
google_organic_or_paid(can't distinguish without UTM)
Step 4: Pull Google Ads data for same 30-day window
- Conversions + conversion value by campaign (using existing
google_ads_weekly_summary.pypattern) - Set to "by conversion time" not "by click time" for date alignment
Step 5: Produce comparison report
- Google Ads claimed: conversions + revenue by campaign
- Shopify UTM-confirmed: orders + revenue where
utm_source=google&utm_medium=cpc - Gap analysis: which campaigns are most overattributed
- Flag PMax specifically — expect it to show the largest gap
What We'll Learn
- Is 22x ROAS real or inflated? — Real number will likely be 8-15x
- Which campaigns drive genuine incremental orders? — Brand search vs PMax vs Prospecting
- Is Google spend sized correctly? — If real ROAS is 8x not 22x, the budget decision changes
- Did the March outage actually hurt? — Pull the 6 weeks before/during/after March to see if Shopify Google-sourced orders actually dropped
Implementation Plan
- ☐ Write
google_ads_attribution_audit.pyin~/ai-projects-local/mission-control/scripts/ - ☐ Pull orders from Shopify API for all 3 stores (30 days)
- ☐ Parse UTM params from
landing_site - ☐ Apply
referring_sitefallback - ☐ Pull Google Ads conversions + revenue for same period
- ☐ Generate comparison report (text + CSV)
- ☐ Save to
~/ai-projects/mission-control/reports/google-ads-attribution-audit-YYYY-MM-DD.md - ☐ Wire into weekly cron alongside
google_ads_weekly_summary.py
Acceptance Criteria
- ☐ Script runs clean for all 3 stores
- ☐ Output shows Google claimed vs Shopify UTM-confirmed side by side
- ☐ Campaign-level breakdown showing which campaigns have the largest gap
- ☐ March period analysis showing whether the outage impacted real order volume
Known Limitations
- UTM data will be missing for 15-30% of web orders (app redirects strip params)
- Can't distinguish paid vs organic for orders where only
referring_siteshows Google - No GCLID capture means we can't do exact order-level matching
- This audit shows correlation, not causation — it won't prove whether Google caused the orders, only whether Google was in the path
Execution Log
2026-05-20 — Plan created
- Research confirmed PMax attribution inflation is the likely explanation for 22x ROAS
- Shopify
landing_siteis the right data source - Awaiting approval to execute
~/ai-projects/mission-control/plans/google-ads-attribution-audit.md