Back to Blog
google-adsgaqlreference

GAQL Queries: The Complete Reference

A comprehensive reference for Google Ads Query Language (GAQL). Covers syntax, common queries, filtering, sorting, date ranges, and how Xylo abstracts GAQL away.

Xylo Team|March 5, 2026|7 min read

What Is GAQL?

GAQL (Google Ads Query Language) is a SQL-like query language used to retrieve data from the Google Ads API. Unlike most REST APIs where you specify fields as query parameters, Google Ads requires you to write structured queries that define the resource, fields, filters, and sort order.

If you have used SQL, GAQL will look familiar. If you have not, it adds a significant learning curve to Google Ads API integration.

GAQL Syntax

The basic structure:

SELECT field1, field2, field3
FROM resource
WHERE condition1 AND condition2
ORDER BY field1 DESC
LIMIT 100

Clauses

Clause Required Purpose
SELECT Yes Fields to return
FROM Yes Resource type (campaign, ad_group, etc.)
WHERE No Filter conditions
ORDER BY No Sort results
LIMIT No Maximum rows returned
PARAMETERS No Additional options (like include_drafts)

Resources

GAQL queries operate on specific resources. The most common:

Resource Description
campaign Campaign-level data
ad_group Ad group-level data
ad_group_ad Individual ad data
keyword_view Keyword performance
search_term_view Search term report
campaign_budget Budget configuration
customer Account-level data
geographic_view Geographic performance
age_range_view Age demographic data
gender_view Gender demographic data

Common Queries

Campaign Performance

SELECT
  campaign.id,
  campaign.name,
  campaign.status,
  campaign.advertising_channel_type,
  campaign_budget.amount_micros,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions,
  metrics.cost_per_conversion,
  metrics.click_through_rate,
  metrics.average_cpc
FROM campaign
WHERE campaign.status != 'REMOVED'
  AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.cost_micros DESC

Note: cost_micros and amount_micros are in micros (1,000,000 = $1.00). You must divide by 1,000,000 to get dollars.

Ad Group Performance

SELECT
  ad_group.id,
  ad_group.name,
  ad_group.status,
  ad_group.type,
  campaign.name,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions,
  metrics.average_cpc
FROM ad_group
WHERE ad_group.status = 'ENABLED'
  AND campaign.status = 'ENABLED'
  AND segments.date DURING LAST_7_DAYS
ORDER BY metrics.conversions DESC
LIMIT 50

Keyword Performance

SELECT
  ad_group_criterion.keyword.text,
  ad_group_criterion.keyword.match_type,
  ad_group.name,
  campaign.name,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions,
  metrics.search_impression_share,
  metrics.quality_score
FROM keyword_view
WHERE segments.date DURING LAST_7_DAYS
  AND ad_group_criterion.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
LIMIT 100

Search Terms Report

See what actual search queries triggered your ads:

SELECT
  search_term_view.search_term,
  search_term_view.status,
  campaign.name,
  ad_group.name,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions
FROM search_term_view
WHERE segments.date DURING LAST_7_DAYS
  AND metrics.impressions > 10
ORDER BY metrics.impressions DESC
LIMIT 200

Daily Performance Breakdown

SELECT
  segments.date,
  campaign.name,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions
FROM campaign
WHERE segments.date BETWEEN '2026-03-01' AND '2026-03-31'
  AND campaign.status != 'REMOVED'
ORDER BY segments.date DESC

Geographic Performance

SELECT
  geographic_view.country_criterion_id,
  geographic_view.location_type,
  campaign.name,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions
FROM geographic_view
WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.cost_micros DESC
LIMIT 50

Filtering with WHERE

Comparison Operators

WHERE metrics.impressions > 1000
WHERE campaign.status = 'ENABLED'
WHERE campaign.status != 'REMOVED'
WHERE metrics.cost_micros >= 1000000  -- at least $1
WHERE campaign.name LIKE '%Brand%'
WHERE campaign.name NOT LIKE '%Test%'

Date Filtering

GAQL supports predefined date ranges and custom ranges:

-- 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
WHERE segments.date DURING THIS_QUARTER
WHERE segments.date DURING LAST_YEAR

-- Custom range
WHERE segments.date BETWEEN '2026-01-01' AND '2026-03-31'

-- Single date
WHERE segments.date = '2026-03-15'

Enum Filtering

Many fields use enum values that must be referenced exactly:

-- Campaign status
WHERE campaign.status IN ('ENABLED', 'PAUSED')

-- Campaign type
WHERE campaign.advertising_channel_type = 'SEARCH'

-- Keyword match type
WHERE ad_group_criterion.keyword.match_type = 'EXACT'

Combining Conditions

WHERE campaign.status = 'ENABLED'
  AND metrics.impressions > 100
  AND segments.date DURING LAST_7_DAYS
  AND campaign.advertising_channel_type IN ('SEARCH', 'SHOPPING')

GAQL supports AND but does not support OR at the top level. To achieve OR-like behavior, you need to run multiple queries.

Segments

Segments add dimensional breakdowns to your data. When you include a segment in the SELECT clause, the data is broken down by that dimension:

-- Daily breakdown
SELECT
  segments.date,
  campaign.name,
  metrics.cost_micros,
  metrics.conversions
FROM campaign
WHERE segments.date DURING LAST_7_DAYS

-- Device breakdown
SELECT
  segments.device,
  campaign.name,
  metrics.cost_micros,
  metrics.conversions
FROM campaign
WHERE segments.date DURING LAST_7_DAYS

-- Hour of day breakdown
SELECT
  segments.hour,
  campaign.name,
  metrics.impressions,
  metrics.clicks
FROM campaign
WHERE segments.date = '2026-03-15'

Segment Compatibility

Not all segments work with all resources. Mixing incompatible segments causes an error. Common compatible combinations:

Resource Compatible Segments
campaign date, device, ad_network_type, click_type
ad_group date, device, ad_network_type
keyword_view date, device
search_term_view date
geographic_view date

GAQL Gotchas

1. Micros Everywhere

All monetary values are in micros. This is easy to forget:

metrics.cost_micros = 15234560  →  $15.23
metrics.average_cpc = 234500    →  $0.23
campaign_budget.amount_micros = 50000000  →  $50.00

2. No Joins

GAQL does not support JOIN operations. You cannot combine data from different resources in a single query. To correlate campaign and ad group data, run separate queries and join in your application code.

3. Field Compatibility

Not every field combination is valid. You cannot select campaign.name from customer resource, for example. Google's documentation lists compatible fields for each resource.

4. Rate Limits

Each GAQL query counts as one API operation. With Basic access, you get 15,000 operations per day. Complex queries that return large result sets may consume additional quota.

5. Date Segment Requirement

If you use segments.date in the WHERE clause, you must also include it in the SELECT clause. Omitting it causes an error.

How Xylo Abstracts GAQL Away

If you are using Xylo, you never need to write GAQL. Xylo translates standard REST query parameters into GAQL internally:

What You Want GAQL Xylo
Last 7 days of campaign data Write the full SELECT/FROM/WHERE query ?date_preset=last_7d
Only active campaigns WHERE campaign.status = 'ENABLED' ?status=active
Sort by spend ORDER BY metrics.cost_micros DESC ?sort=spend&order=desc
Limit results LIMIT 25 ?limit=25

Example -- fetching campaign performance:

# GAQL approach (raw API)
# 1. Set up OAuth, developer token, client library
# 2. Write GAQL query
# 3. Parse micros, enum values, nested objects

# Xylo approach
curl "https://api.xyloapi.dev/v1/campaigns?date_preset=last_7d&status=active" \
  -H "x-api-key: xylo_live_abc123" \
  -H "x-ad-account: customers/1234567890"

Both return the same data. Xylo converts micros to dollars, maps enum values to readable strings, and returns a normalized JSON structure identical to what you get from Meta and TikTok campaigns.

When to Use GAQL Directly

GAQL is worth learning if:

  • You need custom segmentation beyond what Xylo exposes (e.g., hour-of-day breakdowns)
  • You are building a Google Ads-specific product that needs maximum flexibility
  • You need search term reports or keyword-level data with specific filters
  • You are debugging performance issues and need raw data access

Getting Started

If you want to skip GAQL and use a clean REST interface:

  1. Sign up for Xylo and connect your Google Ads account.
  2. Use standard query parameters instead of GAQL syntax.
  3. Get normalized responses with dollars (not micros) and readable status values.

If you need the raw Google Ads API, start with our Google Ads API getting started guide for authentication setup.

For cross-platform reporting that combines Google and Meta data, read our cross-platform reporting guide. Check the API documentation for the complete Xylo endpoint reference.

Ready to simplify your ads API integration?

Get started with Xylo in minutes. One API key for every ad platform.