Search Analytics (performance) query
search_analyticsGet Google Search clicks, impressions, CTR, and average position for your property, grouped by query, page, device, or date. Analyze performance to find optimization opportunities.
Instructions
Runs a Search Analytics (performance) query for a property: clicks, impressions, CTR and average position from Google Search, grouped by the requested dimensions. Each returned row has keys[] (one value per requested dimension, in the same order) plus clicks, impressions, ctr (a FRACTION 0..1, not a percent) and position; rows are sorted by clicks descending. With no dimensions you get one totals row for the range. Dates are calendar dates in Pacific Time and end_date is INCLUSIVE; final data lags ~2-3 days behind (use data_state "all" for fresh, still-changing rows). Pagination: there is no page token — repeat with start_row increased by row_limit until a response comes back with no rows. When grouping by query/page some anonymized long-tail data is never returned, so summed rows will not match a dimensionless totals query. Quota: 1,200 queries/minute per site and per user.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | Row filters, ALL combined with AND — the API has no OR across filters (run separate queries instead). | |
| end_date | Yes | Last date of the range, YYYY-MM-DD, Pacific Time, inclusive. | |
| site_url | Yes | The property EXACTLY as registered in Search Console. Two formats: URL-prefix — a full URL with scheme and trailing slash, e.g. "https://example.com/" (http/https and www/non-www are different properties), or domain property — "sc-domain:example.com" (no scheme, no slash). A mismatched value returns 403/404; list_sites shows the exact registered values. | |
| row_limit | No | Max rows to return (1..25000; API default 1000). | |
| start_row | No | 0-based row offset for pagination (default 0). A response with no rows means the end. | |
| data_state | No | "final" (default) — only finalized data; "all" — include fresh data still subject to change; "hourly_all" — required when grouping by hour (recent data only). | |
| dimensions | No | How to group rows; keys[] in each row follows this order. "country" values are ISO 3166-1 alpha-3 codes, "device" is DESKTOP/MOBILE/TABLET, "hour" requires data_state "hourly_all". Omit for one totals row. | |
| start_date | Yes | First date of the range, YYYY-MM-DD, Pacific Time. | |
| search_type | No | Which search surface to report: "web" (default), "image", "video", "news" (News tab of search), "discover" (Discover feed), "googleNews" (news.google.com and the app). discover/googleNews support a reduced dimension set — an unsupported combination returns the API's 400 verbatim. | |
| aggregation_type | No | How metrics are aggregated: "auto" (default) lets the API decide, "byPage"/"byProperty" force it, "byNewsShowcasePanel" is for News Showcase. Affects how clicks/impressions are counted, not which rows exist. |