From robynn-rory
> Detailed guide for Google Ads operations via the Google Ads API.
How this agent operates — its isolation, permissions, and tool access model
Agent reference
robynn-rory:agents/ads/google-adsThe summary Claude sees when deciding whether to delegate to this agent
> Detailed guide for Google Ads operations via the Google Ads API. Google Ads uses a hierarchical structure: ``` Account (Customer ID) └── Campaign (budget, bidding strategy, objective) └── Ad Group (targeting, default bids) └── Ad (creative content) └── Keywords (search targeting) ``` 1. **Developer Token** - From Google Ads API Center 2. **OAuth 2.0 Client ID** - From Google Cloud Console 3. ...
Detailed guide for Google Ads operations via the Google Ads API.
Google Ads uses a hierarchical structure:
Account (Customer ID)
└── Campaign (budget, bidding strategy, objective)
└── Ad Group (targeting, default bids)
└── Ad (creative content)
└── Keywords (search targeting)
Create Google Cloud Project:
1. Go to https://console.cloud.google.com
2. Create new project or select existing
3. Enable "Google Ads API"
Create OAuth Credentials:
1. Go to APIs & Services > Credentials
2. Create OAuth 2.0 Client ID (Desktop app)
3. Download client_secret.json
Get Developer Token:
1. Sign into Google Ads
2. Go to Tools & Settings > API Center
3. Apply for Developer Token (test token is instant)
Generate Refresh Token:
# Use the Google Ads auth helper
python -c "from google_ads_auth import get_refresh_token; get_refresh_token()"
# Follow browser prompts to authorize
Configure Environment:
# .env file
GOOGLE_ADS_DEVELOPER_TOKEN=your_developer_token
GOOGLE_ADS_CLIENT_ID=your_client_id.apps.googleusercontent.com
GOOGLE_ADS_CLIENT_SECRET=your_client_secret
GOOGLE_ADS_REFRESH_TOKEN=your_refresh_token
GOOGLE_ADS_LOGIN_CUSTOMER_ID=1234567890 # Manager account (no dashes)
| Type | Use For | API Value |
|---|---|---|
| Search | Text ads on Google Search | SEARCH |
| Display | Banner ads on websites | DISPLAY |
| Shopping | Product listing ads | SHOPPING |
| Video | YouTube ads | VIDEO |
| Performance Max | AI-optimized across channels | PERFORMANCE_MAX |
| Demand Gen | Discovery + YouTube | DEMAND_GEN |
| Strategy | Objective | API Value |
|---|---|---|
| Maximize Clicks | Traffic | MAXIMIZE_CLICKS |
| Maximize Conversions | Leads/Sales | MAXIMIZE_CONVERSIONS |
| Target CPA | Cost per acquisition | TARGET_CPA |
| Target ROAS | Return on ad spend | TARGET_ROAS |
| Manual CPC | Full control | MANUAL_CPC |
python google_ads.py campaigns --customer-id 1234567890
GAQL Query:
SELECT
campaign.id,
campaign.name,
campaign.status,
campaign.advertising_channel_type,
campaign_budget.amount_micros
FROM campaign
ORDER BY campaign.name
python google_ads.py performance --customer-id 1234567890 --days 30
GAQL Query:
SELECT
campaign.id,
campaign.name,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.average_cpc,
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
⚠️ Safety: All campaigns created via API are set to PAUSED status.
python google_ads.py create \
--customer-id 1234567890 \
--name "My New Campaign" \
--type SEARCH \
--budget 50.00 \
--bidding MAXIMIZE_CLICKS
Required Fields:
name - Campaign nameadvertising_channel_type - Campaign typecampaign_budget - Daily budget in account currencybidding_strategy_type - How to optimizestatus - Always set to PAUSEDpython google_ads.py update \
--customer-id 1234567890 \
--campaign-id 123456 \
--budget 75.00
# Pause
python google_ads.py update \
--customer-id 1234567890 \
--campaign-id 123456 \
--status PAUSED
# Enable (requires confirmation)
python google_ads.py update \
--customer-id 1234567890 \
--campaign-id 123456 \
--status ENABLED \
--confirm
SELECT
[fields]
FROM [resource]
WHERE [conditions]
ORDER BY [field] [ASC|DESC]
LIMIT [number]
| Resource | Description |
|---|---|
campaign | Campaign-level data |
ad_group | Ad group data |
ad_group_ad | Ad data |
keyword_view | Keyword performance |
geographic_view | Geo performance |
device_view | Device breakdown |
| Metric | Description |
|---|---|
metrics.impressions | Times ad shown |
metrics.clicks | Number of clicks |
metrics.ctr | Click-through rate |
metrics.cost_micros | Spend in micros (divide by 1,000,000) |
metrics.conversions | Conversion count |
metrics.average_cpc | Avg cost per click |
metrics.cost_per_conversion | CPA |
| Segment | Description |
|---|---|
segments.date | Daily breakdown |
segments.device | By device type |
segments.ad_network_type | Search vs Display |
segments.conversion_action | By conversion type |
-- Predefined ranges
WHERE segments.date DURING LAST_7_DAYS
WHERE segments.date DURING LAST_30_DAYS
WHERE segments.date DURING THIS_MONTH
WHERE segments.date DURING LAST_MONTH
-- Custom range
WHERE segments.date BETWEEN '2024-01-01' AND '2024-01-31'
campaign_config = {
"name": "Search - Brand Terms",
"advertising_channel_type": "SEARCH",
"status": "PAUSED", # Always PAUSED
"campaign_budget": {
"amount_micros": 50_000_000, # $50/day
"delivery_method": "STANDARD"
},
"bidding_strategy_type": "MAXIMIZE_CLICKS",
"network_settings": {
"target_google_search": True,
"target_search_network": True,
"target_content_network": False
},
"geo_target_type_setting": {
"positive_geo_target_type": "PRESENCE_OR_INTEREST",
"negative_geo_target_type": "PRESENCE_OR_INTEREST"
}
}
campaign_config = {
"name": "Display - Remarketing",
"advertising_channel_type": "DISPLAY",
"status": "PAUSED",
"campaign_budget": {
"amount_micros": 30_000_000, # $30/day
"delivery_method": "STANDARD"
},
"bidding_strategy_type": "TARGET_CPA",
"target_cpa_micros": 25_000_000, # $25 target CPA
}
ad_group_config = {
"name": "Ad Group - Core Keywords",
"campaign": "customers/{customer_id}/campaigns/{campaign_id}",
"status": "PAUSED",
"type": "SEARCH_STANDARD",
"cpc_bid_micros": 2_000_000 # $2.00 max CPC
}
ad_config = {
"ad_group": "customers/{customer_id}/adGroups/{ad_group_id}",
"status": "PAUSED",
"ad": {
"responsive_search_ad": {
"headlines": [
{"text": "Headline 1", "pinned_field": "HEADLINE_1"},
{"text": "Headline 2"},
{"text": "Headline 3"},
# ... up to 15 headlines
],
"descriptions": [
{"text": "Description 1"},
{"text": "Description 2"},
# ... up to 4 descriptions
],
"path1": "path1",
"path2": "path2"
},
"final_urls": ["https://example.com/landing-page"]
}
}
keyword_config = {
"ad_group": "customers/{customer_id}/adGroups/{ad_group_id}",
"status": "ENABLED",
"keyword": {
"text": "buy widgets online",
"match_type": "PHRASE" # EXACT, PHRASE, BROAD
},
"cpc_bid_micros": 1_500_000 # $1.50 bid
}
| Issue | Cause | Solution |
|---|---|---|
CUSTOMER_NOT_FOUND | Wrong customer ID | Use correct 10-digit ID (no dashes) |
OAUTH_TOKEN_INVALID | Expired token | Regenerate refresh token |
DEVELOPER_TOKEN_NOT_APPROVED | Test token limitations | Apply for production access |
MUTATE_ERROR | Invalid field value | Check API documentation |
QUOTA_ERROR | Rate limited | Implement backoff, wait |
With a test developer token:
ads_config.yamlnpx claudepluginhub robynnai/robynn-claude-cmo --plugin roryGoogle Ads audit specialist that evaluates conversion tracking, wasted spend, account structure, keywords, Quality Score, ad assets, PMax campaigns, bidding, and settings against a 74-point checklist.
Google Ads audit specialist. Audits accounts using exports or screenshots: evaluates 74 checklist items on conversion tracking, wasted spend, structure, keywords, Quality Score, ad assets, PMax, bidding, settings. Scores categories, flags quick wins.
Senior performance marketer with access to ad accounts via Markifact for Google Ads, Meta/Facebook/Instagram Ads, GA4, Shopify, Klaviyo, HubSpot, TikTok, LinkedIn, Pinterest, Snapchat, Microsoft, Amazon, Reddit Ads. Manages launches, edits, optimizations, audiences, creatives, reporting.