The first time I asked Claude to write a GAQL query for me, I lost hours to syntax errors.
The query looked right. Claude was confident. The field names matched what I thought were the right field names. But the API kept rejecting it. Missing date segment. Wrong field path. OR where an IN should have been. Numbers returned in micros when I asked for dollars. Impression share returned as 0.2464 when I expected 24.64%.
Back and forth. Prompt. Test. Fail. Paste the error. Prompt again. Test again. Fail again. I’ve been writing Google Ads queries for years. I knew what I wanted. But getting Claude to generate GAQL that actually runs against the API was a slog.
What fixed it wasn’t better prompting. It was giving Claude a sample of what “right” looks like.
That insight is what the gaql-query-patterns skill exists to codify. It’s a library of battle-tested GAQL queries I use in production — campaign spend, impression share, search terms, keyword quality, RSA performance, geo breakdowns, conversion audits — each one a working example Claude can pattern-match against instead of reconstructing syntax from documentation.
It’s open-sourced as part of my PPC AI Skills repo, and it’s the reason I can now turn a fuzzy question like “show me non-converting search terms over $50 last month” into a working query in under 30 seconds, instead of 45 minutes of debugging.
Here’s why it works, what’s in it, and why reference patterns beat documentation every time when you’re getting AI to write code.
Get the GAQL Query Patterns skill → github.com/fourteenwm/ppc-ai-skills/gaql-query-patterns
Free and open-sourced. Drop the SKILL.md into any Claude Code project in under a minute. No configuration required.
The Core Problem: GAQL Is Not SQL
The hardest thing about GAQL isn’t the complexity. It’s the fact that GAQL looks like SQL. The syntax resembles SQL. The keywords feel like SQL. SELECT, FROM, WHERE, ORDER BY — all present, all familiar.
But GAQL is strict in ways SQL isn’t. And every deviation is a silent trap.
WHERE status = 'ENABLED' OR status = 'PAUSED' — fails. GAQL doesn’t support OR.
Any query with metrics.* fields must include a date segment. Omit it and the query won’t run.
Field paths are hierarchical. campaign.status is right. status alone is wrong.
Monetary values come back as micros. cost_micros = 50000000 means $50.00, not $50 million.
Impression share is a decimal. 0.2464 means 24.64%, not 0.25%.
If you’re a senior PPC specialist asking AI to help with analysis, you already know these rules. The problem is the AI doesn’t consistently apply them — even when you tell it to. Because the rules are nuanced enough that unless the AI has a correct example in front of it, it defaults to SQL-shaped guesses that usually miss.
The fix isn’t “make Claude better at GAQL.” The fix is to stop asking Claude to reconstruct the syntax from first principles every time. Give it working queries to start from.
Templates Over Documentation, Every Time
The pattern I hit over and over with Claude Code is this: documentation helps a little, examples help enormously.
Tell Claude “use GAQL syntax, divide cost_micros by 1,000,000 for dollars, and don’t use OR” — Claude will comply for the next two prompts and then drift. The rules don’t stick.
Paste in a working query with all those rules baked in — Claude pattern-matches against it for the rest of the session. The rules do stick, because they’re not abstract constraints anymore. They’re visible in the code.
That’s the whole value proposition of gaql-query-patterns. It’s not a reference. It’s a seed. Every query in the skill is a correct, runnable example that anchors the model’s behavior for the entire downstream session.
What’s in the Skill
The skill has templates for every query I run often enough that I don’t want to write from scratch:
- Campaign spend analysis (7-day, month-to-date, by budget, by status)
- Impression share diagnostics (Search IS, Budget Lost IS, Rank Lost IS) with interpretation notes
- Search term reports (full SQR and non-converting subset)
- Keyword performance with Quality Score, Post-Click QS, Predicted CTR
- Non-serving keyword detection (180-day zero-impression check for cleanup)
- RSA performance with ad strength
- Conversion action audits (settings, categories, attribution models)
- Geographic and device breakdowns
- Account-level summaries
Each template has a short “Use for” note explaining the investigation it backs. Claude can read the note and pick the right starting template based on context.
When a query doesn’t fit a template exactly, Claude can combine fields from two templates, swap the date range, add a filter. But it’s working from a correct base, not a reconstructed one.
The Micros Trap
This is the single most expensive GAQL gotcha I’ve seen.
Monetary values in the Google Ads API come back in micros. cost_micros = 50000000 is $50. cost_micros = 1234567 is $1.23. Dividing by 1,000,000 is mandatory before displaying anything to a human.
The failure mode: an AI writes a report that says “this campaign spent $47,000,000 last month” because it didn’t convert from micros. If that number goes to a client before anyone catches it, the conversation that follows is not fun.
Every template in the skill has a note reminding the AI about the micros conversion. Not because Claude forgets the rule. Because reminders in the code are stickier than reminders in the prompt.
Impression Share Returns Decimals
Second most common interpretation error.
The Google Ads API returns impression share as a decimal between 0 and 1. 0.2464 means the campaign captured 24.64% of available impressions. An AI reading that value raw and writing “impression share was 0.25” has technically reported the number correctly, but any PPC manager reading the output will assume “0.25” means 25 basis points, which would mean the campaign is basically invisible.
Same story as micros. The template has the conversion note inline. The AI sees it, applies it, and the downstream report is correct.
GAQL Doesn’t Do OR
If you’ve written any SQL, your instinct for a multi-status filter is:
WHERE campaign.status = 'ENABLED' OR campaign.status = 'PAUSED'
GAQL rejects that outright. The right syntax is:
WHERE campaign.status IN ('ENABLED', 'PAUSED')
Minor thing. But in a multi-hour investigation where Claude drafts 10 different queries, that one syntax error shows up over and over unless there’s a reference example steering it away. The skill has the IN pattern throughout.
When Templates Don’t Fit — Build From the Closest One
The skill isn’t a menu. It’s a starting library. Most real investigations need a query that doesn’t exist in the library exactly. Different date range. Custom filter. Joined with a segment that isn’t in any template.
The rule is: start from the template closest to the need, then modify. Don’t start from a blank line.
Starting from a blank line is where the hours-lost problem comes from. Starting from a working query and modifying two fields is where the 30-second construction comes from.
What This Has Actually Prevented
Since I built the skill and dropped it into every agent that needs to query Google Ads data:
- Hours of syntax debugging — the biggest single source of friction in my old workflow, gone.
- Client-facing micros errors — no more $47M spend reports because the conversion happens at template level, not “remember to convert later.”
- Impression share misreads — the interpretation notes catch the decimal-versus-percentage confusion before it makes it into a deliverable.
ORfailures — Claude now reaches forINwithout prompting, because every template models it.- Missing date segment errors — every template has the
WHERE segments.dateclause visible, so Claude keeps including it.
None of these catches are dramatic. They’re friction I used to absorb every time I ran an investigation, and they’re gone now.
Get the GAQL Query Patterns Skill
Install in 30 seconds
Copy the SKILL.md file into your Claude Code project:
mkdir -p .claude/skills/gaql-query-patterns
curl -o .claude/skills/gaql-query-patterns/SKILL.md \
https://raw.githubusercontent.com/fourteenwm/ppc-ai-skills/main/gaql-query-patterns/SKILL.mdClaude Code auto-loads the skill when any agent or script needs to query Google Ads data. No configuration required. Works with any AI harness that respects skill files — I built it for Claude Code but the patterns are portable.
Free. Open-sourced. MIT licensed.
The full repo has dozens of other PPC AI skills I use in production every day — mutation safety, SQR classification, impression share diagnostics, ad copy verification, and more. All at github.com/fourteenwm/ppc-ai-skills.
The Bigger Point
Most AI-in-PPC conversations treat the model as the thing to optimize. Better prompts. More context. Larger models. The hidden cost of that framing is that it puts the burden on the human to keep restating the rules.
Reference patterns flip that. Instead of reminding the AI how GAQL works, you give it working GAQL. Instead of teaching the rules in prose, you encode them in example. The AI pattern-matches against the examples, and the rules stick for the whole session, not just the next prompt.
This is why every AI coding system that actually ships uses examples, not docs. Docs tell you what. Examples show you how. For a language as strict and easy-to-mistype as GAQL, the difference is hours.
Codify the correct answer once. Reuse it forever. That’s the whole game.