Google results (SERP)
https://api.crawl4ai.com/serpGoogle's results page as structured data: true ranks, every block Google showed, and the place the page was localised to. Built for rank tracking and SEO tools. Not the same as /search, which is Crawl4AI's own web search for reading results. In beta since 8 October 2026: the shape is settled, the service is new; it becomes stable in a few weeks. POST /serp takes the same fields as a JSON body.
beta · added 8 Oct 2026
Request
curl "https://api.crawl4ai.com/serp?q=best+crm+software&country=us" \ -H "Authorization: Bearer sk_live_..."
Query
qrequiredstring | The search query (max 512 chars). |
countrystring | Default usDefault |
languagestring | Default enDefault |
locationstring | Optional. A city or region, for example |
num10, 20, 30 … 100 | Default 10Default 10, any multiple of 10. Results per page: |
pageint | Default 1Default 1. Counts in steps of |
devicestring | Default desktopDefault |
timestring | Optional. |
fresh0 | 1 | Default 0Default 0. |
sourceauto | google | Default autoDefault |
enginestring | Default googleDefault |
typestring | Default organicDefault |
Response
Shortened, for q=car insurance quotes:
{ "search": { "q": "car insurance quotes", "engine": "google", "type": "organic", "country": "us", "language": "en", "location": null, "device": "desktop", "page": 1, "num": 10, "time": null }, "cached": false, "age_s": 0, "source": "gg", "pages": { "asked": 1, "got": 1, "missing": [] }, "blocks": [ "ai_overview", "organic", "people_also_ask", "related_searches" ], "total_results": 238000000, "results": [ { "position": 1, "position_absolute": 2, "title": "…", "url": "https://www.libertymutual.com/…", "domain": "libertymutual.com", "displayed_url": "https://www.libertymutual.com › auto-insurance › state", "snippet": "…" }, … ], "ai_overview": { "text": "You can compare rates…", "sources": [ { "title": "The Zebra", "url": "https://…" } ] }, "people_also_ask": [ "…", "…", "…", "…" ], "related_searches": [ "…" ], "ms": 1240 }
The top-level keys:
searchobject | The settings the page was fetched with: |
resultsarray | The organic results, in Google's order (below). No results is a |
blocksarray | The names of the blocks that were on the page, in page order. |
total_resultsint | Google's own estimate, as printed on the page ("About 116 results"). With a place attached it is often a small number. Absent when Google did not show one. |
sourcegg | gs | mixed | Where the pages came from: |
empty_reasonstring | Only when |
cachedbool |
|
pagesobject |
|
msint | The time the answer took, in milliseconds. |
Each result:
positionint | The rank among the organic results only, from 1. |
position_absoluteint | The rank among every block on the page, in page order: an ad, an AI Overview or a places block each take a number too. |
titlestring | The result's title. |
urlstring | The page itself, not a redirect. |
domainstring | The host of |
displayed_urlstring | The address Google prints under the title, with its |
snippetstring | The text Google shows, without the date at its start. |
datestring | Optional. The date Google shows, as shown ( |
sitelinksarray | Optional. The small links under the result: |
The blocks
A block Google did not show is absent, never null. Each block's key and its item fields:
| Key | Fields |
|---|---|
ai_overview |
{text, sources: [{title, url}]} |
people_also_ask |
a list of questions (strings) |
related_searches |
a list of searches (strings) |
knowledge_panel |
{title, subtitle, description, facts: [{k, v}]} |
top_stories |
[{title, url}] |
local_pack |
[{position, name, rating, reviews_count, address}] |
ads_top · ads_bottom |
[{position_absolute, title, url, displayed_url, snippet}] |
short_videos |
[{title, url, source, duration}] |
images |
[{title, url, source}]; url is the page the image is on |
latest_from_site |
[{title, url, date}]; latest_from_site_domain names the site |
perspectives |
[{title, url, source, author, date}] |
apps |
[{title, url, store}] |
blocks can also name videos and discussions: they were on the page and take a number in position_absolute, but they have no list of their own. A block can be named in blocks with no list when we could not read its links.
Depth and paging
For exact ranks past the first 10, ask a bigger num: its Google pages are fetched at the same time, and position runs on across them. With page above 1, numbers start at (page-1)×num+1; this is an estimate, because a Google page holds 8 to 10 organic results. If a later page fails, the answer is still a 200 with the pages we got, and pages.missing names the failed ones.
Credits and errors
1 credit per Google page fetched live; a page from our cache costs half. The x-c4-cost header carries the real cost of the call. A failed first page or a blocked fetch is a 5xx and is not charged. A bad setting answers 400 with the reason in error.
Run this call in the playground and see the real answer, the time and the units.
Next
Crawl4AI's own web search: results ranked and cleaned for reading.
Answer a questionGET /answerAsk a question, get a direct answer.
Something unclear or wrong on this page? Tell us.