← All articles
Article

Google Search Console API: What It Returns, Its Limits, How to Query It

What the Search Analytics and URL Inspection endpoints return, the row and quota limits Google publishes, and one worked request you can copy.

Written by Sebastian Kinzlinger, Founder, Keylogs

· 11 min read

Google Search Console API: What It Returns, Its Limits, How to Query It
On this page

The Google Search Console API returns the same clicks, impressions, CTR and position data as the Performance report, up to 25,000 rows per request instead of the 1,000 the table shows, plus index status for single URLs. It is a REST service with published quotas and no price list. This post covers what each endpoint returns, where the limits sit, and one request you can copy.

What can you pull from the Google Search Console API?

Google describes the API as programmatic access to "much of the functionality" of Search Console: view, add or remove properties and sitemaps, run queries on Search results data for properties you manage, and test individual pages. You need owner, full or read access to the property, the same as in the UI. [13]Google Search Console API. Overview

For SEO work two endpoints matter.

Search Analytics (searchanalytics.query) is the Performance report as data. Every row carries the four metrics you know from the report: clicks, impressions, CTR as a value between 0 and 1.0, and average position. You choose the grouping with the dimensions list: query, page, country, device, searchAppearance, date and hour. Rows come back sorted by clicks, descending, unless you group by date. [1]Google Search Console API. Method: searchanalytics.query

The type parameter selects the search type. web is the default and means the combined "All" tab; the others are image, video, news (the News tab), googleNews (news.google.com and the app) and discover. The API also lets you filter by any dimension without grouping by it, with equals, contains, notContains, notEquals and two RE2 regex operators. [1]Google Search Console API. Method: searchanalytics.query

URL Inspection (index.inspect) returns the index status of one URL: whether it is indexed, the canonical Google chose, the last crawl time, and whether robots.txt or a noindex rule blocks it. More on it below.

Google's own how-to adds a framing worth keeping in mind: you must decide between "more complete counts" and "more dimensions". Ask for page or query detail and some rows are dropped. [2]Google Search Console API. Getting your performance data

Search Console API limits: rows, quotas and data freshness

Three different limits get mixed up under "API limits". They are not the same thing.

LimitValue Google publishesWhere it bites
Rows per requestrowLimit 1 to 25,000, default 1,000; page with startRow [1]Google Search Console API. Method: searchanalytics.queryAny export larger than one page
Rows per day per search type50,000, sorted by clicks [2]Google Search Console API. Getting your performance dataLarge sites grouped by page or query
Search Analytics calls1,200 per minute per site and per user; 40,000 per minute and 30,000,000 per day per project [3]Google Search Console API. Usage LimitsScripts that loop over many properties or days
Load quotaMeasured in 10-minute and 1-day chunks; no number published [3]Google Search Console API. Usage LimitsWide date ranges grouped by page and query
URL Inspection calls2,000 per day and 600 per minute per site [3]Google Search Console API. Usage LimitsBulk index checks
History16 months [11]Google Analytics Help. [GA4] Queries reportYear-over-year beyond that

The row limit is the one to understand first. A single request returns at most 25,000 rows, and you page through a larger result by re-running the same request with startRow increased by 25,000 until a response comes back with zero rows. [2]Google Search Console API. Getting your performance data But the reference page also says the API "does not guarantee to return all data rows but rather top ones", and the how-to puts a number on that: at most 50,000 rows of data per day per search type, sorted by clicks. [1]Google Search Console API. Method: searchanalytics.query [2]Google Search Console API. Getting your performance data On a site with 200,000 query-page combinations in a day, pagination gets you the top 50,000 by clicks and then stops. The long tail is not retrievable through this endpoint, which is why the anonymized queries and row limits post sends large sites to bulk export.

The load quota is the one people hit without knowing it. Google says grouping or filtering by page or query is expensive, page and query together is the most expensive, and a six-month range costs much more than one day. Its advice is to query one day at a time and never re-request the same data. [2]Google Search Console API. Getting your performance data [3]Google Search Console API. Usage Limits

Freshness is controlled by dataState. Leave it out, or set final, and you get only finalized days. Set all and the response includes fresh data that can still change; the response then carries a first_incomplete_date field telling you from which day onward the numbers may move. hourly_all goes with the hour dimension. [1]Google Search Console API. Method: searchanalytics.query Google's help pages say collected data is normally available in 2 to 3 days, and the fresh-data announcement explains that each fresh point is replaced by a final one after a few days. [6]Google Search Console Help. About Search Console data [12]Google Search Central Blog. Fresher data in your site's Search Performance report

The thing people get wrong: the 25,000 figure is a page size, not a ceiling on your data. The ceiling is 50,000 rows a day per search type, and it applies only when you ask for page or query detail. Totals without those dimensions are complete.

How to query the Search Analytics API (a worked request)

The endpoint is a POST to https://www.googleapis.com/webmasters/v3/sites/{siteUrl}/searchAnalytics/query, where siteUrl is the property exactly as Search Console names it: sc-domain:example.com for a Domain property, or the full prefix with trailing slash for a URL-prefix property, URL-encoded. The request needs the webmasters.readonly or webmasters OAuth scope. [1]Google Search Console API. Method: searchanalytics.query

1. Confirm which days have data

Google recommends a quick query grouped by date with no filters first, because the most recent day or two is often missing. [14]Google Search Console API. Query your Google Search analytics data

{
  "startDate": "2026-10-20",
  "endDate": "2026-11-03",
  "dimensions": ["date"]
}

If the last row is 2026-11-01, that is your latest final day.

2. Pull queries and pages for one day

This request asks for every query-page pair on web search for a single day, 25,000 rows at a time:

{
  "startDate": "2026-11-01",
  "endDate": "2026-11-01",
  "dimensions": ["query", "page"],
  "type": "web",
  "rowLimit": 25000,
  "startRow": 0
}

Dates are inclusive and interpreted in Pacific time. [1]Google Search Console API. Method: searchanalytics.query The response looks like this (figures constructed to illustrate the shape):

{
  "rows": [
    {
      "keys": ["keyword cannibalization", "https://example.com/blog/keyword-cannibalization"],
      "clicks": 42,
      "impressions": 1310,
      "ctr": 0.0320,
      "position": 7.4
    }
  ],
  "responseAggregationType": "byPage"
}

keys follows the order of your dimensions. ctr is a fraction, so 0.032 is 3.2 %. responseAggregationType tells you how the row was aggregated: because the request grouped by page, the API aggregated by page, and it will refuse byProperty for any request that groups or filters by page. [1]Google Search Console API. Method: searchanalytics.query

3. Page until the rows run out

Re-send the same body with startRow: 25000, then 50000, until a response contains no rows. Google's own pseudocode does exactly this in a loop, with the date set three days back to stay on final data. [2]Google Search Console API. Getting your performance data If a page comes back with fewer rows than rowLimit, you already have everything. [14]Google Search Console API. Query your Google Search analytics data

4. Repeat per search type

Each type is a separate request. Run the same loop with image, video or discover if those matter for the site. [2]Google Search Console API. Getting your performance data

Filters go in dimensionFilterGroups. To restrict step 2 to one directory, add a filter on page with the contains operator, or includingRegex for anything more precise. Only the and group type is supported. [1]Google Search Console API. Method: searchanalytics.query

Why API totals differ from the Performance report

Nine times out of ten the answer is aggregation. The Performance report chart is always aggregated by property. The table switches to by-page aggregation as soon as you group by Pages or Search appearance. [7]Google Search Console Help. Performance report (Search results): Dimensions and data groupings By property, a query where your site appears twice counts one impression and reports the topmost position; by page, each URL counts its own impression and its own position. CTR and average position are therefore generally higher by property. [8]Google Search Console Help. Performance report (Search results): About the data

The API behaves the same way. A request with page in its dimensions is aggregated by page. A request without it, and without a page filter, defaults to by-property. So an API export grouped by page will not sum to the chart total, and it is not supposed to. [1]Google Search Console API. Method: searchanalytics.query [8]Google Search Console Help. Performance report (Search results): About the data

The second cause is anonymized queries. Google omits rare queries from query-level rows for privacy but includes them in chart totals unless a query filter is applied. [7]Google Search Console Help. Performance report (Search results): Dimensions and data groupings Your API rows grouped by query miss them too; the gap between a no-dimension total and the sum of your query rows is the size of that privacy hole plus any truncation. Google's troubleshooting page lists the same four reasons for chart-versus-table gaps in the UI: aggregation, the 1,000-row table limit, anonymized queries, and filtered totals that do not add up. [15]Google Search Console Help. Performance report (Search results): Troubleshooting data discrepancies

Third, the table itself. Google says Search Console stores "only the most important data rows", so the UI table at 1,000 rows and the API at 50,000 a day are both views of a pre-truncated set. [7]Google Search Console Help. Performance report (Search results): Dimensions and data groupings

Practical rule: for totals you can reconcile with the chart, send one request with no page and no query dimension. For detail, accept that the rows will not sum, and compare like with like. If you report this data to clients, the Search Console metrics for client reporting post covers how to present the gap.

API vs bulk export vs the UI: which to use

Performance report (UI)Search Analytics APIBulk data export
Rows1,000 per table [6]Google Search Console Help. About Search Console data25,000 per request, 50,000 a day per search type with page or query [1]Google Search Console API. Method: searchanalytics.query [2]Google Search Console API. Getting your performance dataAll performance data Google has for the property, except anonymized queries [16]Google Search Console Help. About bulk data export of Search Console data to BigQuery
History16 months [11]Google Analytics Help. [GA4] Queries report16 months [11]Google Analytics Help. [GA4] Queries reportFrom the day you set it up; no backfill [10]Google Search Console Help. Start a new bulk data export
Anonymized queriesOmitted from the query table, in chart totals [7]Google Search Console Help. Performance report (Search results): Dimensions and data groupingsOmitted from query rowsFlagged with is_anonymized_query, query text blank [9]Google Search Console Help. Table guidelines and reference (bulk data export)
CostNone statedQuotas, no price stated [3]Google Search Console API. Usage LimitsBigQuery storage and query charges above the free level [10]Google Search Console Help. Start a new bulk data export
SetupNoneCloud project, OAuth, codeCloud project with billing, BigQuery, service account roles [10]Google Search Console Help. Start a new bulk data export

Use the UI for a look. Use the API when you want to keep history, join Search Console with other data, or run the same check every week. Use bulk export when 50,000 rows a day is not enough, and set it up early: the first export happens up to 48 hours after configuration and includes only data from that day forward, so every month you wait is a month you will never have in BigQuery. [10]Google Search Console Help. Start a new bulk data export

Keylogs sits on the API side of that table. The SEO low hanging fruit finder reads your Search Console data through a read-only Google sign-in, keeps the keywords in positions 4 to 30, and scores each one against your site's own click-through curve rather than a generic table. Very large properties are capped to the top queries by impressions so the scan stays fast, and the report notes when that happened.

The URL Inspection API: quota and the fields it returns

index.inspect is a POST to https://searchconsole.googleapis.com/v1/urlInspection/index:inspect with three fields: inspectionUrl, siteUrl and an optional languageCode. The URL must belong to the property. Google is explicit that it reports "only the status of the version in the Google index"; you cannot run a live test through the API. [4]Google Search Console API. Method: index.inspect

The quota is per site: 2,000 calls a day and 600 a minute, with a much larger per-project ceiling. [3]Google Search Console API. Usage Limits That is enough to check a few thousand URLs overnight, not enough to audit a large site daily.

The useful part of the response is indexStatusResult: [5]Google Search Console API. UrlInspectionResult

FieldWhat it tells you
verdictPASS is "Valid" in the UI, FAIL is "Error", NEUTRAL is "Excluded"
coverageStateThe same status text as the Page indexing report
indexingStateINDEXING_ALLOWED, or blocked by a noindex meta tag or X-Robots-Tag header
robotsTxtStateALLOWED or DISALLOWED
pageFetchStateSUCCESSFUL, SOFT_404, NOT_FOUND, SERVER_ERROR, REDIRECT_ERROR and others
googleCanonical / userCanonicalThe canonical Google selected versus the one you declared; googleCanonical is absent when the page is not indexed
lastCrawlTimeLast successful crawl by the primary crawler, absent if never crawled
crawledAsDESKTOP or MOBILE
referringUrls / sitemapKnown inbound links and sitemaps listing the URL

The pair worth scripting is googleCanonical against userCanonical. When they disagree across many URLs you have a canonical problem, and the post on Google choosing different canonical URLs walks through the causes. For a traffic drop, pulling coverageState and lastCrawlTime for your top pages is the fastest way to rule out indexing before you start on the traffic drop checklist.

The response also carries a link back to the UI (inspectionResultLink), an AMP block when the page is AMP, and a rich results block when structured data was found. The mobile usability block is deprecated. [5]Google Search Console API. UrlInspectionResult

What to do next in Search Console

Open the Performance report, set the date range to the last 16 months, and note how many rows the Queries tab shows. If it stops at 1,000, the API will give you more; if your site is large, start the bulk export today so the history exists when you need it. Then write the one-day pagination loop above, run it once for web, and compare its clicks total against a second request with no dimensions. The difference is your anonymized and truncated share, and it is the first number to explain before anyone compares API exports to the UI.

Frequently asked questions

Is the Google Search Console API free?
Google's API documentation publishes usage quotas, not prices, and the API needs only a Google Cloud project and a verified property. The one route that can cost money is bulk export, where Google says BigQuery storage and query usage above the free level is charged.
How far back does the Search Console API go?
Google states that Search Console keeps data for the last 16 months, so a Search Analytics query can span at most that window. Older days are gone, which is why a daily export job is the only way to keep a longer history.
Does the API include anonymized queries?
No. Google omits rare queries from query-level results in the report and the API to protect privacy, and the developer docs add that grouping by page or query may drop rows. Those searches still count in totals from a query without the query dimension.
Why does my API export show fewer rows than the Performance report chart suggests?
The chart is aggregated by property and includes anonymized queries, while a query grouped by page or query is capped at 50,000 rows a day per search type and omits anonymized rows. Run one request without the page and query dimensions to get totals that match the chart.
Can I check indexing for many URLs through the API?
Yes, within limits. The URL Inspection API allows 2,000 calls a day and 600 a minute per site, and it only reports the version in Google's index, not a live test of the page.

Article sources

  1. Google Search Console API. “Method: searchanalytics.query”. Accessed Nov 5, 2026.
  2. Google Search Console API. “Getting your performance data”. Accessed Nov 5, 2026.
  3. Google Search Console API. “Usage Limits”. Accessed Nov 5, 2026.
  4. Google Search Console API. “Method: index.inspect”. Accessed Nov 5, 2026.
  5. Google Search Console API. “UrlInspectionResult”. Accessed Nov 5, 2026.
  6. Google Search Console Help. “About Search Console data”. Accessed Nov 5, 2026.
  7. Google Search Console Help. “Performance report (Search results): Dimensions and data groupings”. Accessed Nov 5, 2026.
  8. Google Search Console Help. “Performance report (Search results): About the data”. Accessed Nov 5, 2026.
  9. Google Search Console Help. “Table guidelines and reference (bulk data export)”. Accessed Nov 5, 2026.
  10. Google Search Console Help. “Start a new bulk data export”. Accessed Nov 5, 2026.
  11. Google Analytics Help. “[GA4] Queries report”. Accessed Nov 5, 2026.
  12. Google Search Central Blog. “Fresher data in your site's Search Performance report”. Accessed Nov 5, 2026.
  13. Google Search Console API. “Overview”. Accessed Nov 5, 2026.
  14. Google Search Console API. “Query your Google Search analytics data”. Accessed Nov 5, 2026.
  15. Google Search Console Help. “Performance report (Search results): Troubleshooting data discrepancies”. Accessed Nov 5, 2026.
  16. Google Search Console Help. “About bulk data export of Search Console data to BigQuery”. Accessed Nov 5, 2026.

Keylogs requires writers to use primary sources — Google's own documentation and original Search Console data. Learn more about our editorial standards.