[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"post:\u002Fblog\u002Fgoogle-search-console-api":3,"blog-order":1297},{"page":4,"collection":1296},{"id":5,"title":6,"author":7,"body":8,"bottomLine":1210,"cluster":1210,"cta":1211,"date":1212,"definition":1210,"description":1213,"draft":1214,"extension":1215,"factChecker":1210,"faq":1216,"image":1232,"meta":1233,"meta_description":1234,"meta_title":1235,"navigation":1236,"path":1237,"related":1210,"reviewer":1210,"seo":1238,"sitemap":1239,"sources":1240,"stem":1294,"summary":1210,"takeaways":1210,"term":1210,"tier":1210,"updated":1210,"__hash__":1295},"posts\u002Fblog\u002Fgoogle-search-console-api.md","Google Search Console API: What It Returns, Its Limits, How to Query It","sebastian",{"type":9,"value":10,"toc":1196},"minimark",[11,15,20,27,30,92,136,145,151,155,158,268,287,294,332,341,345,370,375,384,453,456,460,463,551,557,670,693,697,716,720,735,758,762,772,782,794,799,813,817,934,939,947,951,973,979,988,1149,1173,1182,1186,1192],[12,13,14],"p",{},"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.",[16,17,19],"h2",{"id":18},"what-can-you-pull-from-the-google-search-console-api","What can you pull from the Google Search Console API?",[12,21,22,23],{},"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. ",[24,25],"cite-ref",{"n":26},"13",[12,28,29],{},"For SEO work two endpoints matter.",[12,31,32,36,37,41,42,47,48,47,52,56,57,61,62,65,66,47,69,47,72,47,75,47,78,47,81,84,85,88,89],{},[33,34,35],"strong",{},"Search Analytics"," (",[38,39,40],"code",{},"searchanalytics.query",") is the Performance report as data. Every row carries the four metrics you know from the report: ",[43,44,46],"a",{"href":45},"\u002Fglossary\u002Fsearch-console-clicks","clicks",", ",[43,49,51],{"href":50},"\u002Fglossary\u002Fsearch-console-impressions","impressions",[43,53,55],{"href":54},"\u002Fglossary\u002Fsearch-console-ctr","CTR"," as a value between 0 and 1.0, and ",[43,58,60],{"href":59},"\u002Fglossary\u002Fsearch-console-average-position","average position",". You choose the grouping with the ",[38,63,64],{},"dimensions"," list: ",[38,67,68],{},"query",[38,70,71],{},"page",[38,73,74],{},"country",[38,76,77],{},"device",[38,79,80],{},"searchAppearance",[38,82,83],{},"date"," and ",[38,86,87],{},"hour",". Rows come back sorted by clicks, descending, unless you group by date. ",[24,90],{"n":91},"1",[12,93,94,95,98,99,102,103,47,106,47,109,112,113,116,117,120,121,47,124,47,127,47,130,133,134],{},"The ",[38,96,97],{},"type"," parameter selects the search type. ",[38,100,101],{},"web"," is the default and means the combined \"All\" tab; the others are ",[38,104,105],{},"image",[38,107,108],{},"video",[38,110,111],{},"news"," (the News tab), ",[38,114,115],{},"googleNews"," (news.google.com and the app) and ",[38,118,119],{},"discover",". The API also lets you filter by any dimension without grouping by it, with ",[38,122,123],{},"equals",[38,125,126],{},"contains",[38,128,129],{},"notContains",[38,131,132],{},"notEquals"," and two RE2 regex operators. ",[24,135],{"n":91},[12,137,138,36,141,144],{},[33,139,140],{},"URL Inspection",[38,142,143],{},"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.",[12,146,147,148],{},"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. ",[24,149],{"n":150},"2",[16,152,154],{"id":153},"search-console-api-limits-rows-quotas-and-data-freshness","Search Console API limits: rows, quotas and data freshness",[12,156,157],{},"Three different limits get mixed up under \"API limits\". They are not the same thing.",[159,160,161,177],"table",{},[162,163,164],"thead",{},[165,166,167,171,174],"tr",{},[168,169,170],"th",{},"Limit",[168,172,173],{},"Value Google publishes",[168,175,176],{},"Where it bites",[178,179,180,201,214,228,241,254],"tbody",{},[165,181,182,186,198],{},[183,184,185],"td",{},"Rows per request",[183,187,188,191,192,195,196],{},[38,189,190],{},"rowLimit"," 1 to 25,000, default 1,000; page with ",[38,193,194],{},"startRow"," ",[24,197],{"n":91},[183,199,200],{},"Any export larger than one page",[165,202,203,206,211],{},[183,204,205],{},"Rows per day per search type",[183,207,208,209],{},"50,000, sorted by clicks ",[24,210],{"n":150},[183,212,213],{},"Large sites grouped by page or query",[165,215,216,219,225],{},[183,217,218],{},"Search Analytics calls",[183,220,221,222],{},"1,200 per minute per site and per user; 40,000 per minute and 30,000,000 per day per project ",[24,223],{"n":224},"3",[183,226,227],{},"Scripts that loop over many properties or days",[165,229,230,233,238],{},[183,231,232],{},"Load quota",[183,234,235,236],{},"Measured in 10-minute and 1-day chunks; no number published ",[24,237],{"n":224},[183,239,240],{},"Wide date ranges grouped by page and query",[165,242,243,246,251],{},[183,244,245],{},"URL Inspection calls",[183,247,248,249],{},"2,000 per day and 600 per minute per site ",[24,250],{"n":224},[183,252,253],{},"Bulk index checks",[165,255,256,259,265],{},[183,257,258],{},"History",[183,260,261,262],{},"16 months ",[24,263],{"n":264},"11",[183,266,267],{},"Year-over-year beyond that",[12,269,270,271,273,274,276,277,195,279,281,282,286],{},"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 ",[38,272,194],{}," increased by 25,000 until a response comes back with zero rows. ",[24,275],{"n":150}," 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. ",[24,278],{"n":91},[24,280],{"n":150}," 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 ",[43,283,285],{"href":284},"\u002Fblog\u002Fanonymized-queries-vs-search-console-row-limits","anonymized queries and row limits post"," sends large sites to bulk export.",[12,288,289,290,195,292],{},"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. ",[24,291],{"n":150},[24,293],{"n":224},[12,295,296,299,300,303,304,307,308,311,312,315,316,319,320,322,323,325,326,195,329],{},[33,297,298],{},"Freshness"," is controlled by ",[38,301,302],{},"dataState",". Leave it out, or set ",[38,305,306],{},"final",", and you get only finalized days. Set ",[38,309,310],{},"all"," and the response includes fresh data that can still change; the response then carries a ",[38,313,314],{},"first_incomplete_date"," field telling you from which day onward the numbers may move. ",[38,317,318],{},"hourly_all"," goes with the ",[38,321,87],{}," dimension. ",[24,324],{"n":91}," 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. ",[24,327],{"n":328},"6",[24,330],{"n":331},"12",[333,334,335],"blockquote",{},[12,336,337,340],{},[33,338,339],{},"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.",[16,342,344],{"id":343},"how-to-query-the-search-analytics-api-a-worked-request","How to query the Search Analytics API (a worked request)",[12,346,347,348,351,352,355,356,359,360,363,364,367,368],{},"The endpoint is a POST to ",[38,349,350],{},"https:\u002F\u002Fwww.googleapis.com\u002Fwebmasters\u002Fv3\u002Fsites\u002F{siteUrl}\u002FsearchAnalytics\u002Fquery",", where ",[38,353,354],{},"siteUrl"," is the property exactly as Search Console names it: ",[38,357,358],{},"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 ",[38,361,362],{},"webmasters.readonly"," or ",[38,365,366],{},"webmasters"," OAuth scope. ",[24,369],{"n":91},[371,372,374],"h3",{"id":373},"_1-confirm-which-days-have-data","1. Confirm which days have data",[12,376,377,378,380,381],{},"Google recommends a quick query grouped by ",[38,379,83],{}," with no filters first, because the most recent day or two is often missing. ",[24,382],{"n":383},"14",[385,386,391],"pre",{"className":387,"code":388,"language":389,"meta":390,"style":390},"language-json shiki shiki-themes github-light github-dark","{\n  \"startDate\": \"2026-10-20\",\n  \"endDate\": \"2026-11-03\",\n  \"dimensions\": [\"date\"]\n}\n","json","",[38,392,393,402,419,432,447],{"__ignoreMap":390},[394,395,398],"span",{"class":396,"line":397},"line",1,[394,399,401],{"class":400},"sVt8B","{\n",[394,403,405,409,412,416],{"class":396,"line":404},2,[394,406,408],{"class":407},"sj4cs","  \"startDate\"",[394,410,411],{"class":400},": ",[394,413,415],{"class":414},"sZZnC","\"2026-10-20\"",[394,417,418],{"class":400},",\n",[394,420,422,425,427,430],{"class":396,"line":421},3,[394,423,424],{"class":407},"  \"endDate\"",[394,426,411],{"class":400},[394,428,429],{"class":414},"\"2026-11-03\"",[394,431,418],{"class":400},[394,433,435,438,441,444],{"class":396,"line":434},4,[394,436,437],{"class":407},"  \"dimensions\"",[394,439,440],{"class":400},": [",[394,442,443],{"class":414},"\"date\"",[394,445,446],{"class":400},"]\n",[394,448,450],{"class":396,"line":449},5,[394,451,452],{"class":400},"}\n",[12,454,455],{},"If the last row is 2026-11-01, that is your latest final day.",[371,457,459],{"id":458},"_2-pull-queries-and-pages-for-one-day","2. Pull queries and pages for one day",[12,461,462],{},"This request asks for every query-page pair on web search for a single day, 25,000 rows at a time:",[385,464,466],{"className":387,"code":465,"language":389,"meta":390,"style":390},"{\n  \"startDate\": \"2026-11-01\",\n  \"endDate\": \"2026-11-01\",\n  \"dimensions\": [\"query\", \"page\"],\n  \"type\": \"web\",\n  \"rowLimit\": 25000,\n  \"startRow\": 0\n}\n",[38,467,468,472,483,493,510,522,535,546],{"__ignoreMap":390},[394,469,470],{"class":396,"line":397},[394,471,401],{"class":400},[394,473,474,476,478,481],{"class":396,"line":404},[394,475,408],{"class":407},[394,477,411],{"class":400},[394,479,480],{"class":414},"\"2026-11-01\"",[394,482,418],{"class":400},[394,484,485,487,489,491],{"class":396,"line":421},[394,486,424],{"class":407},[394,488,411],{"class":400},[394,490,480],{"class":414},[394,492,418],{"class":400},[394,494,495,497,499,502,504,507],{"class":396,"line":434},[394,496,437],{"class":407},[394,498,440],{"class":400},[394,500,501],{"class":414},"\"query\"",[394,503,47],{"class":400},[394,505,506],{"class":414},"\"page\"",[394,508,509],{"class":400},"],\n",[394,511,512,515,517,520],{"class":396,"line":449},[394,513,514],{"class":407},"  \"type\"",[394,516,411],{"class":400},[394,518,519],{"class":414},"\"web\"",[394,521,418],{"class":400},[394,523,525,528,530,533],{"class":396,"line":524},6,[394,526,527],{"class":407},"  \"rowLimit\"",[394,529,411],{"class":400},[394,531,532],{"class":407},"25000",[394,534,418],{"class":400},[394,536,538,541,543],{"class":396,"line":537},7,[394,539,540],{"class":407},"  \"startRow\"",[394,542,411],{"class":400},[394,544,545],{"class":407},"0\n",[394,547,549],{"class":396,"line":548},8,[394,550,452],{"class":400},[12,552,553,554,556],{},"Dates are inclusive and interpreted in Pacific time. ",[24,555],{"n":91}," The response looks like this (figures constructed to illustrate the shape):",[385,558,560],{"className":387,"code":559,"language":389,"meta":390,"style":390},"{\n  \"rows\": [\n    {\n      \"keys\": [\"keyword cannibalization\", \"https:\u002F\u002Fexample.com\u002Fblog\u002Fkeyword-cannibalization\"],\n      \"clicks\": 42,\n      \"impressions\": 1310,\n      \"ctr\": 0.0320,\n      \"position\": 7.4\n    }\n  ],\n  \"responseAggregationType\": \"byPage\"\n}\n",[38,561,562,566,574,579,596,608,620,632,642,648,654,665],{"__ignoreMap":390},[394,563,564],{"class":396,"line":397},[394,565,401],{"class":400},[394,567,568,571],{"class":396,"line":404},[394,569,570],{"class":407},"  \"rows\"",[394,572,573],{"class":400},": [\n",[394,575,576],{"class":396,"line":421},[394,577,578],{"class":400},"    {\n",[394,580,581,584,586,589,591,594],{"class":396,"line":434},[394,582,583],{"class":407},"      \"keys\"",[394,585,440],{"class":400},[394,587,588],{"class":414},"\"keyword cannibalization\"",[394,590,47],{"class":400},[394,592,593],{"class":414},"\"https:\u002F\u002Fexample.com\u002Fblog\u002Fkeyword-cannibalization\"",[394,595,509],{"class":400},[394,597,598,601,603,606],{"class":396,"line":449},[394,599,600],{"class":407},"      \"clicks\"",[394,602,411],{"class":400},[394,604,605],{"class":407},"42",[394,607,418],{"class":400},[394,609,610,613,615,618],{"class":396,"line":524},[394,611,612],{"class":407},"      \"impressions\"",[394,614,411],{"class":400},[394,616,617],{"class":407},"1310",[394,619,418],{"class":400},[394,621,622,625,627,630],{"class":396,"line":537},[394,623,624],{"class":407},"      \"ctr\"",[394,626,411],{"class":400},[394,628,629],{"class":407},"0.0320",[394,631,418],{"class":400},[394,633,634,637,639],{"class":396,"line":548},[394,635,636],{"class":407},"      \"position\"",[394,638,411],{"class":400},[394,640,641],{"class":407},"7.4\n",[394,643,645],{"class":396,"line":644},9,[394,646,647],{"class":400},"    }\n",[394,649,651],{"class":396,"line":650},10,[394,652,653],{"class":400},"  ],\n",[394,655,657,660,662],{"class":396,"line":656},11,[394,658,659],{"class":407},"  \"responseAggregationType\"",[394,661,411],{"class":400},[394,663,664],{"class":414},"\"byPage\"\n",[394,666,668],{"class":396,"line":667},12,[394,669,452],{"class":400},[12,671,672,675,676,678,679,682,683,686,687,690,691],{},[38,673,674],{},"keys"," follows the order of your ",[38,677,64],{},". ",[38,680,681],{},"ctr"," is a fraction, so 0.032 is 3.2 %. ",[38,684,685],{},"responseAggregationType"," tells you how the row was aggregated: because the request grouped by page, the API aggregated by page, and it will refuse ",[38,688,689],{},"byProperty"," for any request that groups or filters by page. ",[24,692],{"n":91},[371,694,696],{"id":695},"_3-page-until-the-rows-run-out","3. Page until the rows run out",[12,698,699,700,703,704,707,708,710,711,713,714],{},"Re-send the same body with ",[38,701,702],{},"startRow: 25000",", then ",[38,705,706],{},"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. ",[24,709],{"n":150}," If a page comes back with fewer rows than ",[38,712,190],{},", you already have everything. ",[24,715],{"n":383},[371,717,719],{"id":718},"_4-repeat-per-search-type","4. Repeat per search type",[12,721,722,723,725,726,47,728,363,730,732,733],{},"Each ",[38,724,97],{}," is a separate request. Run the same loop with ",[38,727,105],{},[38,729,108],{},[38,731,119],{}," if those matter for the site. ",[24,734],{"n":150},[12,736,737,738,741,742,744,745,747,748,751,752,755,756],{},"Filters go in ",[38,739,740],{},"dimensionFilterGroups",". To restrict step 2 to one directory, add a filter on ",[38,743,71],{}," with the ",[38,746,126],{}," operator, or ",[38,749,750],{},"includingRegex"," for anything more precise. Only the ",[38,753,754],{},"and"," group type is supported. ",[24,757],{"n":91},[16,759,761],{"id":760},"why-api-totals-differ-from-the-performance-report","Why API totals differ from the Performance report",[12,763,764,765,768,769],{},"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. ",[24,766],{"n":767},"7"," 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. ",[24,770],{"n":771},"8",[12,773,774,775,777,778,195,780],{},"The API behaves the same way. A request with ",[38,776,71],{}," 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. ",[24,779],{"n":91},[24,781],{"n":771},[12,783,784,785,787,788,790,791],{},"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. ",[24,786],{"n":767}," Your API rows grouped by ",[38,789,68],{}," 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. ",[24,792],{"n":793},"15",[12,795,796,797],{},"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. ",[24,798],{"n":767},[12,800,801,802,804,805,807,808,812],{},"Practical rule: for totals you can reconcile with the chart, send one request with no ",[38,803,71],{}," and no ",[38,806,68],{}," dimension. For detail, accept that the rows will not sum, and compare like with like. If you report this data to clients, the ",[43,809,811],{"href":810},"\u002Fblog\u002Fseo-reporting-search-console-metrics-clients","Search Console metrics for client reporting post"," covers how to present the gap.",[16,814,816],{"id":815},"api-vs-bulk-export-vs-the-ui-which-to-use","API vs bulk export vs the UI: which to use",[159,818,819,834],{},[162,820,821],{},[165,822,823,825,828,831],{},[168,824],{},[168,826,827],{},"Performance report (UI)",[168,829,830],{},"Search Analytics API",[168,832,833],{},"Bulk data export",[178,835,836,859,877,900,918],{},[165,837,838,841,846,853],{},[183,839,840],{},"Rows",[183,842,843,844],{},"1,000 per table ",[24,845],{"n":328},[183,847,848,849,195,851],{},"25,000 per request, 50,000 a day per search type with page or query ",[24,850],{"n":91},[24,852],{"n":150},[183,854,855,856],{},"All performance data Google has for the property, except anonymized queries ",[24,857],{"n":858},"16",[165,860,861,863,867,871],{},[183,862,258],{},[183,864,261,865],{},[24,866],{"n":264},[183,868,261,869],{},[24,870],{"n":264},[183,872,873,874],{},"From the day you set it up; no backfill ",[24,875],{"n":876},"10",[165,878,879,882,887,890],{},[183,880,881],{},"Anonymized queries",[183,883,884,885],{},"Omitted from the query table, in chart totals ",[24,886],{"n":767},[183,888,889],{},"Omitted from query rows",[183,891,892,893,896,897],{},"Flagged with ",[38,894,895],{},"is_anonymized_query",", query text blank ",[24,898],{"n":899},"9",[165,901,902,905,908,913],{},[183,903,904],{},"Cost",[183,906,907],{},"None stated",[183,909,910,911],{},"Quotas, no price stated ",[24,912],{"n":224},[183,914,915,916],{},"BigQuery storage and query charges above the free level ",[24,917],{"n":876},[165,919,920,923,926,929],{},[183,921,922],{},"Setup",[183,924,925],{},"None",[183,927,928],{},"Cloud project, OAuth, code",[183,930,931,932],{},"Cloud project with billing, BigQuery, service account roles ",[24,933],{"n":876},[12,935,936,937],{},"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. ",[24,938],{"n":876},[12,940,941,942,946],{},"Keylogs sits on the API side of that table. The ",[43,943,945],{"href":944},"\u002Fseo-low-hanging-fruit-finder","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.",[16,948,950],{"id":949},"the-url-inspection-api-quota-and-the-fields-it-returns","The URL Inspection API: quota and the fields it returns",[12,952,953,955,956,959,960,47,963,965,966,969,970],{},[38,954,143],{}," is a POST to ",[38,957,958],{},"https:\u002F\u002Fsearchconsole.googleapis.com\u002Fv1\u002FurlInspection\u002Findex:inspect"," with three fields: ",[38,961,962],{},"inspectionUrl",[38,964,354],{}," and an optional ",[38,967,968],{},"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. ",[24,971],{"n":972},"4",[12,974,975,976,978],{},"The quota is per site: 2,000 calls a day and 600 a minute, with a much larger per-project ceiling. ",[24,977],{"n":224}," That is enough to check a few thousand URLs overnight, not enough to audit a large site daily.",[12,980,981,982,411,985],{},"The useful part of the response is ",[38,983,984],{},"indexStatusResult",[24,986],{"n":987},"5",[159,989,990,1000],{},[162,991,992],{},[165,993,994,997],{},[168,995,996],{},"Field",[168,998,999],{},"What it tells you",[178,1001,1002,1023,1033,1054,1069,1094,1111,1121,1136],{},[165,1003,1004,1009],{},[183,1005,1006],{},[38,1007,1008],{},"verdict",[183,1010,1011,1014,1015,1018,1019,1022],{},[38,1012,1013],{},"PASS"," is \"Valid\" in the UI, ",[38,1016,1017],{},"FAIL"," is \"Error\", ",[38,1020,1021],{},"NEUTRAL"," is \"Excluded\"",[165,1024,1025,1030],{},[183,1026,1027],{},[38,1028,1029],{},"coverageState",[183,1031,1032],{},"The same status text as the Page indexing report",[165,1034,1035,1040],{},[183,1036,1037],{},[38,1038,1039],{},"indexingState",[183,1041,1042,1045,1046,1049,1050,1053],{},[38,1043,1044],{},"INDEXING_ALLOWED",", or blocked by a ",[38,1047,1048],{},"noindex"," meta tag or ",[38,1051,1052],{},"X-Robots-Tag"," header",[165,1055,1056,1061],{},[183,1057,1058],{},[38,1059,1060],{},"robotsTxtState",[183,1062,1063,363,1066],{},[38,1064,1065],{},"ALLOWED",[38,1067,1068],{},"DISALLOWED",[165,1070,1071,1076],{},[183,1072,1073],{},[38,1074,1075],{},"pageFetchState",[183,1077,1078,47,1081,47,1084,47,1087,47,1090,1093],{},[38,1079,1080],{},"SUCCESSFUL",[38,1082,1083],{},"SOFT_404",[38,1085,1086],{},"NOT_FOUND",[38,1088,1089],{},"SERVER_ERROR",[38,1091,1092],{},"REDIRECT_ERROR"," and others",[165,1095,1096,1105],{},[183,1097,1098,1101,1102],{},[38,1099,1100],{},"googleCanonical"," \u002F ",[38,1103,1104],{},"userCanonical",[183,1106,1107,1108,1110],{},"The canonical Google selected versus the one you declared; ",[38,1109,1100],{}," is absent when the page is not indexed",[165,1112,1113,1118],{},[183,1114,1115],{},[38,1116,1117],{},"lastCrawlTime",[183,1119,1120],{},"Last successful crawl by the primary crawler, absent if never crawled",[165,1122,1123,1128],{},[183,1124,1125],{},[38,1126,1127],{},"crawledAs",[183,1129,1130,363,1133],{},[38,1131,1132],{},"DESKTOP",[38,1134,1135],{},"MOBILE",[165,1137,1138,1146],{},[183,1139,1140,1101,1143],{},[38,1141,1142],{},"referringUrls",[38,1144,1145],{},"sitemap",[183,1147,1148],{},"Known inbound links and sitemaps listing the URL",[12,1150,1151,1152,1154,1155,1157,1158,1162,1163,84,1165,1167,1168,1172],{},"The pair worth scripting is ",[38,1153,1100],{}," against ",[38,1156,1104],{},". When they disagree across many URLs you have a canonical problem, and the ",[43,1159,1161],{"href":1160},"\u002Fblog\u002Fgoogle-chooses-different-canonical-urls","post on Google choosing different canonical URLs"," walks through the causes. For a traffic drop, pulling ",[38,1164,1029],{},[38,1166,1117],{}," for your top pages is the fastest way to rule out indexing before you start on the ",[43,1169,1171],{"href":1170},"\u002Fblog\u002Forganic-traffic-drop-search-console-checklist","traffic drop checklist",".",[12,1174,1175,1176,1179,1180],{},"The response also carries a link back to the UI (",[38,1177,1178],{},"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. ",[24,1181],{"n":987},[16,1183,1185],{"id":1184},"what-to-do-next-in-search-console","What to do next in Search Console",[12,1187,1188,1189,1191],{},"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 ",[38,1190,101],{},", 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.",[1193,1194,1195],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":390,"searchDepth":421,"depth":421,"links":1197},[1198,1199,1200,1206,1207,1208,1209],{"id":18,"depth":404,"text":19},{"id":153,"depth":404,"text":154},{"id":343,"depth":404,"text":344,"children":1201},[1202,1203,1204,1205],{"id":373,"depth":421,"text":374},{"id":458,"depth":421,"text":459},{"id":695,"depth":421,"text":696},{"id":718,"depth":421,"text":719},{"id":760,"depth":404,"text":761},{"id":815,"depth":404,"text":816},{"id":949,"depth":404,"text":950},{"id":1184,"depth":404,"text":1185},null,"lhf","2026-11-06","What the Search Analytics and URL Inspection endpoints return, the row and quota limits Google publishes, and one worked request you can copy.",false,"md",[1217,1220,1223,1226,1229],{"q":1218,"a":1219},"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.",{"q":1221,"a":1222},"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.",{"q":1224,"a":1225},"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.",{"q":1227,"a":1228},"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.",{"q":1230,"a":1231},"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.","\u002Fimg\u002Fblog\u002Fgoogle-search-console-api.png",{},"What the Google Search Console API returns, the 25,000-row and 50,000-rows-a-day limits, URL Inspection quotas, and a worked Search Analytics request.","Google Search Console API: Data, Limits, Worked Query",true,"\u002Fblog\u002Fgoogle-search-console-api",{"title":6,"description":1213},{"loc":1237},[1241,1246,1249,1252,1255,1258,1262,1265,1268,1271,1274,1278,1282,1285,1288,1291],{"publisher":1242,"name":1243,"url":1244,"accessed":1245},"Google Search Console API","Method: searchanalytics.query","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Fv1\u002Fsearchanalytics\u002Fquery","2026-11-05",{"publisher":1242,"name":1247,"url":1248,"accessed":1245},"Getting your performance data","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Fv1\u002Fhow-tos\u002Fall-your-data",{"publisher":1242,"name":1250,"url":1251,"accessed":1245},"Usage Limits","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Flimits",{"publisher":1242,"name":1253,"url":1254,"accessed":1245},"Method: index.inspect","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Fv1\u002FurlInspection.index\u002Finspect",{"publisher":1242,"name":1256,"url":1257,"accessed":1245},"UrlInspectionResult","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Fv1\u002FurlInspection.index\u002FUrlInspectionResult",{"publisher":1259,"name":1260,"url":1261,"accessed":1245},"Google Search Console Help","About Search Console data","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F96568",{"publisher":1259,"name":1263,"url":1264,"accessed":1245},"Performance report (Search results): Dimensions and data groupings","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F17011259",{"publisher":1259,"name":1266,"url":1267,"accessed":1245},"Performance report (Search results): About the data","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F17011364",{"publisher":1259,"name":1269,"url":1270,"accessed":1245},"Table guidelines and reference (bulk data export)","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F12917991",{"publisher":1259,"name":1272,"url":1273,"accessed":1245},"Start a new bulk data export","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F12917675",{"publisher":1275,"name":1276,"url":1277,"accessed":1245},"Google Analytics Help","[GA4] Queries report","https:\u002F\u002Fsupport.google.com\u002Fanalytics\u002Fanswer\u002F13682862",{"publisher":1279,"name":1280,"url":1281,"accessed":1245},"Google Search Central Blog","Fresher data in your site's Search Performance report","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fblog\u002F2019\u002F09\u002Fsearch-performance-fresh-data",{"publisher":1242,"name":1283,"url":1284,"accessed":1245},"Overview","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Fabout",{"publisher":1242,"name":1286,"url":1287,"accessed":1245},"Query your Google Search analytics data","https:\u002F\u002Fdevelopers.google.com\u002Fwebmaster-tools\u002Fv1\u002Fhow-tos\u002Fsearch_analytics",{"publisher":1259,"name":1289,"url":1290,"accessed":1245},"Performance report (Search results): Troubleshooting data discrepancies","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F17010575",{"publisher":1259,"name":1292,"url":1293,"accessed":1245},"About bulk data export of Search Console data to BigQuery","https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F12918484","blog\u002Fgoogle-search-console-api","t7rRBuTIhkYW5jPl9JWNf1vjb0YGboKO-YsZks8FVvU","posts",[1298,1299,1302,1304,1307,1311,1315,1318,1321,1325,1329,1333,1337,1340,1344,1348,1352,1356,1360,1364,1368,1372,1375,1378,1382,1385,1389,1393,1397],{"path":1237,"title":6,"date":1212},{"path":1300,"title":1301,"date":1212},"\u002Fblog\u002Fkeep-search-console-data-beyond-16-months","How to Keep Search Console Data Beyond 16 Months",{"path":1160,"title":1303,"date":1245},"Why Does Google Choose Different Canonical URLs?",{"path":1305,"title":1306,"date":1245},"\u002Fblog\u002Frequest-indexing-google-search-console","How to Request Indexing in Google Search Console (and When It Helps)",{"path":1308,"title":1309,"date":1310},"\u002Fblog\u002Ftitle-tag-generator","Title Tag Generator","2026-11-04",{"path":1312,"title":1313,"date":1314},"\u002Fblog\u002Fwhy-google-rewrites-meta-descriptions-copy-fixes","Why Google Rewrites Meta Descriptions: Copy Fixes","2026-10-24",{"path":284,"title":1316,"date":1317},"Anonymized Queries vs. Search Console Row Limits","2026-10-23",{"path":810,"title":1319,"date":1320},"SEO Reporting: 7 Search Console Metrics for Clients","2026-10-21",{"path":1322,"title":1323,"date":1324},"\u002Fblog\u002Finternal-linking-support-underperforming-pages","Internal Linking: How to Support Underperforming Pages","2026-10-20",{"path":1326,"title":1327,"date":1328},"\u002Fblog\u002Fprioritize-seo-fixes-potential-traffic-gain","How to Prioritize SEO Fixes by Potential Traffic Gain","2026-10-19",{"path":1330,"title":1331,"date":1332},"\u002Fblog\u002Flow-ctr-find-improve-pages-losing-clicks","Low CTR: How to Find and Improve Pages Losing Clicks","2026-10-18",{"path":1334,"title":1335,"date":1336},"\u002Fblog\u002Fcontent-refresh-find-pages-worth-updating","Content Refresh: How to Find Pages Worth Updating","2026-10-17",{"path":1170,"title":1338,"date":1339},"Organic Traffic Drop: A Search Console Checklist","2026-10-16",{"path":1341,"title":1342,"date":1343},"\u002Fblog\u002Fmerge-or-redirect-competing-seo-pages","Merge or Redirect: How to Handle Competing SEO Pages","2026-10-14",{"path":1345,"title":1346,"date":1347},"\u002Fblog\u002Fkeyword-mapping-prevent-cannibalization","What Is Keyword Mapping? (and How It Prevents Cannibalization)","2026-08-08",{"path":1349,"title":1350,"date":1351},"\u002Fblog\u002Fkeyword-cannibalization-examples","7 Real Keyword Cannibalization Examples (and the Fix)","2026-08-05",{"path":1353,"title":1354,"date":1355},"\u002Fblog\u002Flow-hanging-fruit-seo","Low-Hanging Fruit SEO: What It Is and How to Win It","2026-08-01",{"path":1357,"title":1358,"date":1359},"\u002Fblog\u002Fstriking-distance-keywords","Striking Distance Keywords: Find & Rank the Page-2 Wins","2026-07-29",{"path":1361,"title":1362,"date":1363},"\u002Fblog\u002Fbest-keyword-cannibalization-tools","Best Keyword Cannibalization Tools (2026 Comparison)","2026-07-25",{"path":1365,"title":1366,"date":1367},"\u002Fblog\u002Fhow-to-avoid-keyword-cannibalization","How to Avoid & Prevent Keyword Cannibalization","2026-07-22",{"path":1369,"title":1370,"date":1371},"\u002Fblog\u002Fwhat-is-keyword-cannibalization","What Is Keyword Cannibalization (and When It's Actually Fine)","2026-07-16",{"path":1373,"title":1374,"date":1371},"\u002Fblog\u002Fhow-to-check-keyword-cannibalization","How to Check for Keyword Cannibalization: A Free Audit",{"path":1376,"title":1377,"date":1371},"\u002Fblog\u002Fkeyword-cannibalization-ahrefs-semrush","How to Check Keyword Cannibalization in Ahrefs & Semrush (and the Faster Way)",{"path":1379,"title":1380,"date":1381},"\u002Fblog\u002Fhow-to-find-low-hanging-fruit-keywords","How to Find Low-Hanging Fruit Keywords","2026-07-14",{"path":1383,"title":1384,"date":1381},"\u002Fblog\u002Finternal-keyword-cannibalization","Internal Keyword Cannibalization — How to Spot Your Pages Competing With Each Other",{"path":1386,"title":1387,"date":1388},"\u002Fblog\u002Fanalyze-seo-performance-with-google-search-console","How to Analyze Your SEO Performance in Google Search Console","2018-04-08",{"path":1390,"title":1391,"date":1392},"\u002Fblog\u002Fhow-to-find-and-fix-keyword-cannibalization","How to Fix Keyword Cannibalization (5 Fixes + a Decision Table)","2018-01-24",{"path":1394,"title":1395,"date":1396},"\u002Fblog\u002Fhow-to-easily-find-quick-wins-to-boost-your-traffic","SEO Quick Wins: The 15-Minute Search Console Playbook","2018-01-23",{"path":1398,"title":1399,"date":1396},"\u002Fblog\u002Fhow-to-identify-your-top-performers-with-keylogs","How to Identify Your Top-Performing Pages (80\u002F20) in Search Console"]