Response Schema
ResultsPage, Suggestions, Place, App, Trends and the rest: every type the SERP API returns, field by field.
Each engine returns one shared set of types. A field means the same thing on every engine.
Optional fields are genuinely optional: absent means the page did not say. A missing rating means no stars
were shown; it does not mean zero stars. Times are ISO 8601 in UTC. Every object may carry ext, which holds
facts only that engine has, under the engine's own names.
| Operation | Returns |
|---|---|
search | ResultsPage (app stores: AppsPage) |
suggestions | Suggestions |
places · place · reviews | PlacesPage · Place · PlaceReviewsPage |
app · reviews (app stores) | App · AppReviewsPage |
explore · trending (Google Trends) | TrendsExplore · TrendingPage |
Google Shopping returns the marketplace types SearchResult, Product and ReviewPage, described in the
Marketplace Response Schema.
ResultsPage
One results page, holding every block in the order the page showed it.
| Field | Type | Notes |
|---|---|---|
engine | string | google bing yahoo duckduckgo yandex baidu naver yahoo-japan seznam daum sogou |
query | string | the query as asked; for a reverse-image search, what the engine named the image |
type | string | web news images videos image |
outcome | string | results, or noResults when the engine said it found nothing. A blocked or unreadable page is an error, never noResults |
country lang device timeRange safe | string? | the inputs that framed the search, echoed back |
image | string? | the image a reverse-image search ran on |
correctedQuery | string? | what the engine actually searched, when it rewrote the query ("Showing results for …") |
totalResults | integer? | only when the page states it ("About 1,230,000 results") |
page | integer | 1 for the first page |
items | Item[] | every block, in page order. See below |
cursor | string? | the next page. Pass it alone as cursor |
fetchedAt | string | when the page was read |
Every item has type, rank (its 1-based place among all items on the page) and ext. The rest depends on
type:
type | Fields |
|---|---|
organic | position (among organic results only, counting on across pages), url, title, snippet?, site?, displayUrl?, date?, sitelinks?, thumbnail?, image?, imageWidth?, imageHeight?, images?, durationSec?, lang?, favicon?, badges?, facts?, rating?, ratingScale?, reviewCount? |
ad | block? (top bottom side), url, title, snippet?, advertiser?, displayUrl?, sitelinks?, thumbnail?, phone?, extensions?, favicon?, badges?, rating?, reviewCount?, promotion? |
news | url, title, snippet?, source?, sourceUrl?, sourceLogo?, date?, thumbnail?, favicon? |
image | imageUrl, thumbnail?, width?, height?, title?, url? (the page it is on), source?, date?, format?, favicon? |
video | url, title, snippet?, source?, channel?, channelUrl?, avatar?, date?, durationSec?, views?, viewsText?, thumbnail?, embedUrl?, preview?, favicon? |
topStories videoCarousel imagePack shopping twitter discussions | title?, items (the block's entries), sponsored?, moreUrl?, total? |
peopleAlsoAsk | title?, questions: {question, answer?, url?, title?}[] |
relatedSearches | title?, queries: string[] |
knowledgePanel | title, subtitle?, description?, source?, facts?, images?, website?, links? |
localPack | places: Place[], moreUrl?, total? |
aiOverview | answer: the Answer type of the AI Answers API, unchanged |
other | kind (the engine's own name for the block), title?, text?, links? |
sitelinks and links are {url, title?, snippet?}[]. facts are {label, value}[], kept in the order shown.
badges are the labels the page puts on a result, copied word for word. rating uses the page's own scale.
ratingScale gives the top of that scale when the page states it (8.1/10 → 10). A block the schema has no
shape for yet comes back as other. It is never dropped.
Suggestions
| Field | Type | Notes |
|---|---|---|
engine | string | |
query | string | what was typed |
country lang | string? | echoed when set |
suggestions | array | {text, type?}: the engine's suggestions, in its order. type is the engine's own kind (query, entity…) where it states one |
Place
A business or point of interest.
| Field | Type | Notes |
|---|---|---|
id | string | the engine's stable place id; pass it to place and reviews |
name | string | |
url | string? | the place's page on the engine |
address | object? | {full?, street?, city?, region?, postalCode?, country?} |
lotAddress | string? | Korea's lot-number address, shown beside the road address |
coordinates | object? | {lat, lng} |
categories | string[]? | |
rating reviewCount | number? | stars out of 5, and the count beside them |
priceLevel | string? | as shown: $$, ₩₩ |
phone website | string? | |
hours | array? | {day, hours}, one per day listed, times as shown |
status | string? | open closed temporarilyClosed permanentlyClosed |
statusText | string? | the open-now line as worded ("Closed · Opens 7 AM") |
photos | string[]? | the photos the page carried; photoCount is how many the place has in all |
attributes | array? | {group?, label, value?}: amenities, service options, payment |
description neighborhood logo | string? | |
verifiedOwner | boolean? | the owner claimed the listing |
reviewsUrl | string? | the page with the place's reviews |
lang | string? | echoed |
PlacesPage
| Field | Type | Notes |
|---|---|---|
engine query | string | |
outcome | string | results or noResults |
type | string? | maps (the map's list) or local (Google's local results) |
location near country lang | string? | echoed |
places | Place[] | |
page | object | {index, size, total?}. total appears only when the engine states a count |
cursor | string? | the next page |
fetchedAt | string |
PlaceReviewsPage
| Field | Type | Notes |
|---|---|---|
engine placeId | string | |
summary | object? | {average, count?, distribution?} |
starCounts | object? | star → number of reviews, as stated ({"5": 2409, …}) |
sort | string? | |
page | object | {index, size, total?} |
reviews | array | see below |
cursor | string? | |
fetchedAt | string |
A review has the same fields as a marketplace product review: id?, author?, authorAvatarUrl?, rating?,
title?, body?, date?, helpfulCount?, language?, images, reply? ({body, date?, author?}, the
owner's answer). Places add authorId?, authorUrl? and pinned?. A place review may have no stars
(Naver visitors often leave keywords instead), and then rating is absent, never 0.
AppsPage
The search result of Google Play and the App Store.
| Field | Type | Notes |
|---|---|---|
engine | string | google-play app-store |
query | string | |
outcome | string | results or noResults |
country lang | string? | echoed |
apps | array | each one an App as a list shows it, plus rank |
page | object | {index, size, total?} |
cursor | string? | |
fetchedAt | string |
App
| Field | Type | Notes |
|---|---|---|
id | string | Play's package name (com.strava), Apple's numeric id (426826309) |
name | string | |
url icon video | string? | |
developer | object? | {id?, name, url?, website?, email?, address?} |
summary | string? | the one line under the name |
description whatsNew | string? | |
screenshots | string[]? | |
categories | string[]? | the main one first |
rating | object? | {average, count?} |
starCounts | object? | star → number of ratings |
editorsChoice | boolean? | |
price | object? | {currency, amount}; a free app is amount: 0 |
inAppPurchases | boolean? | |
contentRating version requires | string? | as shown ("Teen", "12+", "Requires iOS 16.0 or later") |
releasedAt updatedAt | string? | |
country lang | string? | echoed |
related moreByDeveloper | App[]? | the apps the page lists beside it, as a list shows them (app only) |
privacyPolicyUrl | string? | app only |
chart | object? | {name, position}: the app's place in a store chart (app only) |
AppReviewsPage
| Field | Type | Notes |
|---|---|---|
engine appId | string | |
sort country lang | string? | echoed |
page | object | {index, size, total?} |
reviews | array | id?, author?, rating, title?, body?, date?, helpfulCount?, images, reply? (the developer's answer) |
cursor | string? | |
fetchedAt | string |
TrendsExplore
What Google Trends shows for up to five terms. Trends reports relative interest from 0 to 100, measured
against the busiest point of the request. A 0 is a value Trends stated, so it is returned as 0.
| Field | Type | Notes |
|---|---|---|
terms | string[] | as asked, in order |
country subregion timeRange category property lang | the inputs, echoed. No country means worldwide | |
interestOverTime | object? | {points, averages?}. A point is {date, values, partial?, noData?}, with one value per term |
interestByRegion | object? | {resolution?, measure?, regions}. A region is {code?, name, values, noData?, coordinates?}. measure is interest for one term; with several terms it is share, each term's share of the region's searches |
related | array? | {term, topics?, queries?}, each with top and rising lists of {title, kind?, id?, value?, growth?, growthValue?, url?} |
fetchedAt | string |
TrendingPage
What is trending now in a country.
| Field | Type | Notes |
|---|---|---|
country subregion window category lang | echoed | |
items | array | {rank, query, volume?, minVolume?, growth?, startedAt?, endedAt?, active?, categories?, related?, articles?} |
fetchedAt | string |
volume is the search count as shown (200K+) and minVolume its lower bound. articles are
{title, url, source?, date?, image?}; with include=articles, every article Trends holds for each trend is
returned.