Google Maps Scraper API
This cluster covers the Google Maps workflow end to end. Business Search takes a free-text query, optionally centred on a latitude and longitude, and returns each matching place with its name, address, coordinates, category, rating, review count, opening hours, website and phone, plus the place id and feature id you can pass straight into Place Details. Place Details resolves one place by that id — or by a CID, a feature id, or a pasted Google Maps link — into the same full record. Reviews reads the review feed for a place: rating, full text, author, photos, timestamp and the owner’s reply, sorted by relevance, date or rating, with cursor pagination through the whole set. Every one of them is a pure HTTP call over upAPI’s own request path — no browser is launched, so there is nothing to solve a CAPTCHA on and no per-request compute cost to pass through. Each response is cached for a while after the first call, so a repeat lookup inside that window is free and instant; the exact time-to-live is on this page’s FAQ, generated from the same catalog the calls run against. Every field on this page is read directly from the operations’ own published output schema, so if Google adds or renames a field here, the page picks it up on the next deploy rather than drifting from what the API actually returns.
What data you get
Google Maps Business Search
- count
- integerrequired
- query
- stringrequired
- places
- arrayrequired
- places[].cid
- string — Google customer id — the decimal form of the feature id
- places[].city
- string
- places[].name
- stringrequired
- places[].phone
- string — Phone as Google displays it locally
- places[].domain
- string
- places[].rating
- number
- places[].street
- string
- places[].address
- string
- places[].placeId
- string — Google place id (ChIJ...)
- places[].website
- string
- places[].category
- string — Primary Google category
- places[].latitude
- number
- places[].locality
- string — Human "City, Region, Country" line
- places[].timezone
- string
- places[].featureId
- string — Google feature id (0x<cell>:0x<cid>); pass it to Google Maps Place Details
- places[].longitude
- number
- places[].thumbnail
- string
- places[].categories
- array
- places[].countryCode
- string
- places[].reviewCount
- integer — Total Google reviews. Best-effort: Google serves this field inconsistently on the Maps endpoints — the same request returned it one hour and omitted it the next (measured 2026-08-17) — so treat null as 'not published on this response', not as zero reviews.
- places[].addressLines
- array
- places[].openingHours
- array — Per weekday, as [{"day": "Monday", "hours": ["8 AM-11 PM"]}]
- places[].googleMapsUrl
- string
- places[].phoneInternational
- string — E.164 phone, when Google publishes one
- truncated
- booleanrequired — True when Google still had more results than `maxResults` allowed
Google Maps Place Details
- cid
- string — Google customer id — the decimal form of the feature id
- city
- string
- name
- stringrequired
- phone
- string — Phone as Google displays it locally
- domain
- string
- rating
- number
- street
- string
- address
- string
- placeId
- string — Google place id (ChIJ...)
- website
- string
- category
- string — Primary Google category
- latitude
- number
- locality
- string — Human "City, Region, Country" line
- timezone
- string
- featureId
- string — Google feature id (0x<cell>:0x<cid>); pass it to Google Maps Place Details
- longitude
- number
- thumbnail
- string
- categories
- array
- countryCode
- string
- reviewCount
- integer — Total Google reviews. Best-effort: Google serves this field inconsistently on the Maps endpoints — the same request returned it one hour and omitted it the next (measured 2026-08-17) — so treat null as 'not published on this response', not as zero reviews.
- addressLines
- array
- openingHours
- array — Per weekday, as [{"day": "Monday", "hours": ["8 AM-11 PM"]}]
- resolvedFrom
- stringrequired — Which input identifier this lookup was resolved from: placeId, cid, featureId or url
- googleMapsUrl
- string
- phoneInternational
- string — E.164 phone, when Google publishes one
Google Maps Reviews
- sort
- stringrequired
- count
- integerrequired
- reviews
- arrayrequired
- reviews[].text
- string — The review body in full. Null when the author rated without writing anything, which is common — roughly one review in ten on the places measured.
- reviews[].author
- object
- reviews[].photos
- array — Photos the author attached to this review
- reviews[].rating
- integer — Stars the author gave, 1-5
- reviews[].source
- string — Which network published the review — "Google" for the overwhelming majority, but Google also syndicates partner sources on some places
- reviews[].language
- string — Language of the text as delivered, as an ISO code
- reviews[].reviewId
- string
- reviews[].ratingMax
- integer — The scale the rating is on — 5 on every response measured
- reviews[].reviewUrl
- string — Permalink to the review on Google Maps
- reviews[].publishedAt
- string — When the review was posted, as an ISO 8601 UTC timestamp
- reviews[].relativeTime
- string — How Google phrases the age of the review (e.g. "a week ago")
- reviews[].ownerResponse
- object — The business owner's public reply, when there is one
- featureId
- stringrequired — The Google feature id these reviews were read from
- truncated
- booleanrequired — True when Google still had more reviews than `maxResults` allowed
- resolvedFrom
- stringrequired — Which input identifier this lookup was resolved from: placeId, cid, featureId or url
- nextPageToken
- string — Pass back as `pageToken` to read the next page. Null when Google has no more reviews to give.
Calling Google Maps Business Search
A schema-derived request and response shape — not a captured production call, since upAPI has none to publish. Every field is real, from the operation’s own published schema.
curl -X POST https://api.upapi.io/google-maps-search.post \
-H "X-Api-Key: $UPAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "coffee shops in Ottawa",
"region": "us",
"language": "en",
"maxResults": 20
}'{
"count": 3,
"query": "typescript",
"places": [
{
"cid": "example",
"city": "example",
"name": "example",
"phone": "example",
"domain": "example",
"rating": 1,
"street": "example",
"address": "example",
"placeId": "example",
"website": "example",
"category": "example",
"latitude": 43.65,
"locality": "example",
"timezone": "example",
"featureId": "example",
"longitude": -79.38,
"thumbnail": "example",
"categories": [
null
],
"countryCode": "US",
"reviewCount": 1,
"addressLines": [
null
],
"openingHours": [
null
],
"googleMapsUrl": "example",
"phoneInternational": "example"
}
],
"truncated": false
}Pricing
Google Maps Business Search
6 units per call
Google Maps Place Details
4 units per call
Google Maps Reviews
6 units per call
Every unit draws from one pooled monthly quota shared across the whole catalog. See upapi.io/pricing for what a unit costs on each plan.
Questions people actually ask
Do I need my own Google Maps API key or Google Cloud billing account?
No. These are upAPI operations, not a proxy in front of Google’s paid Places API — you call them with one upAPI key (the X-Api-Key header) and they run over upAPI’s own request path. There is nothing to enable in Google Cloud and no separate Google billing.
How much does this cost?
Google Maps Business Search is 6 units per call; Google Maps Place Details is 4 units per call; Google Maps Reviews is 6 units per call — every unit draws from one pooled monthly quota shared across the whole catalog. See upapi.io/pricing for what a unit costs on each plan.
How fresh is the data — is it cached?
Google Maps Business Search is cached for 30 minutes; Google Maps Place Details is cached for 1 hour; Google Maps Reviews is cached for 15 minutes. A repeat call inside a cached window returns the cached response and is billed nothing.
Can I search by coordinates instead of a text query?
Yes. Business Search accepts an optional latitude/longitude pair to centre the search, plus a zoom value that controls the effective radius, alongside the required text query.
What do I pass from a search result into Place Details?
Every place returned by Business Search carries a placeId, a featureId and a cid — Place Details accepts any of those ids, or a pasted Google Maps link, so you never have to hold onto the search response just to look one place up again later.