Skip to main content
The /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.
Results from all pages are concatenated into 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.
If the proxy pool for that country is exhausted or unavailable, the response includes the country we actually fell back to in the 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+nyc performs differently from keyword=best%20pizza%20nyc%202026. Use spaces or +, not commas.
  • Watch totalResults for sanity. A totalResults of 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 on url.