You have access to google-ads-open-cli, a read-only CLI for the Google Ads API (v23). Use it to query ad accounts, pull performance stats, and run custom GAQL queries.
# Check if the CLI is available
google-ads-open-cli --help
# List accessible accounts
google-ads-open-cli customers
If the CLI is not installed, install it:
npm install -g google-ads-open-cli
The CLI requires two credentials: an OAuth2 access token and a developer token. Credentials are resolved in this order:
--credentials flag (per-command)GOOGLE_ADS_ACCESS_TOKEN + GOOGLE_ADS_DEVELOPER_TOKEN~/.config/google-ads-open-cli/credentials.jsonFor MCC (manager) accounts, also set GOOGLE_ADS_LOGIN_CUSTOMER_ID.
Before running any command, verify credentials are configured by running google-ads-open-cli customers. If it fails with a credentials error, ask the user to set up authentication.
Manager Account (MCC)
└── Customer Account (10-digit ID, e.g. 1234567890)
├── Campaign
│ └── Ad Group
│ ├── Ad (Ad Group Ad)
│ └── Keyword (Ad Group Criterion)
├── Campaign Budget
├── Conversion Action
├── User List (remarketing)
└── Asset (images, videos, sitelinks)
Customer IDs are 10-digit numbers. Dashes are stripped automatically.
Google Ads uses micros: 1 currency unit = 1,000,000 micros. All cost/bid/budget values returned by the CLI are in micros. Always divide by 1,000,000 when presenting monetary values to the user.
All commands output pretty-printed JSON by default. Use --format compact for single-line JSON (useful for piping).
# List all accessible accounts
google-ads-open-cli customers
# Get details for a specific account
google-ads-open-cli customer 1234567890
# List sub-accounts under an MCC
google-ads-open-cli account-hierarchy 1234567890
# Campaigns (filter by status: ENABLED, PAUSED, REMOVED)
google-ads-open-cli campaigns 1234567890
google-ads-open-cli campaigns 1234567890 --status ENABLED
# Get a specific campaign
google-ads-open-cli campaign 1234567890 98765
# Campaign budgets
google-ads-open-cli campaign-budgets 1234567890
# Ad groups (filter by campaign, status)
google-ads-open-cli ad-groups 1234567890 --campaign 98765
# Get a specific ad group
google-ads-open-cli ad-group 1234567890 11111
# Ads (filter by campaign, ad group, status)
google-ads-open-cli ads 1234567890 --campaign 98765 --ad-group 11111
# Get a specific ad (requires ad-group-id and ad-id)
google-ads-open-cli ad 1234567890 11111 22222
# Keywords
google-ads-open-cli keywords 1234567890 --campaign 98765 --status ENABLED
All listing commands support --limit (default 100).
Stats commands require --start and --end dates (YYYY-MM-DD):
# Campaign stats
google-ads-open-cli campaign-stats 1234567890 --start 2026-01-01 --end 2026-01-31
# Campaign stats with device segment
google-ads-open-cli campaign-stats 1234567890 --start 2026-01-01 --end 2026-01-31 --segments device
# Ad group stats (filter by --campaign and/or --ad-group)
google-ads-open-cli ad-group-stats 1234567890 --start 2026-01-01 --end 2026-01-31 --campaign 98765
# Ad-level stats (filter by --campaign and/or --ad-group)
google-ads-open-cli ad-stats 1234567890 --start 2026-01-01 --end 2026-01-31
# Keyword stats (sorted by impressions desc; filter by --campaign and/or --ad-group)
google-ads-open-cli keyword-stats 1234567890 --start 2026-01-01 --end 2026-01-31
Available segments for campaign-stats --segments: device, ad_network_type, day_of_week (comma-separated).
Stats commands default to --limit 1000.
# Audiences and remarketing lists
google-ads-open-cli audiences 1234567890
google-ads-open-cli user-lists 1234567890
# Assets and extensions
google-ads-open-cli assets 1234567890 --type SITELINK
google-ads-open-cli extensions 1234567890 --campaign 98765
# Conversions and billing
google-ads-open-cli conversion-actions 1234567890
google-ads-open-cli billing 1234567890
# Change history
google-ads-open-cli change-status 1234567890 --limit 20
# Negative keyword lists
google-ads-open-cli negative-keywords 1234567890
Asset types: IMAGE, MEDIA_BUNDLE, TEXT, YOUTUBE_VIDEO, LEAD_FORM, CALL, CALLOUT, SITELINK, STRUCTURED_SNIPPET.
The query command is the escape hatch for anything not covered by built-in commands. It runs arbitrary GAQL (Google Ads Query Language) against the Google Ads API.
google-ads-open-cli query <customer-id> "<GAQL>"
SELECT field1, field2, ...
FROM resource_name
WHERE conditions
ORDER BY field [ASC|DESC]
LIMIT count
PARAMETERS key=value
SELECT and FROM are required. WHERE, ORDER BY, LIMIT, PARAMETERS are optional.SELECT, FROM, WHERE, etc.) are case-insensitive.OR operator -- all WHERE conditions are AND-ed together.JOIN, GROUP BY, HAVING, or subqueries.| Operator | Example |
|---|---|
| --- | --- |
=, !=, >, <, >=, <= | campaign.status = 'ENABLED' |
IN, NOT IN | campaign.status IN ('ENABLED', 'PAUSED') |
LIKE, NOT LIKE | campaign.name LIKE '%brand%' (case-insensitive) |
REGEXP_MATCH | campaign.name REGEXP_MATCH '(?i)brand' |
BETWEEN ... AND ... | segments.date BETWEEN '2026-01-01' AND '2026-01-31' |
DURING | segments.date DURING LAST_30_DAYS |
IS NULL, IS NOT NULL | ad_group_ad.ad.final_urls IS NOT NULL |
CONTAINS ANY/ALL/NONE | For repeated fields |
Custom range:
WHERE segments.date BETWEEN '2026-01-01' AND '2026-01-31'
Predefined ranges (with DURING):
TODAY, YESTERDAYLAST_7_DAYS, LAST_14_DAYS, LAST_30_DAYS (NOT including today)THIS_MONTH, LAST_MONTHTHIS_WEEK_SUN_TODAY, THIS_WEEK_MON_TODAYLAST_WEEK_SUN_SAT, LAST_WEEK_MON_SUNLAST_BUSINESS_WEEKEntities: customer, campaign, campaign_budget, ad_group, ad_group_ad, ad_group_criterion, campaign_criterion
View resources (for metrics): keyword_view, search_term_view, geographic_view, gender_view, age_range_view, landing_page_view, ad_group_audience_view, shopping_performance_view, click_view
Other: change_status, change_event, conversion_action, asset, bidding_strategy, label, recommendation, shared_set, shared_criterion
Performance: metrics.impressions, metrics.clicks, metrics.cost_micros, metrics.ctr, metrics.average_cpc, metrics.average_cpm, metrics.interactions
Conversions: metrics.conversions, metrics.conversions_value, metrics.all_conversions, metrics.cost_per_conversion, metrics.conversion_rate, metrics.value_per_conversion
Impression share: metrics.search_impression_share, metrics.search_budget_lost_impression_share, metrics.search_rank_lost_impression_share, metrics.absolute_top_impression_percentage, metrics.top_impression_percentage
Video: metrics.video_views, metrics.video_view_rate, metrics.average_cpv
Date: segments.date, segments.week, segments.month, segments.quarter, segments.year, segments.hour_of_day, segments.day_of_week
Device/network: segments.device, segments.ad_network_type, segments.slot, segments.click_type
Conversion: segments.conversion_action, segments.conversion_action_name, segments.conversion_action_category
segments.date (or segments.week, segments.month, etc.) is in SELECT, a finite date range filter MUST be in WHERE.campaign.status != 'REMOVED' (or equivalent) to match Google Ads UI behavior.campaign.name is available when FROM ad_group.Search terms that triggered ads:
google-ads-open-cli query 1234567890 "SELECT search_term_view.search_term, search_term_view.status, campaign.name, ad_group.name, metrics.clicks, metrics.impressions, metrics.ctr, metrics.cost_micros FROM search_term_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.impressions DESC LIMIT 50"
Campaign performance by device:
google-ads-open-cli query 1234567890 "SELECT campaign.name, segments.device, metrics.impressions, metrics.clicks, metrics.ctr, metrics.cost_micros, metrics.conversions FROM campaign WHERE segments.date DURING LAST_30_DAYS AND campaign.status != 'REMOVED'"
Impression share analysis:
google-ads-open-cli query 1234567890 "SELECT campaign.name, metrics.search_impression_share, metrics.search_budget_lost_impression_share, metrics.search_rank_lost_impression_share, metrics.clicks, metrics.impressions, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_7_DAYS AND campaign.status = 'ENABLED' ORDER BY metrics.search_budget_lost_impression_share DESC"
Landing page performance:
google-ads-open-cli query 1234567890 "SELECT landing_page_view.unexpanded_final_url, metrics.clicks, metrics.impressions, metrics.ctr, metrics.cost_micros, metrics.conversions FROM landing_page_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.clicks DESC LIMIT 20"
Demographics -- age breakdown:
google-ads-open-cli query 1234567890 "SELECT ad_group_criterion.age_range.type, campaign.name, metrics.clicks, metrics.impressions, metrics.ctr, metrics.cost_micros FROM age_range_view WHERE segments.date DURING LAST_30_DAYS"
Geographic performance (by user location):
google-ads-open-cli query 1234567890 "SELECT geographic_view.country_criterion_id, geographic_view.location_type, campaign.name, metrics.clicks, metrics.impressions, metrics.cost_micros FROM geographic_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.clicks DESC LIMIT 50"
Ad copy performance (responsive search ads):
google-ads-open-cli query 1234567890 "SELECT ad_group_ad.ad.responsive_search_ad.headlines, ad_group_ad.ad.responsive_search_ad.descriptions, ad_group_ad.ad.final_urls, ad_group_ad.status, metrics.clicks, metrics.impressions, metrics.ctr, metrics.cost_micros FROM ad_group_ad WHERE segments.date DURING LAST_30_DAYS AND ad_group_ad.status != 'REMOVED' AND ad_group_ad.ad.type = 'RESPONSIVE_SEARCH_AD' ORDER BY metrics.clicks DESC LIMIT 20"
Conversion actions audit:
google-ads-open-cli query 1234567890 "SELECT conversion_action.name, conversion_action.type, conversion_action.status, conversion_action.category, conversion_action.counting_type, conversion_action.click_through_lookback_window_days, conversion_action.view_through_lookback_window_days FROM conversion_action WHERE conversion_action.status = 'ENABLED'"
Shopping product performance:
google-ads-open-cli query 1234567890 "SELECT segments.product_item_id, segments.product_title, metrics.clicks, metrics.impressions, metrics.ctr, metrics.cost_micros, metrics.conversions, metrics.conversions_value FROM shopping_performance_view WHERE segments.date DURING LAST_30_DAYS ORDER BY metrics.conversions_value DESC LIMIT 50"
Account-level daily trend:
google-ads-open-cli query 1234567890 "SELECT segments.date, metrics.clicks, metrics.impressions, metrics.ctr, metrics.cost_micros, metrics.conversions, metrics.conversions_value FROM customer WHERE segments.date DURING LAST_30_DAYS ORDER BY segments.date"
google-ads-open-cli customers to find accessible accountscampaign-stats with a recent date range for a performance snapshotcampaign-stats to identify the scopead-group-stats or keyword-stats for underperforming campaignsconversion-actions to verify tracking setupUse the query command with GAQL. Common scenarios:
search_term_viewgeographic_viewgender_view, age_range_viewlanding_page_viewmetrics.search_impression_share and related fields from campaignshopping_performance_viewchange_event for detailed logssegments.month or segments.quarter, the date must be the first day of the period共 1 个版本