gaql-reference — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited gaql-reference (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Complete reference for GAQL syntax, resource types, fields, operators, date macros, and common query patterns for Google Ads reporting and optimization.
Full docs: https://cogny.com/docs/gaql-reference
/gaql-reference # Show full syntax overview
/gaql-reference search terms # Search terms report pattern
/gaql-reference quality score # Quality Score analysis query
/gaql-reference impression share # Budget & impression share query
/gaql-reference geographic # Geographic performance query
/gaql-reference change history # Change history audit queryYou are a Google Ads Query Language (GAQL) expert. Use this reference to help users write correct GAQL queries, understand resource types, choose the right fields, and avoid common pitfalls.
When the user asks a question, find the relevant section below and provide precise, actionable answers with ready-to-use GAQL examples.
If the user provides a specific topic as an argument, focus on that area. Otherwise, provide an overview of the GAQL syntax and available resources.
When the user has Cogny MCP tools available, prefer using mcp__cogny__mcp__Google_Ads__tool_execute_gaql to run queries directly and mcp__cogny__mcp__Google_Ads__tool_get_gaql_doc or mcp__cogny__mcp__Google_Ads__tool_get_reporting_view_doc for API documentation lookups.
If Cogny isn't connected, skip this and note what connecting adds.
| Engine | How | Note |
|---|---|---|
| Google Ads | mcp__cogny__mcp__Google_Ads__tool_execute_gaql (after tool_list_accessible_accounts) | Free without an account: the reference still works, queries just aren't run |
| Microsoft Ads | No GAQL. mcp__cogny__mcp__Bing_Ads__tool_get_report (report_type: campaign, ad_group, keyword, search_query, ad, geographic; optional columns) | Money in account-currency units, percents as percents |
query = SELECT field_list FROM resource_name
[ WHERE condition_list ]
[ ORDER BY ordering { , ordering } ]
[ LIMIT positive_integer ]
[ PARAMETERS param_list ]
field_list = field_name { , field_name }
condition_list = condition { AND condition }
condition = field_name operator value
ordering = field_name [ ASC | DESC ]
param_list = param_name = param_value { , param_name = param_value }| Clause | Required | Description |
|---|---|---|
SELECT | Yes | Fields to return (resource fields, metrics, segments) |
FROM | Yes | Single resource type to query |
WHERE | No | Filter conditions joined by AND (no OR support) |
ORDER BY | No | Sort by one or more comma-separated fields, each ASC or DESC |
LIMIT | No | Maximum number of rows to return |
PARAMETERS | No | Query-level parameters (e.g., include_drafts = true) |
SELECT
campaign.name,
metrics.impressions,
metrics.clicks,
metrics.cost_micros
FROM campaign
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.impressions DESC
LIMIT 50| Resource | Description |
|---|---|
campaign | Campaign settings, status, bidding, budget |
campaign_budget | Shared and campaign-level budgets |
campaign_criterion | Campaign-level targeting criteria |
campaign_bid_modifier | Bid adjustments at campaign level |
bidding_strategy | Portfolio bidding strategies |
| Resource | Description |
|---|---|
ad_group | Ad group settings, status, targeting |
ad_group_ad | Ads within ad groups (RSA, ETA, etc.) |
ad_group_ad_asset_view | Asset-level performance for responsive ads |
ad_group_criterion | Keywords, audiences, and other criteria |
ad_group_bid_modifier | Bid adjustments at ad group level |
| Resource | Description |
|---|---|
keyword_view | Keyword-level performance metrics |
search_term_view | Actual search queries that triggered ads |
landing_page_view | Landing page performance |
geographic_view | Performance by geographic location |
location_view | Performance by targeted/excluded location |
age_range_view | Performance by age range demographic |
gender_view | Performance by gender demographic |
user_location_view | Performance by user's physical location |
display_keyword_view | Display network keyword performance |
topic_view | Display/video topic targeting performance |
managed_placement_view | Managed placement performance |
| Resource | Description |
|---|---|
conversion_action | Conversion action configuration |
customer_conversion_goal | Conversion goals and optimization settings |
| Resource | Description |
|---|---|
customer | Account-level settings |
asset | Account assets (sitelinks, callouts, images) |
asset_group | Performance Max asset groups |
asset_group_asset | Assets within asset groups |
| Resource | Description |
|---|---|
change_status | Recent changes to account entities |
change_event | Detailed change history with old/new values |
| Field | Type | Description |
|---|---|---|
campaign.id | INT64 | Unique campaign ID |
campaign.name | STRING | Campaign name |
campaign.status | ENUM | ENABLED, PAUSED, REMOVED |
campaign.advertising_channel_type | ENUM | SEARCH, DISPLAY, SHOPPING, VIDEO, PERFORMANCE_MAX |
campaign.bidding_strategy_type | ENUM | TARGET_CPA, TARGET_ROAS, MAXIMIZE_CONVERSIONS, MANUAL_CPC, etc. |
campaign.campaign_budget | RESOURCE | Budget resource name |
campaign.start_date | DATE | Campaign start date |
campaign.end_date | DATE | Campaign end date |
campaign.serving_status | ENUM | SERVING, NONE, ENDED, PENDING, SUSPENDED |
campaign.target_cpa.target_cpa_micros | INT64 | Target CPA in micros |
campaign.target_roas.target_roas | DOUBLE | Target ROAS as a ratio |
| Field | Type | Description |
|---|---|---|
ad_group.id | INT64 | Unique ad group ID |
ad_group.name | STRING | Ad group name |
ad_group.status | ENUM | ENABLED, PAUSED, REMOVED |
ad_group.type | ENUM | SEARCH_STANDARD, DISPLAY_STANDARD, SHOPPING_PRODUCT_ADS, etc. |
ad_group.cpc_bid_micros | INT64 | Default CPC bid in micros |
ad_group.target_cpa_micros | INT64 | Ad group-level target CPA |
| Field | Type | Description |
|---|---|---|
ad_group_ad.ad.id | INT64 | Unique ad ID |
ad_group_ad.ad.type | ENUM | RESPONSIVE_SEARCH_AD, EXPANDED_TEXT_AD, etc. |
ad_group_ad.ad.final_urls | STRING (repeated) | Landing page URLs |
ad_group_ad.status | ENUM | ENABLED, PAUSED, REMOVED |
ad_group_ad.ad.responsive_search_ad.headlines | MESSAGE (repeated) | RSA headline assets |
ad_group_ad.ad.responsive_search_ad.descriptions | MESSAGE (repeated) | RSA description assets |
ad_group_ad.policy_summary.approval_status | ENUM | APPROVED, DISAPPROVED, etc. |
| Field | Type | Description |
|---|---|---|
ad_group_criterion.criterion_id | INT64 | Criterion ID |
ad_group_criterion.keyword.text | STRING | Keyword text |
ad_group_criterion.keyword.match_type | ENUM | BROAD, PHRASE, EXACT |
ad_group_criterion.status | ENUM | ENABLED, PAUSED, REMOVED |
ad_group_criterion.quality_info.quality_score | INT32 | Quality Score (1-10) |
ad_group_criterion.quality_info.creative_quality_score | ENUM | BELOW_AVERAGE, AVERAGE, ABOVE_AVERAGE |
ad_group_criterion.quality_info.post_click_quality_score | ENUM | Landing page experience |
ad_group_criterion.quality_info.search_predicted_ctr | ENUM | Expected CTR |
ad_group_criterion.effective_cpc_bid_micros | INT64 | Effective CPC bid |
ad_group_criterion.position_estimates.first_page_cpc_micros | INT64 | Estimated first page CPC |
| Field | Type | Description |
|---|---|---|
search_term_view.search_term | STRING | Actual user search query |
search_term_view.status | ENUM | ADDED, EXCLUDED, ADDED_EXCLUDED, NONE |
| Field | Type | Description |
|---|---|---|
metrics.impressions | INT64 | Number of impressions |
metrics.clicks | INT64 | Number of clicks |
metrics.cost_micros | INT64 | Cost in micros (divide by 1,000,000) |
metrics.ctr | DOUBLE | Click-through rate |
metrics.average_cpc | DOUBLE | Average CPC in micros |
metrics.average_cpm | DOUBLE | Average CPM in micros |
metrics.conversions | DOUBLE | Conversions |
metrics.conversions_value | DOUBLE | Total conversion value |
metrics.cost_per_conversion | DOUBLE | Cost per conversion in micros |
metrics.all_conversions | DOUBLE | All conversions (including cross-device) |
metrics.all_conversions_value | DOUBLE | All conversions value |
metrics.view_through_conversions | INT64 | View-through conversions |
metrics.search_impression_share | DOUBLE | Search impression share (0.0-1.0) |
metrics.search_top_impression_share | DOUBLE | Top impression share |
metrics.search_absolute_top_impression_share | DOUBLE | Absolute top impression share |
metrics.search_budget_lost_impression_share | DOUBLE | IS lost to budget |
metrics.search_rank_lost_impression_share | DOUBLE | IS lost to rank |
metrics.interaction_rate | DOUBLE | Interaction rate |
metrics.interactions | INT64 | Interactions |
metrics.video_views | INT64 | Video views |
metrics.video_view_rate | DOUBLE | Video view rate |
metrics.invalid_clicks | INT64 | Invalid clicks filtered by Google |
| Field | Type | Description |
|---|---|---|
segments.date | DATE | Date (YYYY-MM-DD) |
segments.day_of_week | ENUM | MONDAY through SUNDAY |
segments.month | DATE | First day of the month |
segments.quarter | DATE | First day of the quarter |
segments.year | INT32 | Year |
segments.hour | INT32 | Hour of day (0-23) |
segments.device | ENUM | DESKTOP, MOBILE, TABLET, OTHER |
segments.ad_network_type | ENUM | SEARCH, SEARCH_PARTNERS, CONTENT, YOUTUBE_SEARCH, YOUTUBE_WATCH |
segments.slot | ENUM | TOP, OTHER |
segments.conversion_action | RESOURCE | Conversion action resource name |
segments.conversion_action_name | STRING | Conversion action name |
segments.conversion_action_category | ENUM | Conversion action category |
segments.click_type | ENUM | URL_CLICKS, CALLS, SITELINKS, etc. |
segments.keyword.info.text | STRING | Keyword text (in search_term_view) |
segments.keyword.info.match_type | ENUM | Keyword match type |
| Operator | Example |
|---|---|
= | campaign.status = 'ENABLED' |
!= | campaign.status != 'REMOVED' |
> | metrics.impressions > 100 |
< | metrics.ctr < 0.02 |
>= | metrics.clicks >= 10 |
<= | metrics.cost_micros <= 5000000 |
| Operator | Example |
|---|---|
IN | campaign.status IN ('ENABLED', 'PAUSED') |
NOT IN | campaign.advertising_channel_type NOT IN ('VIDEO', 'DISPLAY') |
CONTAINS ANY | campaign.labels CONTAINS ANY ('customers/123/labels/456') |
CONTAINS ALL | campaign.labels CONTAINS ALL ('..label1..', '..label2..') |
CONTAINS NONE | campaign.labels CONTAINS NONE ('customers/123/labels/456') |
| Operator | Example |
|---|---|
LIKE | campaign.name LIKE '%Brand%' |
NOT LIKE | campaign.name NOT LIKE '%Test%' |
| Operator | Example |
|---|---|
IS NULL | ad_group_criterion.quality_info.quality_score IS NULL |
IS NOT NULL | ad_group_criterion.quality_info.quality_score IS NOT NULL |
| Operator | Example |
|---|---|
BETWEEN | segments.date BETWEEN '2025-01-01' AND '2025-01-31' |
DURING | segments.date DURING LAST_30_DAYS |
| Macro | Description |
|---|---|
TODAY | Today only |
YESTERDAY | Yesterday only |
LAST_7_DAYS | Last 7 days (not including today) |
LAST_14_DAYS | Last 14 days |
LAST_30_DAYS | Last 30 days |
LAST_BUSINESS_WEEK | Monday-Friday of previous week |
THIS_WEEK_MON_TODAY | Monday of this week through today |
THIS_WEEK_SUN_TODAY | Sunday of this week through today |
THIS_MONTH | First day of this month through today |
LAST_MONTH | Entire previous month |
SELECT
campaign.id,
campaign.name,
campaign.status,
campaign.advertising_channel_type,
campaign.bidding_strategy_type,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions,
metrics.conversions_value,
metrics.cost_per_conversion
FROM campaign
WHERE campaign.status != 'REMOVED'
AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.cost_micros DESCSELECT
search_term_view.search_term,
search_term_view.status,
segments.keyword.info.text,
segments.keyword.info.match_type,
campaign.name,
ad_group.name,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion
FROM search_term_view
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
AND metrics.impressions > 10
ORDER BY metrics.cost_micros DESC
LIMIT 1000Filter for high-cost, zero-conversion terms to build negative keyword lists.
SELECT
campaign.name,
ad_group.name,
ad_group_criterion.keyword.text,
ad_group_criterion.keyword.match_type,
ad_group_criterion.quality_info.quality_score,
ad_group_criterion.quality_info.creative_quality_score,
ad_group_criterion.quality_info.post_click_quality_score,
ad_group_criterion.quality_info.search_predicted_ctr,
metrics.impressions,
metrics.clicks,
metrics.cost_micros,
metrics.conversions
FROM keyword_view
WHERE campaign.status = 'ENABLED'
AND ad_group.status = 'ENABLED'
AND ad_group_criterion.status = 'ENABLED'
AND ad_group_criterion.quality_info.quality_score IS NOT NULL
AND segments.date DURING LAST_30_DAYS
ORDER BY ad_group_criterion.quality_info.quality_score ASCSELECT
landing_page_view.unexpanded_final_url,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion
FROM landing_page_view
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
AND metrics.clicks > 0
ORDER BY metrics.clicks DESC
LIMIT 100SELECT
campaign.name,
segments.device,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion
FROM campaign
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
ORDER BY campaign.name, segments.deviceSELECT
geographic_view.country_criterion_id,
geographic_view.location_type,
campaign.name,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions,
metrics.conversions_value,
metrics.cost_per_conversion
FROM geographic_view
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
AND metrics.impressions > 0
ORDER BY metrics.cost_micros DESC
LIMIT 200SELECT
campaign.name,
ad_group.name,
ad_group_ad.ad.id,
ad_group_ad.ad.responsive_search_ad.headlines,
ad_group_ad.ad.responsive_search_ad.descriptions,
ad_group_ad.ad.final_urls,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions
FROM ad_group_ad
WHERE campaign.status = 'ENABLED'
AND ad_group.status = 'ENABLED'
AND ad_group_ad.status = 'ENABLED'
AND ad_group_ad.ad.type = 'RESPONSIVE_SEARCH_AD'
AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.impressions DESCAsset-level performance:
SELECT
campaign.name,
ad_group.name,
ad_group_ad_asset_view.field_type,
ad_group_ad_asset_view.performance_label,
asset.text_asset.text,
metrics.impressions,
metrics.clicks,
metrics.ctr,
metrics.cost_micros,
metrics.conversions
FROM ad_group_ad_asset_view
WHERE campaign.status = 'ENABLED'
AND ad_group.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
ORDER BY ad_group_ad_asset_view.performance_label DESC, metrics.impressions DESCSELECT
campaign.name,
campaign.campaign_budget,
campaign_budget.amount_micros,
campaign.bidding_strategy_type,
metrics.impressions,
metrics.cost_micros,
metrics.search_impression_share,
metrics.search_top_impression_share,
metrics.search_absolute_top_impression_share,
metrics.search_budget_lost_impression_share,
metrics.search_rank_lost_impression_share
FROM campaign
WHERE campaign.status = 'ENABLED'
AND campaign.advertising_channel_type = 'SEARCH'
AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.search_budget_lost_impression_share DESCSELECT
campaign.name,
segments.conversion_action_name,
segments.conversion_action_category,
metrics.conversions,
metrics.conversions_value,
metrics.all_conversions,
metrics.all_conversions_value
FROM campaign
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
AND metrics.all_conversions > 0
ORDER BY metrics.conversions DESCsegments.conversion_action_name (and the other conversion-action segments) can't be combined with cost metrics: metrics.cost_per_conversion or metrics.cost_micros fails with PROHIBITED_SEGMENT_WITH_METRIC_IN_SELECT_OR_WHERE_CLAUSE. For cost per conversion by action, run a second query without the segment for metrics.cost_micros, then divide client-side. Filtering on all_conversions keeps secondary (non-primary) actions, which report 0 in metrics.conversions.
SELECT
change_event.change_date_time,
change_event.change_resource_type,
change_event.change_resource_name,
change_event.resource_change_operation,
change_event.changed_fields,
change_event.old_resource,
change_event.new_resource,
change_event.user_email
FROM change_event
WHERE change_event.change_date_time DURING LAST_14_DAYS
AND change_event.change_resource_type IN (
'CAMPAIGN', 'AD_GROUP', 'AD_GROUP_AD',
'AD_GROUP_CRITERION', 'CAMPAIGN_BUDGET'
)
ORDER BY change_event.change_date_time DESC
LIMIT 500All cost fields are in micros (1/1,000,000 of the currency unit):
Actual cost = metrics.cost_micros / 1,000,000
Actual CPC = metrics.average_cpc / 1,000,000Example: cost_micros = 5430000 means $5.43.
segments.conversion_action — impressions/clicks repeat across each conversion action row. Do not sum them.segments.click_type — clicks and impressions fragment by click type. Summing overcounts.segments.slot — only compatible with search campaigns.segments.hour — cannot be combined with segments.date for some resources.metrics.* fields require a date range (segments.date DURING ... or BETWEEN).Enum fields must use string constant names:
ENABLED, PAUSED, REMOVEDENABLED, PAUSED, REMOVEDSEARCH, DISPLAY, SHOPPING, VIDEO, PERFORMANCE_MAX, MULTI_CHANNEL, LOCAL, SMART, HOTEL, DEMAND_GEN (formerly DISCOVERY, which is no longer a valid enum and fails with BAD_ENUM_CONSTANT)BROAD, PHRASE, EXACTTARGET_CPA, TARGET_ROAS, MAXIMIZE_CONVERSIONS, MAXIMIZE_CONVERSION_VALUE, MANUAL_CPC, TARGET_IMPRESSION_SHARE; ENHANCED_CPC is deprecated (no longer available for Search and Display since March 2025) but can still appear on old campaignsDESKTOP, MOBILE, TABLET, CONNECTED_TV, OTHERBELOW_AVERAGE, AVERAGE, ABOVE_AVERAGEDaily operations per developer token (access levels, rolling 24 hours):
RESOURCE_EXHAUSTED) still apply at every level; back off and retry.SearchStream for large result sets (one operation regardless of size).IN or separate queries.AS in GAQL.cost_micros / 1000000 client-side.WHERE campaign.status != 'REMOVED' (or the resource's own status) to match the UI.include_drafts = true for drafts, omit_unselected_resource_names = true to reduce response size.(v25 is current as of 2026-10; swap in the latest version from https://developers.google.com/google-ads/api/docs/release-notes)
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.