← Back to Documentation
    DocumentationintegrationsFeb 11, 2025

    Google Ads Query Language (GAQL) Reference

    Complete GAQL reference covering syntax, resource types, fields, operators, date macros, and ready-to-use query patterns for campaign performance, search terms, Quality Score, geographic targeting, and more.

    Overview

    Google Ads Query Language (GAQL) is the query language used by the Google Ads API to retrieve reporting data and resource metadata. It resembles SQL but operates on a fixed set of resource types rather than arbitrary tables. Understanding GAQL is essential for pulling performance data, auditing campaigns, and building automated optimizations with Cogny.

    API endpoint: GoogleAdsService.SearchStream (streaming) or GoogleAdsService.Search (paged)

    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
    SELECTYesFields to return (resource fields, metrics, segments)
    FROMYesSingle resource type to query
    WHERENoFilter conditions joined by AND (no OR support)
    ORDER BYNoSort by one field, ASC or DESC
    LIMITNoMaximum number of rows to return
    PARAMETERSNoQuery-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
    campaignCampaign settings, status, bidding, budget
    campaign_budgetShared and campaign-level budgets
    campaign_criterionCampaign-level targeting criteria (locations, languages, etc.)
    campaign_bid_modifierBid adjustments at campaign level
    bidding_strategyPortfolio bidding strategies

    Ad Groups & Ads

    ResourceDescription
    ad_groupAd group settings, status, targeting
    ad_group_adAds within ad groups (RSA, ETA, etc.)
    ad_group_ad_asset_viewAsset-level performance for responsive ads
    ad_group_criterionKeywords, audiences, and other criteria in ad groups
    ad_group_bid_modifierBid adjustments at ad group level

    Performance Views

    ResourceDescription
    keyword_viewKeyword-level performance metrics
    search_term_viewActual search queries that triggered ads
    landing_page_viewLanding page performance (expanded/unexpanded URLs)
    geographic_viewPerformance by geographic location
    location_viewPerformance by targeted/excluded location
    age_range_viewPerformance by age range demographic
    gender_viewPerformance by gender demographic
    user_location_viewPerformance by user's physical location
    display_keyword_viewDisplay network keyword performance
    topic_viewDisplay/video topic targeting performance
    managed_placement_viewManaged placement performance

    Conversion & Attribution

    ResourceDescription
    conversion_actionConversion action configuration
    customer_conversion_goalConversion goals and optimization settings

    Account & Extensions

    ResourceDescription
    customerAccount-level settings and descriptive info
    assetAccount assets (sitelinks, callouts, images, etc.)
    asset_groupPerformance Max asset groups
    asset_group_assetAssets within asset groups
    extension_feed_itemLegacy extension feed items

    Change History

    ResourceDescription
    change_statusRecent changes to account entities
    change_eventDetailed change history with old/new values

    Common Fields

    Campaign Fields

    FieldTypeDescription
    campaign.idINT64Unique campaign ID
    campaign.nameSTRINGCampaign name
    campaign.statusENUMENABLED, PAUSED, REMOVED
    campaign.advertising_channel_typeENUMSEARCH, DISPLAY, SHOPPING, VIDEO, PERFORMANCE_MAX, MULTI_CHANNEL
    campaign.advertising_channel_sub_typeENUMFurther channel subtype
    campaign.bidding_strategy_typeENUMTARGET_CPA, TARGET_ROAS, MAXIMIZE_CONVERSIONS, MAXIMIZE_CONVERSION_VALUE, MANUAL_CPC, ENHANCED_CPC, TARGET_IMPRESSION_SHARE
    campaign.campaign_budgetRESOURCEBudget resource name
    campaign.start_dateDATECampaign start date (YYYY-MM-DD)
    campaign.end_dateDATECampaign end date (YYYY-MM-DD)
    campaign.serving_statusENUMActual serving status (SERVING, NONE, ENDED, PENDING, SUSPENDED)
    campaign.target_cpa.target_cpa_microsINT64Target CPA in micros
    campaign.target_roas.target_roasDOUBLETarget ROAS as a ratio (e.g., 3.5 = 350%)

    Ad Group Fields

    FieldTypeDescription
    ad_group.idINT64Unique ad group ID
    ad_group.nameSTRINGAd group name
    ad_group.statusENUMENABLED, PAUSED, REMOVED
    ad_group.typeENUMSEARCH_STANDARD, DISPLAY_STANDARD, SHOPPING_PRODUCT_ADS, etc.
    ad_group.cpc_bid_microsINT64Default CPC bid in micros
    ad_group.target_cpa_microsINT64Ad group-level target CPA

    Ad Fields

    FieldTypeDescription
    ad_group_ad.ad.idINT64Unique ad ID
    ad_group_ad.ad.typeENUMRESPONSIVE_SEARCH_AD, EXPANDED_TEXT_AD, RESPONSIVE_DISPLAY_AD, etc.
    ad_group_ad.ad.final_urlsSTRING (repeated)Landing page URLs
    ad_group_ad.statusENUMENABLED, PAUSED, REMOVED
    ad_group_ad.ad.responsive_search_ad.headlinesMESSAGE (repeated)RSA headline assets
    ad_group_ad.ad.responsive_search_ad.descriptionsMESSAGE (repeated)RSA description assets
    ad_group_ad.policy_summary.approval_statusENUMAPPROVED, APPROVED_LIMITED, AREA_OF_INTEREST_ONLY, DISAPPROVED

    Keyword & Criterion Fields

    FieldTypeDescription
    ad_group_criterion.criterion_idINT64Criterion ID
    ad_group_criterion.keyword.textSTRINGKeyword text
    ad_group_criterion.keyword.match_typeENUMBROAD, PHRASE, EXACT
    ad_group_criterion.statusENUMENABLED, PAUSED, REMOVED
    ad_group_criterion.quality_info.quality_scoreINT32Quality Score (1-10)
    ad_group_criterion.quality_info.creative_quality_scoreENUMBELOW_AVERAGE, AVERAGE, ABOVE_AVERAGE
    ad_group_criterion.quality_info.post_click_quality_scoreENUMLanding page experience
    ad_group_criterion.quality_info.search_predicted_ctrENUMExpected CTR
    ad_group_criterion.effective_cpc_bid_microsINT64Effective CPC bid
    ad_group_criterion.position_estimates.first_page_cpc_microsINT64Estimated first page CPC
    ad_group_criterion.final_urlsSTRING (repeated)Keyword-level final URLs

    Search Term Fields

    FieldTypeDescription
    search_term_view.search_termSTRINGActual user search query
    search_term_view.statusENUMADDED, EXCLUDED, ADDED_EXCLUDED, NONE
    search_term_view.resource_nameSTRINGResource path

    Metrics

    FieldTypeDescription
    metrics.impressionsINT64Number of impressions
    metrics.clicksINT64Number of clicks
    metrics.cost_microsINT64Cost in micros (divide by 1,000,000 for actual currency)
    metrics.ctrDOUBLEClick-through rate (clicks / impressions)
    metrics.average_cpcDOUBLEAverage cost per click in micros
    metrics.average_cpmDOUBLEAverage cost per thousand impressions in micros
    metrics.conversionsDOUBLENumber of conversions
    metrics.conversions_valueDOUBLETotal conversion value
    metrics.cost_per_conversionDOUBLECost per conversion in micros
    metrics.all_conversionsDOUBLEAll conversions (including cross-device)
    metrics.all_conversions_valueDOUBLEAll conversions value
    metrics.view_through_conversionsINT64View-through conversions
    metrics.search_impression_shareDOUBLESearch impression share (0.0 to 1.0)
    metrics.search_top_impression_shareDOUBLETop impression share
    metrics.search_absolute_top_impression_shareDOUBLEAbsolute top impression share
    metrics.search_budget_lost_impression_shareDOUBLEIS lost to budget
    metrics.search_rank_lost_impression_shareDOUBLEIS lost to rank
    metrics.interaction_rateDOUBLEInteraction rate
    metrics.interactionsINT64Interactions
    metrics.video_viewsINT64Video views
    metrics.video_view_rateDOUBLEVideo view rate
    metrics.average_cpvDOUBLEAverage cost per video view in micros
    metrics.bounce_rateDOUBLEBounce rate (when linked to GA)
    metrics.active_view_impressionsINT64Viewable impressions
    metrics.active_view_ctrDOUBLEViewable CTR
    metrics.invalid_clicksINT64Invalid clicks filtered by Google

    Segments

    FieldTypeDescription
    segments.dateDATEDate (YYYY-MM-DD)
    segments.day_of_weekENUMMONDAY through SUNDAY
    segments.monthDATEFirst day of the month
    segments.quarterDATEFirst day of the quarter
    segments.yearINT32Year
    segments.hourINT32Hour of day (0-23)
    segments.deviceENUMDESKTOP, MOBILE, TABLET, OTHER
    segments.ad_network_typeENUMSEARCH, SEARCH_PARTNERS, CONTENT, YOUTUBE_SEARCH, YOUTUBE_WATCH, MIXED
    segments.slotENUMTOP, OTHER
    segments.conversion_actionRESOURCEConversion action resource name
    segments.conversion_action_nameSTRINGConversion action name
    segments.conversion_action_categoryENUMCategory of the conversion action
    segments.click_typeENUMURL_CLICKS, CALLS, SITELINKS, etc.
    segments.keyword.ad_group_criterionRESOURCEKeyword criterion resource
    segments.keyword.info.textSTRINGKeyword text (in search_term_view)
    segments.keyword.info.match_typeENUMKeyword 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
    INcampaign.status IN ('ENABLED', 'PAUSED')
    NOT INcampaign.advertising_channel_type NOT IN ('VIDEO', 'DISPLAY')
    CONTAINS ANYcampaign.labels CONTAINS ANY ('customers/123/labels/456')
    CONTAINS ALLcampaign.labels CONTAINS ALL ('customers/123/labels/456', 'customers/123/labels/789')
    CONTAINS NONEcampaign.labels CONTAINS NONE ('customers/123/labels/456')

    String Operators

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

    Null Checks

    OperatorExample
    IS NULLad_group_criterion.quality_info.quality_score IS NULL
    IS NOT NULLad_group_criterion.quality_info.quality_score IS NOT NULL

    Range Operators

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

    Date Macros (DURING)

    MacroDescription
    TODAYToday only
    YESTERDAYYesterday only
    LAST_7_DAYSLast 7 days (not including today)
    LAST_14_DAYSLast 14 days
    LAST_30_DAYSLast 30 days
    LAST_BUSINESS_WEEKMonday through Friday of the previous week
    THIS_WEEK_MON_TODAYMonday of this week through today
    THIS_WEEK_SUN_TODAYSunday of this week through today
    THIS_MONTHFirst day of this month through today
    LAST_MONTHEntire previous month
    LAST_14_DAYSLast 14 days

    Common Query Patterns

    1. 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
    

    2. Search Terms Report (with 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
    

    Use this to identify wasted spend: filter for search terms with high cost and zero conversions to build negative keyword lists.

    3. 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
    

    4. 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,
      metrics.bounce_rate
    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
    

    5. 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
    

    6. 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
    

    7. Ad Copy Performance (RSA Asset-Level)

    SELECT
      campaign.name,
      ad_group.name,
      ad_group_ad.ad.id,
      ad_group_ad.ad.type,
      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.policy_summary.approval_status,
      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
    

    For asset-level performance (which headline/description combinations performed best):

    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
    

    8. 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
    

    9. 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
    

    10. 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). Always divide by 1,000,000 for human-readable values:

    Actual cost = metrics.cost_micros / 1,000,000
    Actual CPC  = metrics.average_cpc / 1,000,000
    

    For example, cost_micros = 5430000 means $5.43 (or 5.43 in the account's currency).

    Segment + Metric Compatibility

    Not all segments can be used with all metrics. Key rules:

    • segments.conversion_action — when you add this segment, metrics.conversions and metrics.conversions_value break down by conversion action, but metrics.clicks and metrics.impressions will repeat across each conversion action row. Do not sum impressions/clicks when conversion segments are present.
    • segments.click_type — similar issue; clicks and impressions fragment by click type. Summing them will overcount.
    • segments.slot — only compatible with search campaigns.
    • segments.hour — cannot be combined with segments.date in the same query for some resources. Use one or the other.
    • Check the Google Ads API field compatibility matrix when in doubt.

    Date Range Requirements

    • Queries that include any metrics.* field require a date range via segments.date DURING ... or segments.date BETWEEN ... AND ....
    • If you omit the date range, the API returns an error for metric-bearing queries.
    • Resource-only queries (no metrics) do not need a date range.

    Enum Values

    Enum fields must use their string constant names. Common enum values:

    CampaignStatus: ENABLED, PAUSED, REMOVED

    AdGroupStatus: ENABLED, PAUSED, REMOVED

    AdGroupAdStatus: 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, MANUAL_CPM, MANUAL_CPV

    Device: DESKTOP, MOBILE, TABLET, CONNECTED_TV, OTHER

    QualityScoreBucket: BELOW_AVERAGE, AVERAGE, ABOVE_AVERAGE

    Rate Limits

    • Standard access: 15,000 requests per day, 1,600 operations per minute per developer token.
    • Basic access: 10,000 requests per day.
    • Use SearchStream instead of Search for large result sets to avoid pagination overhead and reduce quota consumption.
    • Each SearchStream call counts as one operation regardless of result size.
    • Batch multiple queries in parallel where possible, but respect the per-minute operation limit.

    Other Pitfalls

    • No OR in WHERE: All conditions are AND-joined. To simulate OR, run separate queries or use IN.
    • No joins: GAQL queries operate on a single resource. Use attributed resources (e.g., search_term_view already includes campaign and ad group fields).
    • No GROUP BY: Aggregation is implicit. The API groups by the combination of resource fields and segments you select.
    • No aliases: You cannot use AS in GAQL. Field names are returned as-is.
    • No arithmetic: You cannot do metrics.cost_micros / 1000000 in GAQL. Perform calculations client-side.
    • Segment auto-grouping: Adding a segment to SELECT automatically splits rows by that segment. Selecting segments.device means you get one row per campaign per device, not one row per campaign.
    • Removed resources: By default, REMOVED entities are excluded. To include them, filter explicitly with campaign.status IN ('ENABLED', 'PAUSED', 'REMOVED').
    • PARAMETERS clause: Use PARAMETERS include_drafts = true to include draft campaigns, or PARAMETERS omit_unselected_resource_names = true to reduce response size.

    Next Steps

    Claude Code Skill

    This GAQL reference is also available as a free Claude Code skill -- use it directly in your terminal:

    # Install
    curl -sSL https://raw.githubusercontent.com/cognyai/claude-code-marketing-skills/main/install.sh | bash
    
    # Use
    /gaql-reference                           # 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
    

    View on GitHub →

    Resources

    Ready for similar results?
    Start with Solo at $9/mo or talk to us about Cloud.
    ❯ get startedcompare plans →