Blog/Search & RAG
11 min read

Google Search URL Parameters: What Still Works in 2026

Google silently killed num in September 2025. Here is the current list, which ones are official, and which are community guesses you should not depend on.

Google Search URL Parameters: What Still Works in 2026

Copy this line to your agent to fetch a SERP with the parameters recorded alongside the results.

set up https://monid.ai/SKILL.md and use api.strale.io /x402/google-search and keep the search_parameters it returns

In September 2025 Google silently stopped honouring num, the parameter that asked for a hundred results on one page. Nothing was announced, nothing errored, and a great many rank trackers and scrapers carried on requesting a hundred and quietly receiving ten. That is the shape of every risk on this page: search URL parameters are mostly conventions rather than a contract, and the failure mode is a wrong answer rather than an error. Here is the current list, which ones are safe, and how to notice the next time one moves, running through Monid, the OpenRouter for agent tools.

What are Google search URL parameters?

Key and value pairs appended to a Google results URL that change what comes back. q is the query itself; the rest control country, language, pagination, time window, display mode and filtering.

Why anyone cares

Three audiences, and they want different things from the same list. SEO people use them to check what a result looks like in another country without a VPN. Developers building any kind of search integration use them because the parameters are the API surface when there is no API. And anyone running a rank tracker depends on them absolutely, because a position measured under different parameters is not comparable to yesterday's.

The thing to understand before the list

Google publishes very little of this. A few parameters are documented; most are conventions that have worked for years and are described by third parties who reverse-engineered them. That distinction has no practical effect right up until the moment it does, which is what happened last September.

So read the list below as two lists: things Google acknowledges, and things that currently work. Both are useful. Only one is a commitment.

📖 See also Rank Tracking API: The Hard Part Is Not the Fetch

Why did num stop working?

Because it was never officially supported, and in September 2025 Google stopped honouring it without announcing anything.

What happened

Between 12 and 14 September 2025, num stopped having any effect. Requests for a hundred results returned ten. A Google spokesperson subsequently confirmed the parameter had never been formally supported, which is technically accurate and was not much comfort to anybody who had built on it. The clearest write-up of the change and the current parameter set is Bright Data's reference.

Why it hurt more than it looks

A rank tracker checking the top hundred was, from that week, checking the top ten and reporting nothing beyond it. There was no error to alert on: the request succeeded, the response was well formed, and the result set was simply shorter. Any keyword ranking between eleven and one hundred appeared to have vanished.

That is the second time this pattern has come up in a fortnight on this blog. It is the same failure shape as a crawl returning HTTP 200 with an empty body, which we hit and reported in the Crawl4AI guide, and the same defence applies: assert on the content you got rather than on the status of the request.

What replaced it

start, which sets the offset in increments of ten. start=0 is results one to ten, start=10 is eleven to twenty. Getting a hundred results now means ten requests rather than one, which is a tenfold change in the cost of any deep rank check and is the practical consequence most people are still absorbing.

Documented vs reverse-engineered: what actually differs

AspectDocumented parametersCommunity-mapped parameters
Where the spec livesGoogle's own docsBlog posts and testing
Notice before a changeSomeNone
Failure mode when it movesAn error, usuallyA quietly different answer
Safe to build a product onYesWith a monitor
Examplesq, hl, safeudm, tbs values, previously num

The right posture is not to avoid the second column. It is to know which column each parameter is in, and to alert on result shape rather than on request success.

Which parameters can you actually depend on?

Here is the current working set, checked against published references on 2026-08-27.

Query and pagination

q is the query. start is the result offset in multiples of ten, and it is now the only way to page. num is dead: it is ignored and Google returns ten results per page regardless of what you pass.

Geography and language, which are four parameters not two

This is where most mistakes live, because two pairs look interchangeable and are not.

gl sets the country you appear to be searching from, using an ISO 3166-1 alpha-2 code such as gl=us or gl=gb. It changes which results are considered locally relevant.

cr restricts results to pages hosted in a given country. That is a filter on the documents, not on the searcher.

hl sets the interface and query-interpretation language, taking codes like hl=en or fuller tags like hl=en-gb.

lr restricts results to content in a language, written with a prefix as in lr=lang_en.

So gl and hl describe the searcher; cr and lr describe the documents. Setting gl=de gives you what a German searcher sees, including English pages. Setting lr=lang_de gives you German-language pages regardless of who is asking. Conflating them produces a result set that looks plausible and answers a different question.

Display mode

udm selects the display mode and is the most interesting parameter of the last two years. udm=14 is the classic web results view without AI features, which is why it became widely shared. udm=39 is short videos and udm=50 is AI Mode. These values are community-mapped rather than documented, so treat them as the second column of the table above.

Time and filtering

tbs carries time-based filters and a few other switches: tbs=qdr:d is the past day, qdr:w the past week, qdr:m the past month, and tbs=sbd:1 sorts by date rather than relevance. safe takes active or off for SafeSearch. filter controls duplicate clustering, where filter=0 shows everything and the default filter=1 groups similar pages from one site.

The one-line summary

q and start for the query and the page, gl and hl for who is asking, cr and lr for what language the documents are in, tbs for time, udm for the view, filter=0 when you need the unclustered list. And num for nothing at all.

How do you keep parameters from silently drifting?

Three steps, and the third is the one that would have caught the num change.

For agents

Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:

set up https://monid.ai/SKILL.md

It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.

For humans

npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main

Step 1. Use an endpoint that echoes the parameters back

What it does. Turns your assumption about what you asked for into a recorded fact.

The endpoints. api.strale.io/x402/google-search returns a search_parameters object alongside the results.

The call.

monid run -p api.strale.io -e /x402/google-search -w \
  --query '{"query": "best web scraping api", "country": "us"}'

What comes back. From that run on 2026-08-27: a results array with position, title, url, snippet, date and sitelinks, plus result_count, the knowledge_graph, answer_box and people_also_ask slots, a search_parameters object, and a _meta block naming the upstream and the fetch time.

What it costs. Cents per call, billed per call regardless of how many results come back. Current figures at monid.ai/tools.

Step 2. Store the parameters with the row

What it does. Makes a year-old measurement defensible.

The call. A schema decision, not an endpoint:

row = {"keyword": kw, "position": pos, "checked_at": now_utc(),
       "params": res["search_parameters"],
       "result_count": res["result_count"]}

What comes back. The ability to prove Monday and Thursday were comparable. Without it, a position that moved is indistinguishable from a parameter that moved.

Step 3. Alert on result count, not on errors

What it does. Catches the next num.

The call. One condition:

if res["result_count"] < EXPECTED_MIN:
    alert(f"{kw}: got {res['result_count']} results, expected {EXPECTED_MIN}")

What comes back. A page. In September 2025 this single check would have fired on the first run after the change, on every keyword, instead of six weeks of quietly truncated data. It costs nothing and it is the only defence against a parameter that stops working rather than starts failing.

📖 See also Automate SERP Tracking with a Structured Google Search API

Give this to your agent

$Set up https://monid.ai/SKILL.md, and then use Monid to check these 15 keywords in the US with English interface, store the search parameters the response echoes back, and alert me if any run returns fewer than 10 organic results.

Which endpoint should I use for which job?

EndpointWhat it doesInputOutputBest forBilling
api.strale.io/x402/google-searchNumbered SERP with the parameters echoedQuery, countryposition, feature slots, search_parametersRank checks and SERP featuresPer call
context.dev/web/searchIndex results with a relevance bandQuery, freshness, domain filtersURL, title, description, relevanceRetrieval, not rankingPer result
api.strale.io/x402/keyword-suggestAutocomplete expansionA seed keywordQuestions, comparisons, long tailDeciding what to trackPer call
context.dev/web/scrape/markdownReads a result that movedA URLMarkdown, headings, JSON-LDInvestigating a changePer call

Every row was verified with monid inspect on 2026-08-27. The table gives billing shape rather than figures; shape drives design and current numbers live on monid.ai/tools.

The num change has a direct cost consequence here worth stating. Because pagination is now ten at a time, a top-hundred check is ten calls rather than one, so deep rank tracking got roughly ten times more expensive across the whole category in one week. That is an argument for tracking fewer keywords deeply rather than many keywords shallowly, and it is a budget conversation most teams have not yet had.

When should you not build on URL parameters?

Three cases.

Bing is a different question entirely. Microsoft retired its Search API, so the parameter set above does not transfer and the replacement landscape is its own decision, covered in Bing Search API Retired: What Actually Replaces It.

You have an official API for the thing you want. If the data is available through a documented interface, use it. Search Console gives you your own site's positions, free and first-party, with none of this fragility. It only covers properties you verify, which is exactly why the rest of this page exists.

You need a guarantee. Nothing on this page is a contract. Most of it is convention, one part of it is officially disowned, and the num episode is the proof that "it has worked for years" is not a commitment. If a broken field is a customer incident, buy from somebody who takes that risk on your behalf and tells you when it moves.

You are only doing it once. For a one-off check, open the browser. Building a parameter-handling layer for a question you will ask twice is the same over-engineering as building a scraper for a hundred rows.

There is also a case for the specialists this page has been implicitly comparing itself to. Bright Data and SerpApi both maintain public references on exactly this subject and keep them current, which is real work and worth reading. We linked one above for that reason rather than despite it.

And the disclosure: this is Monid's blog and we sell per-call access to tools, so the case we argue best is the one where you want the SERP without maintaining the parameter layer yourself. If you enjoy maintaining it, the list above is free and so is the browser.

Conclusion

Google search URL parameters are a working convention rather than a documented interface, and September 2025 is the proof: num stopped functioning with no announcement, no error and no visible failure, and the systems built on it kept reporting confidently wrong numbers. The current safe set is small, q and start for the query and page, gl and hl for the searcher, cr and lr for the documents, tbs for time, udm for the view.

The general lesson is worth more than the list, and it is the same one that keeps surfacing in this category: the dangerous failures here do not throw. A truncated result set, an empty page body, a missing field read as zero. Assert on the shape of what came back rather than on the success of the request, and alert on a count rather than an exception. That single habit would have caught the change that broke this category, on day one, for free.

Free next step: run monid inspect -p api.strale.io -e /x402/google-search and read what the response carries. It is free, and seeing search_parameters in the schema is the fastest way to understand why storing them matters. Start at monid.ai.

FAQ

What does udm=14 do?

It selects the classic web results view without the AI features layered on top, which is why it circulated so widely after AI Overviews rolled out. It is a display-mode value that the developer community mapped rather than one Google documents, so treat it as something that currently works rather than something guaranteed to keep working. If your pipeline depends on it, add a check that the response still looks like a plain results list rather than assuming the parameter took effect.

What is the difference between gl and cr?

gl sets the country you appear to be searching from, so it changes which results Google considers locally relevant to you. cr restricts results to pages hosted in a given country, which is a filter on the documents rather than on the searcher. They produce different result sets and mixing them up is the most common source of rank data that looks plausible and is measuring the wrong thing. The same distinction exists on the language side between hl and lr.

Can you still get 100 Google results in one request?

No. num has been ignored since September 2025 and Google returns ten results per page regardless of what you pass. Pagination is now start in increments of ten, so a top-hundred check is ten requests. The practical consequence is that deep rank tracking is roughly ten times the request volume it was, which is worth rebudgeting for rather than discovering at the end of a month.

How do the tbs time filters work?

tbs=qdr:d is the past day, qdr:w the past week, qdr:m the past month and qdr:y the past year, and tbs=sbd:1 sorts by date instead of relevance. The syntax is compact and easy to get subtly wrong, which is one reason search endpoints tend to expose a plain freshness enum instead; ours takes last_24_hours through last_year and does the translation for you. For news work specifically, the freshness window matters more than any other parameter, and that case is covered in Web Scraping News Articles.

Last updated August 2026.

google search url parametersserp apirank trackingudmsearch operators