← Back to all projects
In Progress PREP Created 2026-05-20 0/12 tasks

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_site in 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_site is a fallback — if landing_site is missing UTMs, a Google domain in referring_site confirms 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_campaign from each landing_site URL
  • Tag orders as google_cpc where utm_source=google AND utm_medium=cpc

Step 3: Referring site fallback

  • For orders with no UTM data in landing_site: check if referring_site contains google.com, googleadservices.com, or google.
  • 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.py pattern)
  • 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

  1. Is 22x ROAS real or inflated? — Real number will likely be 8-15x
  2. Which campaigns drive genuine incremental orders? — Brand search vs PMax vs Prospecting
  3. Is Google spend sized correctly? — If real ROAS is 8x not 22x, the budget decision changes
  4. 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.py in ~/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_site fallback
  • 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_site shows 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_site is the right data source
  • Awaiting approval to execute