OA
Part 2 of 2  ·  Measure Summit
Organized AI
Google APIs at Scale
Building and managing your entire Google marketing stack programmatically — with AI agents in the loop.
GTM Management API Google Ads API GA4 Admin API GWS CLI GCP MCP
JH
Jordan Hill
Blue Highlighted Text  ·  Organized AI
The real problem
Manual tracking
doesn't scale.
47
Tags per container
Average mid-market DTC brand. Most broken, duplicated, or firing on every page.
6 hrs
Per tracking audit
Clicking through UIs, building screenshots, writing SOPs — every single client.
Scale ceiling
Can't 10x clients with the same manual process. Something has to change.
# Current workflow — repeated for every client, every month 1. Open GTM UI → navigate workspace → manually inspect each tag 2. Open GA4 → validate events in DebugView → check custom dimensions 3. Open Google Ads UI → verify conversion actions → check Enhanced Conv. 4. Write it all up in a doc → attach screenshots → send to client # What the same work looks like programmatically claude --dangerously-skip-permissions "audit all containers, flag broken tags, check GA4 parity, push fixes"
The full toolkit
Google's programmatic
marketing API layer
REST v2

Tag Manager API

Read, write, version, publish GTM containers. Tags, triggers, variables — all writable.

gRPC + REST

Google Ads API

GAQL queries, conversion actions, Enhanced Conversions, Customer Match — fully programmatic.

REST + Admin

GA4 Admin + Data

Provision properties, register events, build audiences, pull funnel reports — without the UI.

REST

Merchant Center API

Product feeds, performance data, account config — scriptable for multi-account management.

CLI

GWS CLI (gcloud)

Google Workspace + Cloud from the terminal. Service accounts, IAM, projects — all scriptable. Pairs directly with Claude Code.

MCP

GCP MCP

GWS CLI + a scoped service account = Claude's MCP surface over any Google Cloud API. Infra-as-conversation.

API Deep Dive — 01
Google Suite
Everything GWS CLI reaches — in one surface.
Ads + Analytics — configure & query
Google Ads API — GAQL
Conversion actions, Enhanced Conversions, Offline Conversion Import, Customer Match — all programmatic. GAQL reports piped into Claude for analysis.
GA4 Admin API — properties as code
Provision properties, register events + custom dimensions, build audiences, flip on BigQuery export — no UI clicks.
GA4 Data API — funnels on demand
Pull funnel and cohort reports, feed to Claude, get plain-English drop-off analysis with fix recommendations in <60 seconds.
Google Ads MCP GAQL GA4 Admin GA4 Data Stape MCP Enhanced Conv. OCI
GWS CLI access — the full surface
Tag Manager API
Containers, workspaces, tags, triggers, variables — scripted.
BigQuery
Raw GA4 events + ad-hoc SQL. The analytics source of truth for every dashboard.
Cloud Scheduler + Cloud Run
Nightly audit jobs, webhook pipelines, OCI uploads — cron via gcloud scheduler.
Secret Manager + IAM
Service-account keys, OAuth tokens, per-API scopes — granted as code, read at runtime.
Google Sheets API
Read + write reporting sheets directly — client dashboards, pacing docs, pivot exports updated on a cron.
Search Console + Merchant Center
Organic + shopping feeds on the same CLI — cross-channel reporting without a new vendor.
Google Workspaces — built for agent interaction. One SDK, one auth flow, every surface addressable from Claude Code.
The edge layer
Cloudflare Dev Platform MCP
+ Wrangler CLI — edge infra, chat-native.
The Cloudflare MCP exposes D1, KV, R2, Workers, and Hyperdrive as direct Claude tool calls. Wrangler CLI ships the code.
D1 for audit artifacts + session state
cloudflare.d1_database_query — Claude reads and writes SQL directly. Audit baselines, MCP session tokens, drift history.
R2 for container exports + snapshots
Versioned GTM container JSONs, Meta ad snapshots, weekly audit PDFs — stored + queryable from the MCP.
KV for fast config + feature flags
Per-client tracking configs, experiment toggles, quick cache for GAQL + GA4 results between audits.
Workers as API glue + webhook handlers
GTM webhook → Pub/Sub → Measurement Protocol in a few lines. Deployed with wrangler deploy.
Hyperdrive — GCP ↔ edge DB bridge
Cache BigQuery-backed lookups at the edge. Fresh data without per-query BQ billing.
The split: GCP MCP = the data + compute source of truth. CF Dev Platform MCP + Wrangler = the public edge where audits run, webhooks land, and artifacts live.
# claude_desktop_config.json — CF MCP wired in { "mcpServers": { "cloudflare": { "url": "https://bindings.mcp.cloudflare.com/sse" } } } # "List my Workers" → cloudflare.workers_list() # "Provision audit DB + bucket" → cloudflare.d1_database_create({ name: "gtm-audit-db" }) → cloudflare.r2_bucket_create({ name: "gtm-containers" }) # "Query the last audit" → cloudflare.d1_database_query({ database_id: "...", sql: "SELECT * FROM audits ORDER BY ts DESC LIMIT 1" }) # Wrangler CLI — ship the code wrangler deploy # push Worker wrangler d1 execute DB --file=migrate.sql wrangler tail # live logs from Claude
CF Dev Platform MCP Wrangler CLI D1 R2 KV Workers Hyperdrive
Surface map
What GWS + GCP reach
— and where they overlap.
One service account, one OAuth flow, and a Claude Code session can address every surface below.
flowchart LR subgraph GWS["Google Workspace — GWS CLI"] direction TB G1(Gmail API) G2(Calendar API) G3(Drive API) G4(Sheets API) G5(Docs API) G6(Meet API) G7(Directory / Groups) end subgraph BOTH["Shared surface — gcloud + OAuth"] direction TB B1{{IAM Policies}} B2{{Service Accounts}} B3{{OAuth 2.0 Scopes}} B4{{Admin SDK}} B5{{Cloud Identity}} B6{{Secret Manager}} B7{{Audit Logs}} end subgraph GCP["Google Cloud Platform"] direction TB C1(BigQuery) C2(Cloud Run / Functions) C3(Cloud Scheduler) C4(Pub/Sub) C5(Cloud Storage) C6(KMS) end subgraph MKTG["Marketing APIs — auth via GCP"] direction LR M1(Google Ads) M2(GA4 Admin + Data) M3(Tag Manager) M4(Search Console) M5(Merchant Center) end GWS --- BOTH GCP --- BOTH BOTH --> MKTG classDef gws fill:#2a1f14,stroke:#c9a961,color:#e8dcc4,stroke-width:1px; classDef gcp fill:#231711,stroke:#b8553a,color:#e6cfc4,stroke-width:1px; classDef both fill:#1c1a17,stroke:#c9a961,color:#fff3d9,stroke-width:1.5px; classDef mktg fill:#121616,stroke:#5e8a7d,color:#cfe5db,stroke-width:1px; class G1,G2,G3,G4,G5,G6,G7 gws; class C1,C2,C3,C4,C5,C6 gcp; class B1,B2,B3,B4,B5,B6,B7 both; class M1,M2,M3,M4,M5 mktg;
API Deep Dive — 02
Tag Manager API
Containers are just JSON.
List all containers + workspaces
GET /accounts/{id}/containers — read every tag, trigger, variable across all clients at once.
Create and update tags via API
POST /workspaces/{id}/tags — build GA4 events, Meta pixels, custom HTML without touching the UI.
Version, preview, and publish
create_version → quick_preview → publish — full deploy chain in one Claude Code script.
Export containers as JSON
Full backup, diff, rollback, or fork. Every client's container versioned in R2.
Workspace change sets per sprint
Isolated workspace per project — QA tested before merging to live container.
Live MCP: GTM MCP connects directly to the Tag Manager API from Claude Code. Full read/write/publish in natural language.
// Claude Code — GTM audit + fix via MCP const containers = await gtm.listContainers({ accountId }); for (const c of containers) { const ws = await gtm.listWorkspaces(c); const tags = await gtm.listTags(ws[0]); // Find orphan tags — no firing rule attached const orphans = tags.filter(t => !t.firingRuleId?.length); // Find undefined variable references const broken = await validateVariableRefs(tags); // Patch + push to staging workspace for (const tag of [...orphans, ...broken]) { await gtm.updateTag({ ...tag, patch: fixConfig(tag) }); } await gtm.createVersion({ name: `AI Audit — ${new Date().toISOString()}` }); } // Full audit + fix across all containers: ~90 seconds
GTM MCP Container versioning R2 export storage
What's next
gtm-autoresearch — live on GitHub
12-dimension scorer + LLM mutation loop. Pulls live ads data from Meta & Google Ads APIs, then optimizes the GTM container overnight.
Pull ads data
Score config
Mutate via Claude
Validate
Keep/revert
12-dimension signal quality scorer
8 structural (tag coverage, params, dedup, consent, naming, hygiene, triggers, folders) + 4 ads-driven (Meta alignment, CAPI coverage, funnel integrity, Google Ads alignment).
Ads feedback loop
Enriched snapshot from Meta Ads API + Google Ads API before each run. EMQ scores, CAPI/browser split, funnel ratios, conversion action parity.
JSON operations, not full container output
Claude returns add_tag, modify_tag, set_consent_all ops. Applied programmatically, validated against seed. No drift.
~$0.15 per full run
30 rounds × ~3K tokens on Claude Haiku. Stops at 92% plateau or 3 consecutive regressions.
Organized-AI/gtm-autoresearch — TypeScript, Claude CLI mutations, MCP data sources. No API keys needed for GTM/Meta/Google Ads reads.
# refresh ads snapshot (Meta + GAds) npx tsx scripts/refresh-ads-snapshot.ts # run the optimization loop npx tsx scripts/run-gtm-loop.ts # score → mutate → validate → keep/revert # stops at 92% or 3 regressions # run eval standalone npx tsx evals/eval_gtm_signal_quality.ts \ seed/shopify-ecom-web.json \ --enriched-snapshot \ data/signals/ads-snapshot-enriched.json # outputs: # winning/best-95.7pct-2026-04-08.json # loop-results/2026-04-08T184826.json
autoresearch results
Two clients. Real containers.
First runs on production GTM exports — overnight loops with winning configs saved to R2.
HRE Beauty — Shopify 17 tags · 8 triggers
84.3% 95.7%
Consent Mode v2 init tag + consentStatus on all 18 tags
Meta AddPaymentInfo + Search pixel tags added (fixes 15% funnel gap + 67 untracked events)
Meta Ads alignment → 100%, CAPI coverage → 99.4%
5 winning configs tracked over 2 days
BLADE — Multi-platform 105 tags · 42 triggers
53.6% 76.8%
GA4 Config tag added — was completely missing from a 105-tag container
8 GA4 ecommerce event tags created (view_item through purchase)
Consent Mode v2 set on all 105 tracking tags
15 rounds, ~$0.15 total cost on Claude Haiku
Organized-AI/gtm-autoresearch — winning configs, experiment logs, enriched snapshots all in the repo. Never publishes to live.
Real deployments — 1 of 2
Custom builds. Agent-driven from day one.
B2B SaaS / LinkedIn Web + Server GTM
LinkedIn InsightTag 2.0 installed from GTM Community Gallery via API — zero manual UI clicks
5-phase autonomous Claude Code execution: variables → tags → validate → preview → publish with rollback hooks
Skills used: gtm-AI, linkedin-capi-setup, gcp-access-gtm, tidy-gtm
Dual-container deduplication: shared event_id across web GTM (GTM-W9S77T7) and server GTM (GTM-KJHX6KJ7)
Global Coaching Platform Meta Ads + CAPI
Interactive CAPI audit dashboard: 42-task tracker across 5 phases — deployed to Cloudflare Pages in one wrangler pages deploy
£111,974 spend + 27,765 leads + 575 purchases analyzed; 4 critical findings with severity scores surfaced via Meta Ads MCP
Webhook → Cloudflare Worker → Pixel Events + Orders API pipeline — fully programmatic lead attribution
Account health score, campaign performance view, and prioritized recommendations all generated from audit data
Indie Film Release GTM + OpenClaw
GTM deployment plan + Bowser OpenClaw agent integration for audience signal collection and remarketing
Plugin marketplace skills pre-wired in .claude/ — newsletter and LinkedIn post auto-generated from codebase on deploy
MCP server config (.mcp.json) + gtm-debug skill for post-deploy validation without opening GTM UI
Agents driving awareness tracking → conversion attribution end-to-end with zero manual platform logins
Real deployments — 2 of 2
Tracking infrastructure. Signal recovery at scale.
E-Commerce / Health DTC Shopify + sGTM
GAQL audit found $0 conversion values on PMAX — cart data mapping issue in sGTM identified and patched via API without touching the container UI
GA4 Data API pull surfaced major Advantage+ vs. Remarketing budget misallocation — reallocation decision made from a single GAQL query
Shopify Web Pixels API + Stape CAPI restored full server-side checkout event coverage after iOS 14+ signal loss
sGTM → GA4 client → Google Ads ECID pipeline rebuilt programmatically; value tracking confirmed via Ads API query
Healthcare SaaS Next.js + Stripe
Web + sGTM containers bootstrapped from a single JSON template via GTM API — consistent config across all environments
Meta pixel wired exclusively through sGTM CAPI — zero client-side pixel footprint for HIPAA-adjacent compliance posture
State-specific consent law compliance enforced via API-driven tag gating — legal team gets config file, not UI instructions
CareValidate intake events → GA4 Measurement Protocol → Google Ads OCI pipeline built with Node + Cloudflare Worker
Legal Services Custom CMS + Node
Phase 0.5 LP scan (Playwright) ran before any API writes — full baseline JSON captured and stored in R2 for future diffs
Playwright QA gate enforced as hard check — no GTM container published without full tag-firing test suite passing first
Codex QA pass run after every Claude Code change — second-agent review catches naming drift and undefined variables before publish
CRM lead event → GA4 Measurement Protocol + Google Ads Offline Conversion Import in a single Express server pipeline
Hard-won lessons — 1 of 2
Key findings from building this in production.
01
MCP reliability is still a gamble
MCP servers drop connections mid-session, rate-limit silently, and some operations aren't exposed as tools yet. Building mission-critical automation on top of MCP uptime is fragile — one dropped connection kills the whole deploy.
The fix — CLI as foundation
CLI first: gcloud, node scripts, direct API calls. MCP sits on top as a convenience layer. If MCP fails mid-session, the underlying CLI script still runs. Every MCP operation has a CLI fallback in scripts/.
02
Claude needs GTM context loaded explicitly
Out-of-the-box Claude has no GTM mental model. Without a skill, it hallucinates tag type names, wrong trigger IDs, and invalid API parameter schemas — and publishes confidently broken configs. We found this out the hard way.
The fix — domain skills
Skills pre-wired in .claude/skills/: gtm-AI (deploy + audit), tidy-gtm (standardize), linkedin-capi-setup, tracking-validation, data-audit. Each skill injects the correct API schema and tag type registry before Claude writes anything.
03
GTM API real-time builds vs. JSON import fallback
GTM API is fast and surgical — patch a single tag in seconds. But every write requires a valid fingerprint, rate limits appear without warning, and one malformed payload can corrupt the entire workspace state mid-session.
The fix — two-path strategy
API-first for real-time surgical changes. JSON export → Claude edits → import as fallback for bulk operations or when rate limits hit. Both paths tracked in CONFIG/phase-state.json. Claude selects the right path automatically based on operation scope.
Hard-won lessons — 2 of 2
Key findings from building this in production.
04
Naming chaos breaks agent reasoning
Tags named "New Tag 47", variables named "undefined_1" — Claude can't reason about intent from the name. Inconsistent prefixes cause the wrong triggers to fire. Container diffs become noise. Bugs get shipped because the agent inferred wrong.
The fix — tidy-gtm enforces this
Tags: Platform - Type - Event ConvID  ·  Variables: {{DL - name}} {{CJS - name}} {{ED - name}}  ·  Triggers: sGTM - CE - EventName
Convention enforced at write-time by the tidy-gtm skill before every publish. Never manually defined again.
05
GTM Preview is the last manual bottleneck
The GTM Preview UI requires a human: open a browser, paste the preview link, navigate to the site, trigger the events manually, read the tag panel, and confirm each tag fired. This breaks the automation loop completely and adds manual QA time to every deploy.
The fix — Playwright drives preview
Playwright loads the GTM preview URL headlessly, fires synthetic events that match the expected triggers, reads the tag summary panel via DOM, and asserts each expected tag fired with correct parameters. The QA gate runs automatically before every gtm.createVersion() call. Zero human clicks required.
Before — manual preview
Open GTM UI  →  Enter Preview  → 
Open site  →  Trigger events  → 
Read tag panel  →  Screenshot  → 
~8 minutes, zero automation
After — Playwright QA gate
playwright.fire(syntheticEvents)
assert(tagPanel.contains(expected))
gtm.createVersion()  ← only if passes
<30 seconds, fully automated
The business case
What programmatic
actually unlocks
90s
Full container audit
vs. 6 hours manually
10x
Client capacity
Same team, same quality
0
Manual UI clicks
For routine audits
Compounding value
Each pattern improves the next
For agencies: Every client you onboard improves the system. Each audit output trains better prompts. The 10th client is faster than the first — by a lot.
For in-house: Stop being the person who manually checks dashboards. Become the person who built the system that monitors everything and surfaces anomalies automatically.
The real unlock: the Google Suite + CF Dev Platform + GTM API + Ads API + GA4 API — all wired into Claude Code — means your tracking stack is now a conversation, not a series of tabs.
Resources + next steps
Get started today.
Everything is public.
MCP servers — install these first
GTM MCP — Tag Manager API
Tag Manager read/write/publish from Claude.
Google Ads MCP
Full GAQL access + conversion management from Claude.
Meta Ads MCP
Cross-account Meta analysis alongside Google stack.
Cloudflare Developer Platform MCP
Cloudflare Developer Platform MCP — D1, R2, Workers, and GCP infra from Claude.
Organized AI
organizedai.vip  ·  Austin meetups  ·  Claude Code Mastery
Free cert program · job board · plugin marketplace · github.com/Organized-AI
The one prompt to start
# Drop this into Claude Code — right now claude --dangerously-skip-permissions "You are a tracking audit agent. Using the GTM MCP and Google Ads MCP: 1. List all containers for account [ID] 2. Flag tags without firing rules 3. Cross-check conversion actions against GA4 purchase events 4. Generate a remediation plan as JSON 5. Use GWS CLI to log the audit to GCP Secrets Manager 6. Push approved fixes to staging" # That's a full audit + fix cycle. # Time to run: < 2 minutes # Time saved: 6 hours per client
Part 1 replay: "Organized Automation" — Measure Summit recordings. The GTM + sGTM foundation this talk builds on.
Get Started

Tap In With Jordaaan

Ready to deploy your first AI agent fleet on Apple Silicon?

$0
Both deployment modes are free
15 min
Native macOS, any Apple Silicon Mac
12
Pre-wired skills, install-all.sh ready

Start Here

  • Clone github.com/Organized-AI
  • VM-Isolated or Native — your choice
  • Run setup.sh — under 30 min
  • Install 12 skills via install-all.sh
  • Connect a messaging channel
organizedai.vip
github.com/Organized-AI
jobs.organizedai.vip
Scan to Connect
organizedai.vip
organizedai.vip
Website
WhatsApp
OpenClaw Hackathon
WhatsApp Group
LinkedIn
Jordan Hill
LinkedIn
GitHub
Plugin Marketplace
github.com/Organized-AI