logo

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/reviews

Request Parameters

Required

One of data_id or place_id must be provided.

ParameterTypeDescription
tokenstringYour Scrape.do API authentication token
data_idstringPlace ID in 0xHEX:0xHEX format. Returned in local_results[].data_id from Maps Search
place_idstringPlace 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

ParameterTypeDefaultDescription
numint10Reviews per page (1–20)
next_page_tokenstringPagination cursor from pagination.next_page_token in the previous response

Filtering & Sorting

ParameterTypeDescription
sort_bystringSort order. One of newestFirst, ratingHigh, ratingLow. Omit for Google's relevance default
topic_idstringFilter to reviews mentioning a specific topic. Use an id value from the topics[] array in the first-page response
querystringFilter 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

ParameterTypeDefaultDescription
hlstringenHost language. Controls details key names and enables translation of non-English review snippets
glstringusCountry perspective
google_domainstringgoogle.comGoogle 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)

FieldTypeDescription
titlestringPlace name
addressstringFull address
ratingfloatAverage rating (1.0–5.0)
reviewsintTotal review count
typestringPrimary place type

topics[] (first page only)

FieldTypeDescription
keywordstringTopic keyword (e.g., "floor", "big mac")
mentionsintNumber of reviews mentioning this topic
idstringOpaque 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[]

FieldTypeAlways PresentDescription
positionintyesPosition in current page (1-indexed)
linkstringPermalink to the review on Google Maps
review_idstringUnique review identifier
sourcestringReview source: "Google", "Priceline", "Tripadvisor", "Booking.com", "Trip.com"
ratingfloatyesStar rating (1.0–5.0)
datestringRelative date ("4 months ago", "Edited a month ago")
iso_datestringOriginal post date in ISO 8601 format
iso_date_of_last_editstringLast edit date in ISO 8601 (same as iso_date if not edited)
snippetstringReview text
extracted_snippetobject{ original, translated? }. translated is included when hl differs from the review language
likesintyesNumber of "helpful" votes
imagesstring[]Array of review image URLs
userobjectReviewer details (see below)
detailsobjectGuided review details (see Review Details below)
responseobjectOwner/business response (see below)

reviews[].user

FieldTypeDescription
namestringReviewer's display name
linkstringLink to reviewer's profile
contributor_idstringGoogle contributor ID
thumbnailstringProfile photo URL
local_guidebooltrue if reviewer is a Local Guide
reviewsintTotal reviews by this user
photosintTotal photos by this user

reviews[].response

Present when the business has replied to the review.

FieldTypeDescription
datestringRelative date of the response
iso_datestringResponse date in ISO 8601
iso_date_of_last_editstringLast edit date in ISO 8601
snippetstringResponse text
extracted_snippetobject{ original, translated? }. Structured response text

pagination

FieldTypeDescription
next_page_tokenstringToken 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.
  • position restarts at 1 on each page.
  • place_info and topics are first-page only.
  • No duplicates across pages.
  • pagination is 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 valueDescription
(omitted)Most relevant (Google's quality score). Default
newestFirstNewest reviews first
ratingHighHighest rating first
ratingLowLowest 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

KindExampleType
Rating (1–5)"food": 5integer
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..."
    }
  }
}
FieldTypeDescription
datestringRelative date of the response
iso_datestringResponse date in ISO 8601
iso_date_of_last_editstringLast edit date in ISO 8601
snippetstringResponse text
extracted_snippetobject{ 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:

SourceNotes
"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

On this page