Maps Reviews
Fetch paginated Google Maps reviews as structured JSON, with sort, topic filtering, keyword search, and guided review details
The Reviews endpoint returns paginated user reviews for a single Google Maps place. Each review comes with a rating, ISO dates, text (with optional translation), images, user profile data, likes count, guided review details, and (when present) the business owner's response.
Endpoint
GET https://api.scrape.do/plugin/google/maps/reviewsRequest Parameters
Required
One of data_id or place_id must be provided.
| Parameter | Type | Description |
|---|---|---|
token | string | Your Scrape.do API authentication token |
data_id | string | Place ID in 0xHEX:0xHEX format. Returned in local_results[].data_id from Maps Search |
place_id | string | Place ID in ChIJ... format. Returned in local_results[].place_id from Maps Search |
Prefer data_id: the plugin resolves place_id to data_id internally, which adds a small amount of latency.
Pagination
| Parameter | Type | Default | Description |
|---|---|---|---|
num | int | 10 | Reviews per page (1–20) |
next_page_token | string | — | Pagination cursor from pagination.next_page_token in the previous response |
Filtering & Sorting
| Parameter | Type | Description |
|---|---|---|
sort_by | string | Sort order. One of newestFirst, ratingHigh, ratingLow. Omit for Google's relevance default |
topic_id | string | Filter to reviews mentioning a specific topic. Use an id value from the topics[] array in the first-page response |
query | string | Filter reviews by keyword search |
topic_id and query are mutually exclusive. Passing both returns 400.
See Sorting, Topic Filtering, and Keyword Search below for full details.
Localization
| Parameter | Type | Default | Description |
|---|---|---|---|
hl | string | en | Host language. Controls details key names and enables translation of non-English review snippets |
gl | string | us | Country perspective |
google_domain | string | google.com | Google domain to query |
Example Usage
Basic: by data_id
curl --location --request GET 'https://api.scrape.do/plugin/google/maps/reviews?token=<SDO-token>&data_id=0x864c28f004653715:0x57c504dbf0bc93a0'import requests
import json
token = "<SDO-token>"
dataId = "0x864c28f004653715:0x57c504dbf0bc93a0"
url = f"https://api.scrape.do/plugin/google/maps/reviews?token={token}&data_id={dataId}"
response = requests.request("GET", url)
print(json.dumps(response.json(), indent=2))const axios = require('axios');
const token = "<SDO-token>";
const dataId = "0x864c28f004653715:0x57c504dbf0bc93a0";
const url = `https://api.scrape.do/plugin/google/maps/reviews?token=${token}&data_id=${dataId}`;
axios.get(url)
.then(response => {
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error(error);
});package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
token := "<SDO-token>"
dataId := "0x864c28f004653715:0x57c504dbf0bc93a0"
url := fmt.Sprintf(
"https://api.scrape.do/plugin/google/maps/reviews?token=%s&data_id=%s",
token, dataId,
)
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}require 'net/http'
require 'json'
token = "<SDO-token>"
dataId = "0x864c28f004653715:0x57c504dbf0bc93a0"
url = URI("https://api.scrape.do/plugin/google/maps/reviews?token=#{token}&data_id=#{dataId}")
response = Net::HTTP.get(url)
puts JSON.pretty_generate(JSON.parse(response))import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class GoogleMapsReviews {
public static void main(String[] args) throws Exception {
String token = "<SDO-token>";
String dataId = "0x864c28f004653715:0x57c504dbf0bc93a0";
String url = String.format(
"https://api.scrape.do/plugin/google/maps/reviews?token=%s&data_id=%s",
token, dataId
);
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println(response.toString());
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "<SDO-token>";
string dataId = "0x864c28f004653715:0x57c504dbf0bc93a0";
string url = $"https://api.scrape.do/plugin/google/maps/reviews?token={token}&data_id={dataId}";
using HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
}<?php
$token = "<SDO-token>";
$dataId = "0x864c28f004653715:0x57c504dbf0bc93a0";
$url = "https://api.scrape.do/plugin/google/maps/reviews?token={$token}&data_id={$dataId}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
?>curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c2597777397641:0x4387a82ee10d3e3b&token=YOUR_TOKEN"By place_id
curl "https://api.scrape.do/plugin/google/maps/reviews?place_id=ChIJQXY5d3dZWIYRO949EA6uh0M&token=YOUR_TOKEN"20 reviews per page
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c2597777397641:0x4387a82ee10d3e3b&num=20&token=YOUR_TOKEN"Page 2 (using the token from page 1)
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c2597777397641:0x4387a82ee10d3e3b&next_page_token=CAESY0NB...&token=YOUR_TOKEN"Localized (French)
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c2597777397641:0x4387a82ee10d3e3b&hl=fr&token=YOUR_TOKEN"With hl=fr, non-French review snippets come back with both the original text and a translated version (under extracted_snippet.translated).
Response: First Page
The first page includes place_info and topics alongside reviews.
{
"search_metadata": {
"google_maps_url": "https://www.google.com/maps/place/?cid=4866042841694813755&hl=en&gl=us"
},
"search_parameters": {
"engine": "google_maps_reviews",
"data_id": "0x89c2597777397641:0x4387a82ee10d3e3b",
"hl": "en",
"num": 10,
"google_domain": "google.com"
},
"place_info": {
"title": "McDonald's",
"address": "1528 Broadway Times Square, New York, NY 10036",
"rating": 3.7,
"reviews": 1626,
"type": "Fast food restaurant"
},
"topics": [
{ "keyword": "floor", "mentions": 32, "id": "EPwqTcuhb0c" },
{ "keyword": "security", "mentions": 29, "id": "AB8BSPrzZX4" },
{ "keyword": "clean", "mentions": 23, "id": "bdOKu_b9hgo" }
],
"reviews": [
{
"position": 1,
"link": "https://www.google.com/maps/reviews/data=!4m8!14m7!...",
"review_id": "Ci9DQUlRQUNvZENodHljRjlvT2poS2Vu...",
"source": "Google",
"rating": 1,
"date": "4 months ago",
"iso_date": "2025-11-17T13:48:47Z",
"iso_date_of_last_edit": "2025-11-17T13:48:47Z",
"snippet": "As someone who works in fast food...",
"extracted_snippet": {
"original": "As someone who works in fast food..."
},
"likes": 0,
"images": ["https://lh3.googleusercontent.com/geougc-cs/..."],
"user": {
"name": "Breanna Blackwell",
"link": "https://www.google.com/maps/contrib/106896297413018324593?hl=en",
"contributor_id": "106896297413018324593",
"thumbnail": "https://lh3.googleusercontent.com/a/...",
"local_guide": true,
"reviews": 7,
"photos": 2
},
"details": {
"food": 1,
"service": 1,
"atmosphere": 1
}
}
],
"pagination": {
"next_page_token": "CAESY0NB..."
}
}Response: Subsequent Pages
Pages 2+ omit place_info and topics and return only reviews and pagination:
{
"search_metadata": { "google_maps_url": "..." },
"search_parameters": { "engine": "google_maps_reviews", "data_id": "...", "hl": "en", "num": 10 },
"reviews": [
{ "position": 1, "rating": 5, "snippet": "...", "user": { "name": "..." }, "details": { "food": 5 } },
{ "position": 2, "rating": 4, "snippet": "...", "user": { "name": "..." } }
],
"pagination": {
"next_page_token": "CAESY0NB..."
}
}pagination is absent on the last page.
Response Fields
place_info (first page only)
| Field | Type | Description |
|---|---|---|
title | string | Place name |
address | string | Full address |
rating | float | Average rating (1.0–5.0) |
reviews | int | Total review count |
type | string | Primary place type |
topics[] (first page only)
| Field | Type | Description |
|---|---|---|
keyword | string | Topic keyword (e.g., "floor", "big mac") |
mentions | int | Number of reviews mentioning this topic |
id | string | Opaque topic ID. Pass to topic_id to filter reviews to this topic. Format varies: short alphanumeric (EPwqTcuhb0c) or prefixed paths (/m/0l7_8, /g/11c5rmbjqg). Use as-returned |
reviews[]
| Field | Type | Always Present | Description |
|---|---|---|---|
position | int | yes | Position in current page (1-indexed) |
link | string | Permalink to the review on Google Maps | |
review_id | string | Unique review identifier | |
source | string | Review source: "Google", "Priceline", "Tripadvisor", "Booking.com", "Trip.com" | |
rating | float | yes | Star rating (1.0–5.0) |
date | string | Relative date ("4 months ago", "Edited a month ago") | |
iso_date | string | Original post date in ISO 8601 format | |
iso_date_of_last_edit | string | Last edit date in ISO 8601 (same as iso_date if not edited) | |
snippet | string | Review text | |
extracted_snippet | object | { original, translated? }. translated is included when hl differs from the review language | |
likes | int | yes | Number of "helpful" votes |
images | string[] | Array of review image URLs | |
user | object | Reviewer details (see below) | |
details | object | Guided review details (see Review Details below) | |
response | object | Owner/business response (see below) |
reviews[].user
| Field | Type | Description |
|---|---|---|
name | string | Reviewer's display name |
link | string | Link to reviewer's profile |
contributor_id | string | Google contributor ID |
thumbnail | string | Profile photo URL |
local_guide | bool | true if reviewer is a Local Guide |
reviews | int | Total reviews by this user |
photos | int | Total photos by this user |
reviews[].response
Present when the business has replied to the review.
| Field | Type | Description |
|---|---|---|
date | string | Relative date of the response |
iso_date | string | Response date in ISO 8601 |
iso_date_of_last_edit | string | Last edit date in ISO 8601 |
snippet | string | Response text |
extracted_snippet | object | { original, translated? }. Structured response text |
pagination
| Field | Type | Description |
|---|---|---|
next_page_token | string | Token for the next page. Absent on the last page |
Pagination
Default page size is 10; max 20. On each response, read pagination.next_page_token and pass it as next_page_token on the following request.
# Page 1
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=...&num=20&token=$TOKEN"
# → response includes pagination.next_page_token
# Page 2
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=...&num=20&next_page_token=CAESY0NB...&token=$TOKEN"
# → response includes the token for page 3
# Continue until pagination is absent (last page)Pagination behavior:
- Default page size is 10 reviews; max 20 via
num. positionrestarts at 1 on each page.place_infoandtopicsare first-page only.- No duplicates across pages.
paginationis absent on the last page.
A transient 502 response on a page that should exist is almost always recoverable. Retry once before treating it as the end of the review list.
Sorting
sort_by value | Description |
|---|---|
| (omitted) | Most relevant (Google's quality score). Default |
newestFirst | Newest reviews first |
ratingHigh | Highest rating first |
ratingLow | Lowest rating first |
Any other value returns 400 with {"error":"sort_by must be one of: newestFirst, ratingHigh, ratingLow"}.
# Highest-rated reviews
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&sort_by=ratingHigh&token=$TOKEN"
# Lowest-rated first, useful for complaint monitoring
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&sort_by=ratingLow&token=$TOKEN"Topic Filtering
The first-page response contains a topics[] array of keywords Google has identified across the reviews, with counts and opaque IDs. Pass an id as topic_id on a subsequent request to filter reviews to just that topic.
Getting Topic IDs
curl -s "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&token=$TOKEN" \
| jq '.topics'[
{ "keyword": "ny style pizza", "mentions": 41, "id": "EPwqTcuhb0c" },
{ "keyword": "stromboli", "mentions": 21, "id": "AB8BSPrzZX4" },
{ "keyword": "live music", "mentions": 3, "id": "bdOKu_b9hgo" }
]Using a Topic ID
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&topic_id=EPwqTcuhb0c&token=$TOKEN"Topic IDs are opaque. Don't parse or construct them. Format varies: short alphanumeric codes (EPwqTcuhb0c) or prefixed paths (/m/0l7_8, /g/11c5rmbjqg). Pass them through as-received.
Keyword Search (query)
The query parameter filters reviews to those whose text matches a keyword. Google's match is fuzzy rather than strict, so reviews that mention related terms also surface.
curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&query=breakfast&token=$TOKEN"topic_id and query are mutually exclusive. Passing both returns 400 topic_id and query parameters can't be used together.
Review Details
The details field on each review contains structured data from Google's guided review system. The set of keys varies by place type. Restaurants get food/service/atmosphere ratings and meal metadata; hotels get bed comfort and travel group; auto services get price assessments and service lists.
Restaurant details
{
"order_type": "Dine in",
"meal_type": "Dinner",
"price_per_person": "$10–20",
"food": 5,
"service": 5,
"atmosphere": 4,
"noise_level": "Loud, but you can still talk",
"group_size": "2 people",
"wait_time": "No wait",
"recommended_dishes": "Fondant Au Chocolat",
"dietary_restrictions": "No",
"vegetarian_options": "Yes",
"kid_friendliness": "Yes",
"reservation": "Reservations recommended",
"parking_space": "Easy to find parking",
"parking_options": "Free parking",
"wheelchair_accessibility": "Yes"
}Hotel details
{
"trip_type": "Vacation",
"travel_group": "Couple",
"rooms": 4,
"service": 5,
"location": 5,
"bed_comfort": 5,
"hotel_highlights": "Great value",
"safety": 5,
"walkability": 5,
"nearby_activities": 4,
"food_drinks": 3,
"room_view": "Skyline view",
"parking_options": "Valet parking available",
"noteworthy_details": "Quiet despite central location"
}Auto service details
{
"price_assessment": "Great price",
"services": "Auto engine diagnostic, Tires, Oil change"
}Value Types
| Kind | Example | Type |
|---|---|---|
| Rating (1–5) | "food": 5 | integer |
| Choice | "order_type": "Dine in" | string |
| Multi-choice | "services": "Tires, Oil change" | comma-separated string |
Locale behavior. When hl is not English, details keys come back in the requested language. For example, with hl=fr:
{ "ambiance": 5, "cuisine": 5, "service": 5, "type_de_commande": "Repas sur place", "type_de_repas": "Dîner" }This matches Google's own behavior. If you need stable English keys, always pass hl=en.
Owner Responses
Business owners can reply to reviews. When present, reviews[].response contains:
{
"response": {
"date": "3 weeks ago",
"iso_date": "2026-03-07T18:16:24Z",
"iso_date_of_last_edit": "2026-03-07T18:16:24Z",
"snippet": "Hi Amy, we're delighted you enjoyed your stay...",
"extracted_snippet": {
"original": "Hi Amy, we're delighted you enjoyed your stay..."
}
}
}| Field | Type | Description |
|---|---|---|
date | string | Relative date of the response |
iso_date | string | Response date in ISO 8601 |
iso_date_of_last_edit | string | Last edit date in ISO 8601 |
snippet | string | Response text |
extracted_snippet | object | { original, translated? } |
Absent when the business hasn't replied.
Translations
When hl differs from the review's original language, extracted_snippet contains both the original text and a translated version:
{
"snippet": "Stopped into New York Pizza Pasta & Subs...",
"extracted_snippet": {
"original": "Stopped into New York Pizza Pasta & Subs and was genuinely impressed...",
"translated": "Je suis passé chez New York Pizza Pasta & Subs et j'ai été vraiment impressionné..."
}
}translated is omitted when the review is already in the requested language.
Third-Party Sources (Hotels)
Hotels often include reviews aggregated from partner services:
| Source | Notes |
|---|---|
"Google" | Standard Google review with full user profile data |
"Priceline" | External link, no contributor_id / local_guide |
"Tripadvisor" | External link, no contributor_id / local_guide |
"Trip.com" | External link, no contributor_id / local_guide |
"Booking.com" | External link, no contributor_id / local_guide |
Third-party review objects may have limited user data (missing contributor_id, reviews, photos, local_guide).
Full Workflow
TOKEN="YOUR_TOKEN"
# 1. Search for a place and pick one
curl -s "https://api.scrape.do/plugin/google/maps/search?q=best+pizza+nyc&token=$TOKEN" \
| jq '.local_results[0] | {title, data_id, rating, reviews}'
# 2. Fetch reviews for that place
DATA_ID="0x89c259606c152b2d:0xe230af1b18e542a7"
curl -s "https://api.scrape.do/plugin/google/maps/reviews?data_id=$DATA_ID&token=$TOKEN" \
| jq '{place: .place_info.title, topics: [.topics[].keyword], first_five: [.reviews[] | {user: .user.name, rating, snippet: .snippet[:80]}]}'
# 3. Lowest-rated reviews (for quality triage)
curl -s "https://api.scrape.do/plugin/google/maps/reviews?data_id=$DATA_ID&sort_by=ratingLow&token=$TOKEN" \
| jq '.reviews[] | {user: .user.name, rating, snippet: .snippet[:120]}'
# 4. Paginate through all reviews
NEXT=$(curl -s "https://api.scrape.do/plugin/google/maps/reviews?data_id=$DATA_ID&num=20&token=$TOKEN" \
| jq -r '.pagination.next_page_token // empty')
while [ -n "$NEXT" ]; do
BODY=$(curl -s "https://api.scrape.do/plugin/google/maps/reviews?data_id=$DATA_ID&num=20&next_page_token=$NEXT&token=$TOKEN")
echo "$BODY" | jq '.reviews | length'
NEXT=$(echo "$BODY" | jq -r '.pagination.next_page_token // empty')
done
