Claude-code-marketing-skills gaql-reference

Google Ads Query Language (GAQL) Reference — complete syntax, resource types, fields, operators, date macros, and ready-to-use query patterns

install
source · Clone the upstream repo
git clone https://github.com/cognyai/claude-code-marketing-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/cognyai/claude-code-marketing-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/gaql-reference" ~/.claude/skills/cognyai-claude-code-marketing-skills-gaql-reference && rm -rf "$T"
manifest: skills/gaql-reference/SKILL.md
source content

Google Ads Query Language (GAQL) Reference

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

Usage

/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 query

Instructions

You 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__google_ads__tool_execute_gaql
to run queries directly and
mcp__cogny__google_ads__tool_get_gaql_doc
or
mcp__cogny__google_ads__tool_get_reporting_view_doc
for API documentation lookups.


Syntax

Formal Grammar

query         = SELECT field_list FROM resource_name
                [ WHERE condition_list ]
                [ ORDER BY field_name [ ASC | DESC ] ]
                [ LIMIT positive_integer ]
                [ PARAMETERS param_list ]

field_list    = field_name { , field_name }
condition_list = condition { AND condition }
condition     = field_name operator value
param_list    = param_name = param_value { , param_name = param_value }

Clauses

ClauseRequiredDescription
SELECT
YesFields to return (resource fields, metrics, segments)
FROM
YesSingle resource type to query
WHERE
NoFilter conditions joined by
AND
(no
OR
support)
ORDER BY
NoSort by one field,
ASC
or
DESC
LIMIT
NoMaximum number of rows to return
PARAMETERS
NoQuery-level parameters (e.g.,
include_drafts = true
)

Example

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 Types (FROM Clause)

Campaign Management

ResourceDescription
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

Ad Groups & Ads

ResourceDescription
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

Performance Views

ResourceDescription
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

Conversion & Attribution

ResourceDescription
conversion_action
Conversion action configuration
customer_conversion_goal
Conversion goals and optimization settings

Account & Extensions

ResourceDescription
customer
Account-level settings
asset
Account assets (sitelinks, callouts, images)
asset_group
Performance Max asset groups
asset_group_asset
Assets within asset groups

Change History

ResourceDescription
change_status
Recent changes to account entities
change_event
Detailed change history with old/new values

Common Fields

Campaign Fields

FieldTypeDescription
campaign.id
INT64Unique campaign ID
campaign.name
STRINGCampaign 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
RESOURCEBudget resource name
campaign.start_date
DATECampaign start date
campaign.end_date
DATECampaign end date
campaign.serving_status
ENUM
SERVING
,
NONE
,
ENDED
,
PENDING
,
SUSPENDED
campaign.target_cpa.target_cpa_micros
INT64Target CPA in micros
campaign.target_roas.target_roas
DOUBLETarget ROAS as a ratio

Ad Group Fields

FieldTypeDescription
ad_group.id
INT64Unique ad group ID
ad_group.name
STRINGAd 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
INT64Default CPC bid in micros
ad_group.target_cpa_micros
INT64Ad group-level target CPA

Ad Fields

FieldTypeDescription
ad_group_ad.ad.id
INT64Unique 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.

Keyword & Criterion Fields

FieldTypeDescription
ad_group_criterion.criterion_id
INT64Criterion ID
ad_group_criterion.keyword.text
STRINGKeyword 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
INT32Quality 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
ENUMLanding page experience
ad_group_criterion.quality_info.search_predicted_ctr
ENUMExpected CTR
ad_group_criterion.effective_cpc_bid_micros
INT64Effective CPC bid
ad_group_criterion.position_estimates.first_page_cpc_micros
INT64Estimated first page CPC

Search Term Fields

FieldTypeDescription
search_term_view.search_term
STRINGActual user search query
search_term_view.status
ENUM
ADDED
,
EXCLUDED
,
ADDED_EXCLUDED
,
NONE

Metrics

FieldTypeDescription
metrics.impressions
INT64Number of impressions
metrics.clicks
INT64Number of clicks
metrics.cost_micros
INT64Cost in micros (divide by 1,000,000)
metrics.ctr
DOUBLEClick-through rate
metrics.average_cpc
DOUBLEAverage CPC in micros
metrics.average_cpm
DOUBLEAverage CPM in micros
metrics.conversions
DOUBLEConversions
metrics.conversions_value
DOUBLETotal conversion value
metrics.cost_per_conversion
DOUBLECost per conversion in micros
metrics.all_conversions
DOUBLEAll conversions (including cross-device)
metrics.all_conversions_value
DOUBLEAll conversions value
metrics.view_through_conversions
INT64View-through conversions
metrics.search_impression_share
DOUBLESearch impression share (0.0-1.0)
metrics.search_top_impression_share
DOUBLETop impression share
metrics.search_absolute_top_impression_share
DOUBLEAbsolute top impression share
metrics.search_budget_lost_impression_share
DOUBLEIS lost to budget
metrics.search_rank_lost_impression_share
DOUBLEIS lost to rank
metrics.interaction_rate
DOUBLEInteraction rate
metrics.interactions
INT64Interactions
metrics.video_views
INT64Video views
metrics.video_view_rate
DOUBLEVideo view rate
metrics.invalid_clicks
INT64Invalid clicks filtered by Google

Segments

FieldTypeDescription
segments.date
DATEDate (YYYY-MM-DD)
segments.day_of_week
ENUM
MONDAY
through
SUNDAY
segments.month
DATEFirst day of the month
segments.quarter
DATEFirst day of the quarter
segments.year
INT32Year
segments.hour
INT32Hour 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
RESOURCEConversion action resource name
segments.conversion_action_name
STRINGConversion action name
segments.conversion_action_category
ENUMConversion action category
segments.click_type
ENUM
URL_CLICKS
,
CALLS
,
SITELINKS
, etc.
segments.keyword.info.text
STRINGKeyword text (in search_term_view)
segments.keyword.info.match_type
ENUMKeyword match type

WHERE Clause Operators

Comparison Operators

OperatorExample
=
campaign.status = 'ENABLED'
!=
campaign.status != 'REMOVED'
>
metrics.impressions > 100
<
metrics.ctr < 0.02
>=
metrics.clicks >= 10
<=
metrics.cost_micros <= 5000000

Set Operators

OperatorExample
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')

String Operators

OperatorExample
LIKE
campaign.name LIKE '%Brand%'
NOT LIKE
campaign.name NOT LIKE '%Test%'

Null Checks

OperatorExample
IS NULL
ad_group_criterion.quality_info.quality_score IS NULL
IS NOT NULL
ad_group_criterion.quality_info.quality_score IS NOT NULL

Range Operators

OperatorExample
BETWEEN
segments.date BETWEEN '2025-01-01' AND '2025-01-31'
DURING
segments.date DURING LAST_30_DAYS

Date Macros (DURING)

MacroDescription
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

Common Query Patterns

Campaign Performance Report

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 DESC

Search Terms Report (Negative Keyword Identification)

SELECT
  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 1000

Filter for high-cost, zero-conversion terms to build negative keyword lists.

Quality Score Analysis

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 ASC

Landing Page Performance

SELECT
  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 100

Device Breakdown

SELECT
  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.device

Geographic Performance

SELECT
  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 200

Ad Copy Performance (RSA Asset-Level)

SELECT
  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 DESC

Asset-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 DESC

Budget Utilization / Impression Share

SELECT
  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 DESC

Conversion Action Breakdown

SELECT
  campaign.name,
  segments.conversion_action_name,
  segments.conversion_action_category,
  metrics.conversions,
  metrics.conversions_value,
  metrics.all_conversions,
  metrics.all_conversions_value,
  metrics.cost_per_conversion
FROM campaign
WHERE campaign.status = 'ENABLED'
  AND segments.date DURING LAST_30_DAYS
  AND metrics.conversions > 0
ORDER BY metrics.conversions DESC

Change History Audit

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 500

Gotchas and Important Notes

cost_micros Requires Division

All 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,000

Example:

cost_micros = 5430000
means $5.43.

Segment + Metric Compatibility

  • 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.
  • Check the Google Ads API field compatibility matrix when in doubt.

Date Range Requirements

  • Queries with
    metrics.*
    fields require a date range (
    segments.date DURING ...
    or
    BETWEEN
    ).
  • Resource-only queries (no metrics) do not need a date range.

Enum Values

Enum fields must use string constant names:

  • CampaignStatus:
    ENABLED
    ,
    PAUSED
    ,
    REMOVED
  • AdGroupStatus:
    ENABLED
    ,
    PAUSED
    ,
    REMOVED
  • AdvertisingChannelType:
    SEARCH
    ,
    DISPLAY
    ,
    SHOPPING
    ,
    VIDEO
    ,
    PERFORMANCE_MAX
    ,
    MULTI_CHANNEL
    ,
    LOCAL
    ,
    SMART
    ,
    HOTEL
    ,
    DISCOVERY
  • KeywordMatchType:
    BROAD
    ,
    PHRASE
    ,
    EXACT
  • BiddingStrategyType:
    TARGET_CPA
    ,
    TARGET_ROAS
    ,
    MAXIMIZE_CONVERSIONS
    ,
    MAXIMIZE_CONVERSION_VALUE
    ,
    MANUAL_CPC
    ,
    ENHANCED_CPC
    ,
    TARGET_IMPRESSION_SHARE
  • Device:
    DESKTOP
    ,
    MOBILE
    ,
    TABLET
    ,
    CONNECTED_TV
    ,
    OTHER
  • QualityScoreBucket:
    BELOW_AVERAGE
    ,
    AVERAGE
    ,
    ABOVE_AVERAGE

Rate Limits

  • Standard access: 15,000 requests/day, 1,600 operations/minute.
  • Basic access: 10,000 requests/day.
  • Use
    SearchStream
    for large result sets (one operation regardless of size).

Other Pitfalls

  • No
    OR
    :
    All WHERE conditions are AND-joined. Use
    IN
    or separate queries.
  • No joins: GAQL queries operate on a single resource.
  • No
    GROUP BY
    :
    Aggregation is implicit by selected fields + segments.
  • No aliases: Cannot use
    AS
    in GAQL.
  • No arithmetic: Calculate
    cost_micros / 1000000
    client-side.
  • Segment auto-grouping: Adding a segment splits rows by that dimension.
  • Removed resources: Excluded by default. Filter explicitly to include them.
  • PARAMETERS clause:
    include_drafts = true
    for drafts,
    omit_unselected_resource_names = true
    to reduce response size.

Resources