How to audit a Google Ads account with Claude: 50 checks
All 50 checks with the rule, query and fix for each, the 8 exports to pull, and the prompt that has Claude run them for you.
A Google Ads audit is a read-only review of tracking, settings, keywords, search terms, ads and automation that ends in a list of fixes ranked by the money each one puts at risk. Start with conversion tracking, because every cost per conversion depends on it, then run the 50 checks below from CSV exports or let Claude run them through Google Ads Query Language (GAQL).
The checks below come from google-ads-account-audit, an MIT licensed skill in adwarp-dev/paid-ads-skills, down to each threshold and query. It never writes to the account, so the fixes are yours to make in Google Ads.
What a Google Ads audit covers
The skill runs 50 checks in 11 areas, in the order below. It scores Search, Performance Max and AI Max campaigns, and lists Display, Video, Demand Gen, App and Shopping campaigns as out of scope.
| Order | Area | Checks | It asks |
|---|---|---|---|
| 1 | Conversion tracking | C1 to C9 | Are the conversions Google bids on real? |
| 2 | Campaign settings | S1 to S9 | Is money leaking to the wrong networks or places? |
| 3 | Structure | T1, T2 | Can every ad group serve? |
| 4 | Keywords | K1 to K5 | Which keywords cost too much per conversion? |
| 5 | Search terms | Q1 to Q4 | How much goes to searches that never convert? |
| 6 | Negatives | N1 to N4 | Do negatives cover every campaign? |
| 7 | Responsive search ads | R1 to R5 | Does each ad group have enough approved ads? |
| 8 | Assets | A1, A2 | Are sitelinks and the other assets in place? |
| 9 | Performance Max | P1 to P4 | Does it overlap your Search campaigns? |
| 10 | AI Max for Search | X1 to X3 | Do AI Max matches pay their way? |
| 11 | Recommendations and change history | H1 to H3 | What did Google change for you? |
Each check ends as pass, warn, fail, n/a or not checked. In the tables, T means your target cost per acquisition, and "judgment call" marks a threshold the skill chose that you can change. Google's help pages set the rest.
Google's help pages, API guides and access levels quoted in this post were checked on 2026-11-07.
Queries carry a leading zero, Q01 to Q21, so they don't get confused with the search term checks Q1 to Q4. A few IDs hold more than 1 query, and all 31 are in references/gaql-checks.md.
The report opens with a scorecard that grades each area as (passes + 0.5 x warns) / (passes + warns + fails) x 100. The checklist below does the same math on your marks and downloads all 50 checks as a CSV.
Audit checklist, 50 checks
Mark each check as you go. Pick an area in the scorecard to see its checks, and press a result again to clear it.
Overall not scored yet · 0 pass, 0 warn, 0 fail, 0 n/a, 50 not checked
Conversion tracking, C1 to C9
- C1Conversion tracking is onQ01
- C2A primary action is firingQ02, Q03
- C3Primary actions are business outcomesQ02
- C4No double countingQ02, Q03
- C5Counting matches the actionQ02
- C6Values exist when bidding on valueQ02, Q04
- C7Enhanced conversionsQ01
- C8Consent Mode is active (European Economic Area, UK, Switzerland)None, UI only
- C9Auto-tagging is onQ01
Score = (passes + 0.5 x warns) / (passes + warns + fails) x 100, rounded, per area and overall. N/a and unmarked checks stay out of the score.
Checks, rules and queries: google-ads-account-audit (MIT). The example is the made-up Fernhill account from the skill's examples folder. Sources in the CSV were checked 2026-11-07.
Before you start
Pick the window and the target first, then decide where the data comes from: CSV exports with nothing connected, or GAQL through Claude, which also reads account settings that no export carries.
Pick a window and a target cost per acquisition
The skill uses the last 30 days unless you name another window. With no target, it takes the account's own cost per conversion over the window and labels it "account average, used as target". Recent days undercount conversions, so for a long sales cycle end the window 7 days ago (a judgment call).
Option 1, CSV exports
In Google Ads, open each page below, set the window, click the download icon above the table and pick Excel CSV (Google Ads Help).
| Report | Where in Google Ads | Columns the checks use | Checks |
|---|---|---|---|
| Campaigns | Campaigns > Campaigns | Budget, Bid strategy type, Cost, Conversions, Conv. value, Search impr. share, Search lost IS (budget) and (rank) | S5 to S9 |
| Campaigns by network | The same table, segmented by network with search partners shown separately | Network, Cost, Clicks, Conversions | S1, S2 |
| Keywords | Campaigns > Keywords, with the Quality Score columns added | Keyword, Match type, Status, Max. CPC, Quality Score, Exp. CTR, Ad Relevance, Landing Page Exp., Cost, Conversions | S6, T2, K1 to K5 |
| Search terms | Insights and reports > Search terms, plus its Performance Max view | Search term, Match type, Added/Excluded, Keyword, Cost, Conversions | Q1 to Q4, P4 |
| Ads | Campaigns > Ads | Ad type, Status, Ad strength, Cost, Conversions | R1, R2, R5 |
| Conversions summary | Goals > Conversions > Summary | Conversion action, Action optimization, Source, Category, Count, Status, All conv. | C2 to C6 |
| Change history | Campaigns > Change history | Date and time, User, Campaign, Changes | H2, H3 |
| Google Ads Editor export | Account > Export > whole account | Networks, Targeting method, Bid Strategy Type, Headline 1 to 15 with positions, Description 1 to 4, Keyword, Criterion Type | S1 to S4, R3, R4, N1 to N3, A1, A2 |
Option 2, GAQL through Claude
Claude runs each check's query through an MCP server, set up in Run the whole audit with Claude. The audit only reads, so Explorer access is enough: 2,880 operations a day on production accounts, per Google's access levels page.
The same page says developer tokens were sunset on September 9, 2026. Access now belongs to a Google Cloud project, where enabling the Google Ads API grants Test access and you apply for Explorer in the Cloud Console.
If you read the rows yourself, divide any field ending in _micros by 1,000,000 to get account currency. GAQL has no LAST_90_DAYS, so a longer window is written segments.date BETWEEN '2026-07-01' AND '2026-09-30'.
5 settings no report shows
For these, screenshot each setting page or mark the check "not checked". The skill never guesses a setting.
- Auto-tagging (C9): Admin > Account settings. Q01 reads it.
- Enhanced conversions (C7): Goals > Settings. Q01 reads this one too.
- Consent Mode (C8): Goals > Conversions > Summary, a website action, then Diagnostics. No API field reports it.
- Auto-apply (H1): the Recommendations page. Q20 sees only the types the API supports.
- AI Max (X1 to X3): campaign settings, or queries Q04, Q12 and Q13.
Conversion tracking (C1 to C9)
Smart Bidding learns from primary conversion actions, and every cost per conversion in this audit divides by them. Google's help page says primary actions are "used for bidding" when their goal is, and secondary ones are "for observation only" (Google Ads Help).
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| C1 | Conversion tracking is on (Q01) | Status is NOT_CONVERSION_TRACKED | - | Goals > Conversions > New conversion action |
| C2 | A primary action is firing (Q02, Q03) | No enabled primary action converted in 30 days | Newest primary conversion is 8 to 30 days old (judgment call) | Open the action's Diagnostics, then test the thank-you page with Tag Assistant |
| C3 | Primary actions are business outcomes (Q02) | Every primary action is a page view, engagement or outbound click | One of those is primary next to real outcomes | Set it to Secondary under Action optimization |
| C4 | No double counting (Q02, Q03) | - | 2 or more primary actions in the same category both record conversions, such as a Google tag form fill and a Google Analytics 4 generate_lead (judgment call) | Keep 1 primary, set the other to Secondary |
| C5 | Counting matches the action (Q02) | - | A lead category counts every conversion, or a purchase counts 1 | Edit settings > Count |
| C6 | Values exist when bidding on value (Q02, Q04) | Value-based bidding with 0 conversion value in 30 days | Every primary action always uses its default value | Send a value in the tag, or bid on conversions instead |
| C7 | Enhanced conversions (Q01) | - | Effective setting off, or customer data terms not accepted | Goals > Settings: accept the terms, send hashed email from the form |
| C8 | Consent Mode is active for European Economic Area, UK and Swiss traffic | - | Diagnostics shows no active status | UI only: the action's Diagnostics tab |
| C9 | Auto-tagging is on (Q01) | Off | - | Admin > Account settings > Auto-tagging |
If C1 or C2 fails, the skill marks S1, S2, S5 to S9, K1, K5, Q1, Q3, Q4, P4 and X1 "unreliable: tracking" and still reports their raw spend.
C5 follows Google's counting guide, which says usually only 1 lead per ad click adds value while every sale does (Google Ads Help). For C8, give a new Consent Mode setup time: its status can take 48 hours to show in Diagnostics, and up to 2 weeks in some cases (Tag Manager Help).
Q01 reads 3 of these checks in 1 call:
SELECT customer.id, customer.descriptive_name, customer.currency_code, customer.time_zone,
customer.auto_tagging_enabled,
customer.conversion_tracking_setting.conversion_tracking_status,
customer.conversion_tracking_setting.accepted_customer_data_terms,
customer.conversion_tracking_setting.enablement_setting,
customer.conversion_tracking_setting.effective_enablement_setting
FROM customerThat's the v26 form. Adwarp pins API v25 unless ADWARP_GOOGLE_API_VERSION says otherwise, and on v25 the last 2 fields become customer.conversion_tracking_setting.enhanced_conversions_for_leads_enabled. It covers leads only, so check web enhanced conversions in the UI.
Campaign settings (S1 to S9)
Settings decide where the money can go before any keyword matches. Most of these checks compare a campaign with T, or its partner and Display traffic with its own Google Search traffic.
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| S1 | Search partners on Search campaigns (Q04, Q05) | Partners cost per conversion over 1.5x Google Search's (judgment call), or partners cost over 2x T with 0 conversions | Partners on | Networks: untick Google search partners |
| S2 | Display expansion on Search campaigns (Q04, Q05) | The same test on Display traffic | Display on | Networks: untick Display Network, or set it to Low priority with a budget cap |
| S3 | Location option is presence (Q04, Q07) | - | Presence or interest, with over 5% of cost from outside the targeted countries or worse results on area-of-interest traffic (judgment calls) | Locations > Location options > Presence |
| S4 | Location targeting exists (Q04, Q06) | A Search or Performance Max campaign has no positive location, or reports MISSING_LOCATION_TARGETING | - | Campaign settings > Locations |
| S5 | Bidding matches conversion volume (Q04) | - | Target cost per acquisition, or Maximize conversions with a target, under 30 conversions in 30 days. Target return on ad spend, or Maximize conversion value with a target, under 50 | Pool campaigns, raise the target, or bid on a higher-volume action |
| S6 | Broad match runs with Smart Bidding (Q09) | Broad keywords on manual or click bidding spent over 2x T with 0 conversions | Any enabled broad keyword on manual or click bidding | Phrase or exact, or Smart Bidding once S5 passes |
| S7 | Budget-limited campaigns (Q04) | - | 10% or more of impressions lost to budget (judgment call) | On target, move budget from campaigns over target. Over target, fix efficiency first |
| S8 | Rank-limited campaigns (Q04) | - | 50% or more lost to rank on a campaign at or under T (judgment call) | Raise bids on converting keywords, or fix the Below average components from K2 |
| S9 | Campaigns that spend without converting (Q04) | Cost over 2x T, 0 conversions (judgment call) | Cost 1x to 2x T, 0 conversions | Pause, or narrow to the ad groups that convert |
Q05 splits each Search campaign by network: SEARCH is Google Search, SEARCH_PARTNERS is search partners and CONTENT is the Display Network.
SELECT campaign.id, campaign.name, segments.ad_network_type,
metrics.cost_micros, metrics.clicks, metrics.conversions
FROM campaign
WHERE campaign.advertising_channel_type = 'SEARCH' AND campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYSGoogle's own page on the Search Network warns that partner clicks "may not always reflect highly targeted traffic" (Google Ads Help).
Google is changing Display expansion. It added High and Low priority tiers in October 2026, and from February 2027 Search campaigns with Display Expansion move to channel prioritization automatically, which Google warns can shift spend between Google Search, search partners and Display (Google Ads Help). The skill found no API field for the tiers, so read them in campaign settings.
Presence or interest is Google's default and recommended location option (Google Ads Help), and it suits a business people travel to. S3 warns only when the data shows leakage.
For S5, Google lets target cost per acquisition bidding start with no history but recommends judging it over 30 days with at least 30 conversions (Google Ads Help), or 50 for target return on ad spend (Google Ads Help). S6 rests on 1 line in Google's match type guide: "It's critical to use Smart Bidding with broad match" (Google Ads Help).
Structure and keywords (T1, T2, K1 to K5)
T2 looks for brand keywords inside non-brand campaigns. They convert cheaply and drag the blended cost per conversion down, so a shared target ends up overbidding on brand. The keyword checks after it hunt for cost without conversions, by match type and keyword by keyword.
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| T1 | Enabled ad groups can serve (Q08) | Reason includes NO_AD_GROUP_ADS, NO_KEYWORDS or AD_GROUP_INCOMPLETE | - | Add an ad and keywords, or pause the ad group |
| T2 | Brand and non-brand are split (Q09) | - | A campaign mixes keywords with and without your brand terms (judgment call) | Give brand its own campaign, add brand negatives elsewhere |
| K1 | Cost per conversion by match type (Q09) | - | A match type over 1.5x the account's cost per conversion, with cost over 2x T (judgment calls) | Move its weakest keywords to phrase or exact |
| K2 | Quality Score components on top keywords (Q09) | - | A keyword in the top 80% of spend has a Below average component | By component: headlines that repeat the query, a split ad group, or a page about the keyword |
| K3 | Keywords that can't serve (Q10) | Disapproved | Rarely served (Low search volume) or below first page bid | Rewrite or appeal, swap rarely served terms, raise bids only where the keyword converts |
| K4 | Duplicate keywords (Q09) | - | Same text and match type enabled in 2 or more ad groups (judgment call) | Keep the copy whose ads fit, pause the rest |
| K5 | Keywords that spend without converting (Q09) | Cost over 2x T, 0 conversions (judgment call) | Cost 1x to 2x T, 0 conversions | Pause, or narrow the match type |
Google's help page says Quality Score "is not an input in the ad auction" and "should not be optimized or aggregated with the rest of your data" (About Quality Score). K2 never averages it and reads the 3 components only on the keywords that carry the spend.
K3 has its own query, Q10, because a keyword with 0 impressions never appears in Q09's performance rows.
Search terms and negatives (Q1 to Q4, N1 to N4)
The search terms report is where waste shows, though not all of it. Google says "some search terms that don't have enough query activity are omitted from the search terms report" to meet its privacy standards (Google Ads Help). So the waste Q1 reports is a floor, and Q2 measures how much of the cost shows up in the report at all.
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| Q1 | Wasted search term spend (Q11) | Zero-conversion terms over 2x T each make up over 10% of search term cost (judgment calls) | 5% to 10% | Negatives from google-ads-search-terms |
| Q2 | Share of cost you can see (Q11, Q04) | - | Search term cost under 70% of Search campaign cost (judgment call) | None: report Q1 as a floor |
| Q3 | Close variant and expansion drift (Q11) | - | Close variant, broad and AI Max matches over 1.5x the exact match cost per conversion (judgment call) | Negatives for the drifting terms, and X1 for AI Max |
| Q4 | Converting terms not yet keywords (Q11) | - | 2 or more conversions at or under T, not a keyword (upside, judgment call) | Add them as exact keywords |
| N1 | Every Search campaign has negatives (Q14, Q15) | None from any source, with cost over 2x T | None, with lower cost | Attach a list in Tools > Exclusion lists > Negative keyword lists |
| N2 | Shared lists are attached (Q15) | - | A list attached to 0 campaigns, or to some Search campaigns and not others | Attach it everywhere or remove it |
| N3 | Negatives don't block keywords (Q10, Q14, Q15) | A keyword reports CAMPAIGN_CRITERION_NEGATIVE, or a negative blocks its own text | - | Remove or narrow the negative |
| N4 | Account-level negatives cover Performance Max and AI Max (Q15) | - | Either runs with no account-level list linked | Admin > Account settings > Negative keywords |
SELECT campaign.id, campaign.name, ad_group.id, ad_group.name,
search_term_view.search_term, search_term_view.status,
segments.search_term_match_type,
metrics.cost_micros, metrics.clicks, metrics.impressions,
metrics.conversions, metrics.conversions_value
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS AND metrics.impressions > 0Q3 groups these rows by segments.search_term_match_type and compares NEAR_EXACT, NEAR_PHRASE, BROAD and AI_MAX with EXACT.
N3 applies Google's negative matching rules (Google Ads Help). A negative broad keyword blocks a query holding all its words in any order, a negative phrase needs them in order, and a negative exact needs the same words with nothing added. Negatives don't match close variants.
The account-level list in N4 takes up to 1,000 negatives and covers Search and Shopping inventory in Search, Performance Max, App, Shopping, Smart and Local campaigns (Google Ads Help).
The audit sizes the waste. For the full negative list and an upload file, run google-ads-search-terms.
Responsive search ads and assets (R1 to R5, A1, A2)
Google asks for "at least 2 responsive search ads (RSA) with 'Good' or 'Excellent' Ad Strength per ad group" and allows up to 15 headlines and 4 descriptions in each ad (Google Ads Help). An ad group takes 3 enabled responsive search ads at most (account limits).
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| R1 | Responsive search ads per ad group (Q16) | 0 enabled | 1 enabled | Add a second, up to Google's 3 |
| R2 | Ad strength (Q16) | - | An ad with spend rated Poor or Average | Unique headlines that use the ad group's keywords |
| R3 | Enough headlines and descriptions (Q16) | - | Under 8 headlines or under 3 descriptions (judgment call) | Fill toward 15 and 4 |
| R4 | Pinning (Q16) | - | Over half the headlines pinned, or a pinned position with 1 headline (judgment call) | Unpin, or pin 2 or 3 headlines to the same position |
| R5 | Policy status (Q16) | An enabled ad is disapproved | Approved (limited) | Status column > policy details: edit or appeal |
| A1 | Sitelinks (Q17) | Under 2 eligible at campaign or account level | Under 6 | Add sitelinks, at account level when they fit every campaign |
| A2 | Callouts, structured snippets, business name and logo (Q17) | - | Any of the 4 missing (judgment call) | Add the missing type |
R2 never fails. Google says Ad Strength "doesn't determine whether your ad is eligible to serve" and "isn't used to calculate Ad Rank, Quality Score, or auction wins" (About Ad Strength).
R4 takes Google's line that pinning "isn't recommended for most advertisers and can affect ad strength".
For A1, sitelinks need at least 2 to show, and Google's tip is at least 6 with descriptions (Google Ads Help).
Performance Max (P1 to P4)
Performance Max can show on the same searches as your Search campaigns. P1 and P3 look at that overlap through brand and search themes. P2 grades the asset groups, and P4 prices the Performance Max search terms that never convert.
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| P1 | Brand exclusions (Q18, Q19) | Brand terms over 10% of the campaign's search term cost, no brand exclusion (judgment call) | No brand exclusion while a brand Search campaign runs | Campaign settings > Brand exclusions |
| P2 | Asset group health (Q18) | - | Ad strength Poor or Average, or status Not eligible or Limited | Add the asset types the asset group page lists as missing |
| P3 | Search themes (Q18) | - | A theme repeats a phrase or broad Search keyword | Remove the theme, or make the keyword exact |
| P4 | Performance Max search term waste (Q19) | Zero-conversion terms over 2x T each (judgment call) | 1x to 2x T | Campaign negatives, or the account-level list |
Brand exclusions in Performance Max apply to Search and Shopping inventory (Google Ads Help). An asset group takes up to 25 search themes, and they get "the same prioritization as your phrase match and broad match keywords in Search campaigns", while an exact keyword identical to the query still wins (Google Ads Help).
P4 reads campaign_search_term_view, because search_term_view has no Performance Max cost. In Google Ads, it's the "Search terms and landing pages for Performance Max" view of the search terms report (Google Ads Help).
AI Max for Search (X1 to X3)
AI Max lets Google match searches beyond your keywords and adapt ad text and landing pages. Google's API guide says that under AI Max "all keywords are treated as broad match by default" (Google Ads API).
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| X1 | AI Max matches pay their way (Q12) | AI Max matches spent over 2x T with 0 conversions | AI Max cost per conversion over 1.5x the keyword matches' (judgment call) | Turn off search term matching on weak ad groups, or AI Max for the campaign |
| X2 | Auto-migrated campaigns reviewed (Q04) | - | A broad match or automatically created assets migration date is set | Review AI Max, text customization and final URL expansion, and decide each on purpose |
| X3 | Final URL expansion and pins (Q13, Q16) | - | Final URL expansion is on and the ads rely on pinned text | Turn final URL expansion off, or exclude the URLs that need the pins |
Q12 splits search terms by segments.search_term_match_source and compares the AI_MAX_KEYWORDLESS and AI_MAX_BROAD_MATCH rows with ADVERTISER_PROVIDED_KEYWORD (AI Max reporting). It runs only when campaign.ai_max_setting.enable_ai_max is true.
For X2, API v25 added broad_match_migration_date_time and aca_migration_date_time, which record when Google moved a campaign to AI Max. X3 matters if your ads carry required text, since Google says "pinned assets aren't used if a more relevant URL is chosen" (Google Ads Help).
Auto-applied recommendations and change history (H1 to H3)
In the made-up Fernhill account, change history shows Google's recommendations adding the broad match keyword "scheduling software" on October 18, and switching on search partners in a competitor campaign on October 2. Nobody on the team made either change. H1 to H3 find which auto-apply types are on and what they did.
| ID | Check | Fail | Warn | Fix |
|---|---|---|---|---|
| H1 | Auto-apply recommendations (Q20) | On for broad match, search partners or Display expansion | On for keywords or bidding types | Turn those types off in the auto-apply settings on the Recommendations page |
| H2 | Changes made by Google recommendations (Q21) | - | A recommendation changed networks, bidding or keywords in the last 30 days | Review each in Change history and undo what you didn't intend |
| H3 | Change churn on Smart Bidding campaigns (Q21) | - | More than 3 bidding, target or budget changes on 1 campaign in 14 days (judgment call) | Change targets less often, since each change makes the strategy recalibrate |
SELECT recommendation_subscription.type, recommendation_subscription.status,
recommendation_subscription.create_date_time, recommendation_subscription.modify_date_time
FROM recommendation_subscriptionH1 fails on an enabled USE_BROAD_MATCH_KEYWORD, SEARCH_PARTNERS_OPT_IN or DISPLAY_EXPANSION_OPT_IN subscription. The API doesn't cover every auto-apply type (Google Ads API), so also open the Recommendations page, where "Add broad match keywords" and "Use Display expansion" are among the options (Google Ads Help).
H2 and H3 read change_event, which needs a date filter inside the last 30 days and a LIMIT of 10,000 rows or fewer, and doesn't return Google Ads Editor changes (Google Ads API).
Turn findings into fixes ranked by spend at risk
To order the fixes, the skill prices every finding in account currency for the window, with the rules below. The scorecard stays secondary: by the skill's own rule, the score never outranks this list.
| Finding | Spend at risk |
|---|---|
| Zero-conversion spend (S9, K5, Q1, P4, the broad keywords in S6) | The cost of the failing rows, counting each keyword or search term once |
| Network leak (S1, S2) | Network cost minus network conversions x Google Search cost per conversion in the same campaign, floored at 0. If Google Search has no conversions, the whole network cost |
| Location leak (S3) | Cost from people outside the targeted countries, plus area-of-interest cost when it converts worse than presence |
| Cost per conversion gap (K1, Q3, X1) | Cost minus conversions x T, floored at 0 |
| Measurement (C1 to C6) | No figure. Labeled "blocks bidding" with the spend of the Smart Bidding campaigns that learn from the action, or "blocks reporting" |
| Budget-limited on target (S7) | Upside: conversions x impression share lost to budget / impression share, labeled a rough estimate |
The fix list then runs in this order:
- Measurement findings, any fail or warn on C1 to C6, with the cost per acquisition as reported next to the one counting only the primary action that matches the business goal.
- Quantified findings by spend at risk, largest first.
- Upside from S7 and Q4.
- Warnings with no dollar figure, ordered by the spend of the campaigns they touch.
Measurement goes first without a figure because a double-counted lead changes every cost per conversion in the report, and Smart Bidding learns from that count. A search partners finding measured on it can point the wrong way.
Thin data gets no verdict. A cost per conversion check needs at least 2x T of cost in the slice or it's marked "too little data", and Q3, K1 and X1 need 10 conversions in the comparison group (judgment call).
Run the whole audit with Claude
The skill runs in Claude Code, Codex, Cursor and other agents that read SKILL.md files. It works from the CSV exports alone, and with an MCP server connected it runs the queries itself.
- Install the skills with
npx skills add adwarp-dev/paid-ads-skills. - Connect Adwarp or Google's MCP server, or skip this and use exports.
- Paste the prompt.
- Read the report, starting with "Do these 3 first".
npx skills add adwarp-dev/paid-ads-skills
claude mcp add adwarp -- npx -y adwarp mcp
npx adwarp google auth loginAdwarp is a free, MIT licensed MCP server and CLI for LinkedIn Ads and Google Ads that runs from your terminal (Google Ads setup). Claude runs each query through gads_search, which refuses anything but a SELECT, and pulls conversion actions with gads_list_conversion_actions and search terms with gads_performance. From a terminal, the same query is adwarp google query "<GAQL>". The Google tools run only on your machine, because the hosted endpoint serves LinkedIn Ads.
Google's Google Ads MCP server runs the same GAQL through its search tool. It also has tools that create assets and labels, and its README says to set labels: false and assets: false in tools_config.yaml for a strictly read-only setup.
> Audit Google Ads account 123-456-7890 for the last 30 days with the google-ads-account-audit skill. Target cost per acquisition is 150 USD. Read only, change nothing.
adwarp.gads_search Q01 account settings: 1 row
adwarp.gads_list_conversion_actions 123-456-7890: actions
adwarp.gads_search Q04 campaigns, last 30 days: by campaign
adwarp.gads_search Q05 cost by network: by network
adwarp.gads_performance search_term, last_30_days: by cost
Then Q02, Q03 and Q06 to Q21, each a SELECT
50 checks run. Nothing was written to the account.
Scorecard, fixes ranked by spend at risk, 3 to do first
The prompt
Name the account, the window, the target and your brand terms, and say read only.
Audit Google Ads account 123-456-7890 for the last 30 days with the
google-ads-account-audit skill. Target cost per acquisition is 150 USD.
Our brand terms are "fernhill". Read only, change nothing.For exports, start with "Audit the Google Ads exports in this folder" and put the 8 CSV files in it.
A sample report
This is the skill's report on the made-up Fernhill exports, cut down to the scorecard, the top 5 fixes and "Do these 3 first". 19 checks show "not checked" because exports carry no negatives, assets, Performance Max detail or the 5 settings above. A connected run fills them in.
# Google Ads audit: Fernhill (made-up account)
Window: 2026-09-21 to 2026-10-20 | Currency: USD | Target CPA: $150.00 (user target)
Data: Export mode | Campaigns in scope: 4 Search, 1 Performance Max | Out of scope: none
## Scorecard
| Area | Pass | Warn | Fail | Not checked | Score |
| --- | --- | --- | --- | --- | --- |
| Conversion tracking | 2 | 3 | 0 | 3 (+1 n/a) | 70 |
| Campaign settings | 2 | 3 | 3 | 1 | 44 |
| Structure | 1 | 0 | 0 | 1 | 100 |
| Keywords | 0 | 4 | 1 | 0 | 40 |
| Search terms | 1 | 2 | 1 | 0 | 50 |
| Negatives | 0 | 0 | 0 | 4 | not scored |
| Responsive search ads | 0 | 4 | 1 | 0 | 40 |
| Assets | 0 | 0 | 0 | 2 | not scored |
| Performance Max | 0 | 0 | 0 | 4 | not scored |
| AI Max | 0 | 0 | 0 | 3 | not scored |
| Recommendations and history | 0 | 2 | 0 | 1 | 50 |
| Overall | 6 | 18 | 6 | 19 (+1 n/a) | 50 |
Spend at risk in the window: $5,366.19 (27.8% of $19,280.00 total cost), counting each campaign, keyword and search term once.
Measurement first: reported conversions are 135, so reported CPA is $142.81. Counting only "Demo request (Google tag)" (88), CPA is $219.09, above the $150.00 target.
## Fixes ranked by spend at risk
| # | Check | Finding | Spend at risk | Fix |
| --- | --- | --- | --- | --- |
| 1 | C4 Double counting | 2 primary "Submit lead form" actions both record conversions: "Demo request (Google tag)" (88) and "GA4 generate_lead" (31) | Blocks bidding ($11,040.00) | Goals > Conversions > Summary: set "GA4 generate_lead" to Secondary |
| 2 | C3 Micro action as primary | A booking link click (Outbound click, 16 conversions) is primary | Blocks bidding ($11,040.00) | Set it to Secondary in Action optimization |
| 3 | C5 Counting | "Demo request (Google tag)" counts every conversion | Blocks bidding ($11,040.00) | Edit "Demo request (Google tag)" > Count > One |
| 4 | S9 Spends without converting | Search - Competitors: $1,790.00, 350 clicks, 0 conversions | $1,790.00 | Pause the campaign, or rebuild it with exact terms and a CPA cap |
| 5 | Q1 Wasted search terms | 5 terms outside Search - Competitors, 0 conversions, each over $300 | $1,980.00 | Run google-ads-search-terms for the negative list |
## Do these 3 first
1. Fix conversion counting (C4, C3, C5): 1 primary lead action counted once per click.
2. Pause or rebuild Search - Competitors (S9): $1,790.00 in 30 days with 0 conversions.
3. Turn off search partners on Search - Crew Scheduling and Search - Field Service (S1, $1,032.19 excess cost) and add the negatives from google-ads-search-terms (Q1, $1,980.00).Every threshold and the full report format are on the google-ads-account-audit docs page.
How often to audit
Run the full audit when an account changes hands and once a quarter. When cost per acquisition jumps, run the 9 tracking checks before anyone touches bids or budgets.
The API's change history reaches back only 30 days, so read the rest of the quarter on the Change history page in Google Ads, which keeps 2 years (Google Ads Help). February 2027 belongs on the calendar too. That's when Google moves Search campaigns with Display expansion to channel prioritization, so review every campaign S2 flags before then.
Between audits, paid-media-health-check runs a daily check that stays quiet unless something is wrong. For more on running Google Ads from Claude, see Google Ads in Claude and Google Ads reporting.
Put it to work
Google Ads in Claude
Connect Claude Code to Google Ads with Adwarp and run the audit's queries from your terminal.
adwarp.dev/google-ads/claudeBy Stan Rymkiewicz, maintainer of adwarp. Published November 7, 2026.