google-ads
Skill10 starsChanged 7 months agoMITView on GitHub
Create, query, audit, and optimize Google Ads campaigns via the Google Ads API (Python SDK). Use for campaign management, performance analysis, keyword optimization, and ad creation.
- Installs packages
We split this skill into the rules it gives an agent
5 rules. 0 are common, 3 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 25 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 59
If API is not configured, guide the user through references/api-setup.md.
- Distinctive: line 82
Before writing any campaign creation code, document:
- Very specific: line 287
If the API is truly unavailable (no developer token, client account without API access), browser automation can work for read-only checks.
- Distinctive: line 294
Not suitable for mutations (pausing, budget changes) — too risky without confirmation loops
- Distinctive: line 302
When reporting findings, use clear tables:
“Common” is measured: kept by at least 6 in 10 of the 25 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Google Ads Management Skill
Comprehensive skill for managing Google Ads accounts via the Google Ads API.
Why This Skill Exists
The Problem:
Google Ads management requires precise, methodical work. Missed settings cause wasted spend. Forgotten fields cause API rejections. Small mistakes compound into big losses.
The Solution:
This skill provides battle-tested checklists, query templates, and workflows for common Google Ads operations. It captures lessons learned from real production use — the gotchas that aren't in the official docs.
What it prevents:
- Campaign creation with broken landing pages ($$ wasted on 404s)
- RSA text rejections (character limits are strict)
- Missing required fields that cause API errors
- Pausing the wrong campaigns
- Forgetting to set end dates on promotional campaigns
When to Use This Skill
| Task | Use This Skill |
| Check campaign performance | ✅ Yes |
| Create new campaigns/ads | ✅ Yes |
| Find wasted spend | ✅ Yes |
| Pause underperforming keywords | ✅ Yes |
| Adjust budgets | ✅ Yes |
| Audit account health | ✅ Yes |
| Billing/payment issues | ❌ No (use Google support) |
Setup Verification
The agent should verify API access before proceeding:
# Check for API configuration
ls ~/.google-ads.yaml 2>/dev/null && echo "API config found" || echo "No API config — see references/api-setup.md"
# Check for SDK
python3 -c "from google.ads.googleads.client import GoogleAdsClient; print('SDK installed')" 2>/dev/null || echo "SDK not installed — run: pip install google-ads"If API is not configured, guide the user through references/api-setup.md. The API approach is strongly recommended — it's reliable, automatable, and doesn't depend on UI changes.
Campaign Creation Checklist
⚠️ COMPLETE THIS BEFORE CREATING ANY CAMPAIGN
This checklist exists because every item has caused real-world failures:
1. Pre-Flight Verification
# ALWAYS verify landing page is live
curl -sI "https://your-landing-page.com/path" | head -2
# Must return: HTTP/2 200 or HTTP/1.1 200 OK
# Why? We've seen campaigns launch with 404 landing pages.
# All ad spend went to a broken page. Verify FIRST.2. Plan Structure Before Code
Before writing any campaign creation code, document:
| Element | Your Plan | Character Limit |
| Campaign name | — | |
| Campaign type | Search / PMax / Display / etc. | — |
| Daily budget | — | |
| Ad group names | — | |
| Keywords per group | — | |
| Headlines (3-15) | ≤30 chars each | |
| Descriptions (2-4) | ≤90 chars each | |
| Final URL | Must return 200 | |
| Location targeting | — | |
| End date? | (if promotional) |
Why plan first? Iterating campaign structure via API is slow and error-prone. Get it right on paper first.
3. Required API Fields (Easy to Forget)
# EU Political Advertising field (REQUIRED even for non-political ads)
campaign.contains_eu_political_advertising = (
client.enums.EuPoliticalAdvertisingStatusEnum.DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING
)
# Why? Without this, the API rejects the campaign with a confusing error.
# RSA character limits (STRICT)
# Headlines: exactly ≤30 characters (not "about 30")
# Descriptions: exactly ≤90 characters (not "about 90")
# Why? The API rejects over-length text, doesn't truncate it.4. Post-Creation Verification
- Campaign status shows ENABLED (not PAUSED or ERROR)
- Ads show "Eligible" or "Under review" (not "Disapproved")
- Conversion tracking is connected
- Location targeting is correct
- Budget is what you intended
- End date set (if time-limited)
Account Audit Checklist
Quick health check for any Google Ads account:
| Check | Where to Look | Red Flags |
| Zero-conversion keywords | Keywords → Filter: Conv<1, Cost>$X | High spend, no results |
| Empty ad groups | Ad Groups → Filter: Ads=0 | Budget allocated, no creative |
| Policy violations | Campaigns → Status column | Yellow warning icons |
| Optimization Score | Overview page (top right) | Below 70% |
| Conversion tracking | Tools → Conversions | "Inactive" or no recent data |
| Wasted spend | Search Terms report | Irrelevant queries |
| Landing page status | Ads → Final URL column | Any 404s or redirects |
Common Queries (API Mode)
Campaign Performance (Last 30 Days)
query = """
SELECT
campaign.id,
campaign.name,
campaign.status,
campaign_budget.amount_micros,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
AND campaign.status != 'REMOVED'
ORDER BY metrics.cost_micros DESC
LIMIT 50
"""
# Parse results
for row in response:
cost = row.metrics.cost_micros / 1_000_000
conv = row.metrics.conversions
cpa = row.metrics.cost_per_conversion / 1_000_000 if conv > 0 else 0
print(f"{row.campaign.name}: ${cost:.2f} | {conv:.1f} conv | ${cpa:.2f} CPA")Find Wasted Spend (Zero-Conversion Keywords)
query = """
SELECT
ad_group_criterion.keyword.text,
ad_group_criterion.keyword.match_type,
campaign.name,
metrics.cost_micros,
metrics.clicks,
metrics.impressions
FROM keyword_view
WHERE metrics.conversions = 0
AND metrics.cost_micros > 500000000 /* $500 in micros */
AND segments.date DURING LAST_90_DAYS
AND ad_group_criterion.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
LIMIT 100
"""
# Why 90 days? Short windows miss slow converters.
# Why $500 threshold? Adjust based on your CPA expectations.Search Terms Report (Find Bad Matches)
query = """
SELECT
search_term_view.search_term,
campaign.name,
metrics.cost_micros,
metrics.conversions,
metrics.clicks
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.cost_micros DESC
LIMIT 200
"""
# Look for irrelevant searches eating budget.
# Add them as negative keywords.Common Mutations (API Mode)
Mutations change live ad spend. Before running any mutation (pause, budget change, status flip, negative keyword), show the user the exact campaigns or keywords and the change you're about to make, and get explicit approval. Run a read query first to confirm you're targeting the right resources.
Pause Campaigns
from google.ads.googleads.client import GoogleAdsClient
from google.api_core import protobuf_helpers
def pause_campaigns(client, customer_id, campaign_ids):
"""Pause one or more campaigns."""
campaign_service = client.get_service("CampaignService")
operations = []
for campaign_id in campaign_ids:
operation = client.get_type("CampaignOperation")
campaign = operation.update
campaign.resource_name = campaign_service.campaign_path(
customer_id, campaign_id
)
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# Set field mask so the API only updates the fields we changed
client.copy_from(
operation.update_mask,
protobuf_helpers.field_mask(None, campaign._pb)
)
operations.append(operation)
response = campaign_service.mutate_campaigns(
customer_id=customer_id,
operations=operations
)
return responsePause Keywords
from google.api_core import protobuf_helpers
def pause_keywords(client, customer_id, keyword_resource_names):
"""Pause specific keywords by resource name."""
service = client.get_service("AdGroupCriterionService")
operations = []
for resource_name in keyword_resource_names:
operation = client.get_type("AdGroupCriterionOperation")
criterion = operation.update
criterion.resource_name = resource_name
criterion.status = client.enums.AdGroupCriterionStatusEnum.PAUSED
client.copy_from(
operation.update_mask,
protobuf_helpers.field_mask(None, criterion._pb)
)
operations.append(operation)
return service.mutate_ad_group_criteria(
customer_id=customer_id,
operations=operations
)Browser Fallback (Not Recommended)
Stability Warning: Browser automation against ads.google.com is fragile. Google frequently changes their UI, which breaks selectors and workflows. Use the API whenever possible.
If the API is truly unavailable (no developer token, client account without API access), browser automation can work for read-only checks. See references/browser-workflows.md for details.
Limitations of browser mode:
- UI selectors break without warning when Google updates the interface
- Cannot be reliably scheduled or automated
- Requires the user to be logged in with an active session
- Slower and more error-prone than API calls
- Not suitable for mutations (pausing, budget changes) — too risky without confirmation loops
Recommended path: Invest the 1-2 hours to set up API access (see references/api-setup.md). It pays off immediately.
Output Format
When reporting findings, use clear tables:
## Campaign Performance (Last 30 Days)
| Campaign | Cost | Conv | CPA | Status |
|----------|------|------|-----|--------|
| Branded | $5K | 50 | $100| ✅ Strong |
| Generic | $10K | 5 | $2K | ⚠️ Review |
| Test | $2K | 0 | N/A | ❌ Pause |
## Recommended Actions
1. **PAUSE**: Test campaign ($2K spent, 0 conversions)
2. **REVIEW**: Generic campaign (CPA too high)
3. **INCREASE**: Branded budget (efficient performer)Troubleshooting
API Issues
| Error | Cause | Fix |
AuthenticationError | Bad credentials | Regenerate refresh token |
DEVELOPER_TOKEN_NOT_APPROVED | Using test token in prod | Apply for token approval |
CUSTOMER_NOT_FOUND | Wrong customer ID | Use 10-digit ID, no dashes |
proto-plus CopyFrom errors | Wrong assignment syntax | Use direct assignment, not CopyFrom |
INVALID_STRING_LENGTH | Text too long | Headlines ≤30, descriptions ≤90 |
Why This Belongs in Tier 4 (Growth)
This skill directly drives revenue growth:
- Tier 1 = Foundation (secrets, setup)
- Tier 2 = Communication (email, Slack)
- Tier 3 = Business Ops (POS, accounting)
- Tier 4 = Growth (advertising, marketing, SEO)
Google Ads is one of the primary paid growth channels for SMBs. This skill helps you manage it without the expensive mistakes that eat into margins.
Files Included
google-ads/
├── SKILL.md # This documentation
└── references/
├── api-setup.md # Full API setup guide (start here)
└── browser-workflows.md # Browser fallback (unstable, last resort)Other versions28 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- FelipeAngeli/skills★ 214% same
Wrote their own version · 27
- superdesigndev/treg★ 7ksame name
- nowork-studio/toprank★ 4.1ksame name
- nowork-studio/notfair-plugin★ 4.1ksame name
- OpenClaudia/openclaudia-skills★ 724same name
- pedronauck/skills★ 641same name
- ivangfalco/ads-skills★ 267same name
- HybridAIOne/hybridclaw★ 159same name
- hyperfx-ai/marketing-skills★ 107same name
- AceDataCloud/Skills★ 17same name
- chanktb/claude-google-ads★ 11same name
17 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use gohighlevel, google-ads-assets and 5 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
windsor-aiSkillgohighlevel
Analyze GoHighLevel CRM data through Windsor.ai. Use when the user asks about their GoHighLevel account — contacts, opportunities and pipeline stages, deal value, appointments, campaigns, lead sources, or conversion rates. It can also create or update a contact and create an invoice, always after the user confirms the exact change. It does not send emails or SMS, book or change appointments, or modify pipeline or campaign settings. Do not use for other CRMs (HubSpot, Salesforce), outbound messaging, or ad-platform performance data.
Also in 3 projects that use this
chanktbSkillgoogle-ads-assets
Generates Google Ads creative assets shared across campaign types: responsive search ad headlines and descriptions, Performance Max asset-group copy and search themes, Demand Gen image/video briefs, and sitelinks/callouts. Enforces character limits, brand voice from account-context.yaml, and policy/ trademark safety. Use when the user says "ad copy", "headlines", "descriptions", "assets", "creative", "rsa", "asset group copy", "sitelinks", "callouts".
Also in 3 projects that use this
hyperfx-aiSkilltiktok-ads
Plan and create TikTok advertising campaigns end-to-end via the Hyper MCP, with strict parameter validation for objective-specific requirements. Use when the user wants to launch TikTok ads, set up TikTok traffic or reach campaigns, configure conversions or app-promotion campaigns, upload TikTok video creatives, or analyze TikTok ad performance. Also triggers on tiktok marketing, tiktok campaign, tiktok ppc, or tiktok ads manager.
Also in 5 projects that use this
brainbytes-devSkilllinkedin-ads
LinkedIn advertising strategy for B2B lead generation, brand awareness, and recruitment. Use when running LinkedIn ad campaigns.
Also in 5 projects that use this
isiahw1Skillgoogle-search-console
Query and analyze Google Search Console data for SEO insights. Use when users want to analyze search performance, find content optimization opportunities, check URL index status, manage sitemaps, or make data-driven content decisions. Supports multiple properties and covers keyword discovery, CTR analysis, position tracking, and technical SEO checks.
Also in 3 projects that use this
itallstartedwithaideaSkillgoogle-ads-audit
Structured Google Ads account audit across 7 dimensions. Activate when the user asks to "audit my account", "check for problems", "find issues", "review my campaigns", or requests a comprehensive account health assessment. Delivers findings with severity ratings and prioritized action items.
Also in 3 projects that use this
In this repository23 other files it gives its agents.
- data-lake-starterSkill
- google-workspaceSkill
- mcp-guideSkill
- secrets-managerSkill
- semantic-layer-auditSkill
- gmailSkill
- google-calendarSkill
- google-chatSkill
- slack-directorySkill
- slackSkill
- google-docsSkill
- google-driveSkill
- google-sheetsSkill
- google-tasksSkill
- brand-identitySkill
- creative-matrixSkill
- nano-bananaSkill
- autoresearchSkill
- long-running-agentSkill
- morning-briefingSkill
- playbook-discoverySkill
- revenue-forecasterSkill
- patent-figureSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

