/serpApi endpoint scrapes Google search results and returns normalized JSON. It handles the CAPTCHA gauntlet, ad rendering delays, and proxy rotation that make Google scraping painful.
Minimum request
Response shape
aiOverview
Google’s AI-written summary above the results, plus the hostnames it cites, or
null when the search does not have one. Whether Google generates an overview
depends on the query and the region, so treat this as an extra rather than a
guarantee - a commercial query usually has none, an informational one usually
does.
It is read from the page we already fetched and never waited for, so it costs
you no extra time. In rare cases where the overview is still being written when
the page is captured, the field is null.
topAds and bottomAds cover the paid units wherever Google puts them,
including the blocks it now renders inside the organic column. Anything paid is
in one of those two lists and never in organic.Useful parameters
pages_to_check
How many SERP pages to scrape, 1 to 10. Defaults to 1.
topAds, bottomAds, and organic with position reflecting cross-page ordering.
proxy_country
Two-letter ISO code forcing the request through that country’s IP pool. Affects what Google shows you - SERP composition varies by region.
proxy_country field.
wait_after_load
Extra seconds to wait before extraction, on top of the wait we already do.
You should not normally need it: extraction waits for the paid units to finish
arriving before reading the page, so ads are not missed because of timing. Reach
for this only when you have a specific reason to let a SERP settle longer - it
is added to your response time as-is.
captcha_pause
Seconds to pause if Google shows a CAPTCHA, giving an interactive user time to solve it. Only useful when running the API in attended mode. Leave at 0 for automated workloads - rely on proxy_country rotation instead.
Errors
A keyword Google genuinely has no results for is not an error: you get
200
with resultsCollected: 0 and an empty organic array. This is normal for narrow
site: queries, and it means you can trust an empty result set instead of retrying it.
Tips
- Phrase keywords like a user would.
keyword=best+pizza+nycperforms differently fromkeyword=best%20pizza%20nyc%202026. Use spaces or+, not commas. - Watch
totalResultsfor sanity. AtotalResultsof 0 with valid organic results means the count couldn’t be extracted - not that there are no results. - Cross-page dedup is your job. If you call with
pages_to_check=10, expect some overlap on borderline results. Dedup onurl.

