Search analytics report
run_search_analytics_reportOrganic search performance for a property: clicks, impressions, CTR, and average position, broken down by the dimensions you choose (query, page, country, device, date, searchAppearance). Filter to a search type (web/image/video/news/discover/googleNews) - discover and googleNews cover Google's Discover feed and Google News; searchAppearance as a dimension is the closest proxy the API currently offers for isolating AI Overview / rich-result rows, since there is no dedicated AI Overview search type yet. Defaults to the last 28 days (Search Console's own default). Use pageFilters to narrow to (or exclude) a URL pattern server-side - e.g. notContains on /dashboard/ and /authenticate/ to drop internal traffic that would otherwise crowd out marketing pages - rather than requesting the maximum rowLimit and filtering client-side. For an exact-URL allowlist ("only these known-good pages"), use the in operator instead of a hand-written regex - it avoids the notContains-as-denylist mismatch and chunks itself automatically to stay under Google's undocumented filter-size ceiling (may take more than one upstream call for a large list). Large requests are paged internally in batches of up to 5000 rows and will stop early with nextStartRow set if they run long, rather than risk a request timeout - pass that back as startRow to continue. collapseVariants merges query-string/scheme duplicates of the same page; brandKeywords adds a derived branded/non-branded field per query row.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | web | |
| endDate | No | YYYY-MM-DD. | |
| siteUrl | No | ||
| rowLimit | No | ||
| startRow | No | Offset for paging beyond rowLimit. | |
| startDate | No | YYYY-MM-DD. Omit with endDate for the last 28 days. | |
| dimensions | No | ||
| pageFilters | No | Filters applied to the `page` dimension server-side, before rowLimit truncates the result. Multiple filters are ANDed together, e.g. [{operator: 'notContains', expression: '/dashboard/'}, {operator: 'notContains', expression: '/authenticate/'}] excludes both paths in one request. At most one filter may use operator `in` (a values array) - matches if the page is any one of them, expanded internally into chunked regex-alternation queries (Google's filter API has no native set-membership or OR operator). | |
| brandKeywords | No | Caller-supplied brand-name substrings/variants (e.g. ['legitfit', 'legit fit', 'legitfit login']) - plain substrings, not regex. When set and `query` is among `dimensions`, adds a derived `brandedVsNonbranded` field per row via case-insensitive substring match. Caybl does not store or infer these keywords - you decide what counts as this tenant's brand and supply the list each call. | |
| collapseVariants | No | Merge rows that are the same logical page but differ only by tracking query-string or http/https/www scheme - sums clicks/impressions and recomputes ctr/position across the merged rows. Only applies when `page` is among `dimensions`. |