# Maps Reviews > Source: https://scrape.do/documentation/google-scraper-api/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. | 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](/documentation/google-scraper-api/maps/search) | | `place_id` | string | Place ID in `ChIJ...` format. Returned in `local_results[].place_id` from Maps Search | > [!NOTE] > 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 | > [!WARNING] > `topic_id` and `query` are mutually exclusive. Passing both returns `400`. See [Sorting](#sorting), [Topic Filtering](#topic-filtering), and [Keyword Search](#keyword-search-query) 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 (API mode)** ```bash curl --location --request GET 'https://api.scrape.do/plugin/google/maps/reviews?token=&data_id=0x864c28f004653715:0x57c504dbf0bc93a0' ``` **Python (API mode)** ```python import requests import json 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)) ``` **Node.js (API mode)** ```javascript const axios = require('axios'); const 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); }); ``` *(Go, Ruby, Java, C#, PHP examples are also available on the HTML version.)* ```bash curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c2597777397641:0x4387a82ee10d3e3b&token=YOUR_TOKEN" ``` ### By `place_id` ```bash curl "https://api.scrape.do/plugin/google/maps/reviews?place_id=ChIJQXY5d3dZWIYRO949EA6uh0M&token=YOUR_TOKEN" ``` ### 20 reviews per page ```bash 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) ```bash curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c2597777397641:0x4387a82ee10d3e3b&next_page_token=CAESY0NB...&token=YOUR_TOKEN" ``` ### Localized (French) ```bash 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. ```json { "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: ```json { "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](#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. ```bash # 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. > [!WARNING] > 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"}`. ```bash # 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 ```bash curl -s "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&token=$TOKEN" \ | jq '.topics' ``` ```json [ { "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 ```bash curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&topic_id=EPwqTcuhb0c&token=$TOKEN" ``` > [!NOTE] > 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. ```bash curl "https://api.scrape.do/plugin/google/maps/reviews?data_id=0x89c259606c152b2d:0xe230af1b18e542a7&query=breakfast&token=$TOKEN" ``` > [!WARNING] > `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 ```json { "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 ```json { "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 ```json { "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 | > [!NOTE] > **Locale behavior.** When `hl` is not English, `details` keys come back **in the requested language**. For example, with `hl=fr`: > > ```json > { "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: ```json { "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: ```json { "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 ```bash 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 ``` ---