# Google Maps Reviews Scraper - Ratings, Text, Owner Replies (`scrapewise/google-maps-reviews-scraper`) Actor

Scrape Google Maps reviews of any place worldwide, no login: rating, full text in the original language plus translation, date, owner reply, photo count, restaurant ratings (food, service, price). Sort by newest, date filter, onlyNew for schedules. No reviewer names. Error rows are free.

- **URL**: https://apify.com/scrapewise/google-maps-reviews-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Lead generation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.26 / 1,000 review delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Maps Reviews Scraper: ratings, review text, owner replies and restaurant scores

Google Maps Reviews Scraper collects **reviews of any place on Google Maps, anywhere in the world**: restaurants,
hotels, shops, clinics, attractions, offices. Paste a place link (or a Place ID) and each review comes back as one
clean row with the star rating, the full text in its original language, a translation into your language, the exact
publish date, the owner's reply, how many photos it has, the guided ratings Google asks for (food, service,
atmosphere, price per person, wait time...) and a direct link to the review. Every row also carries the place
name, address, category, overall rating and total review count.

No Google account, cookies, API key or browser needed. **Reviewer names, profile links and photos are never
collected.** It is used to:

- track what customers say about your locations or your competitors, every day, with only the new reviews;
- feed sentiment analysis, topic mining and AI summaries with review text in many languages;
- benchmark restaurants by food, service, atmosphere and price per person;
- monitor how fast and how often businesses answer their reviews.

### At a glance

| What | Price |
|---|---|
| Review delivered | **US$ 0.30 per 1,000 reviews** (US$ 0.0003 each) on the Free plan, lower on paid plans |
| Run start | US$ 0.005 per run |

- 5,000 reviews = **about US$ 1.51** on the Free plan.
- The place details (name, address, rating, total) are included; there is no extra event for them.
- Error rows, duplicates and reviews already delivered in earlier runs (`onlyNew`) are never charged.
  `maxReviews` is a hard cap per place, and a spending limit set on the run stops it cleanly with everything
  delivered so far.

### Quick start

```json
{
  "startUrls": ["https://www.google.com/maps/place/Katz's+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"],
  "maxReviews": 50,
  "sort": "newest"
}
```

Several places, only reviews from the last 30 days, with labels and translations in English:

```json
{
  "startUrls": [
    "https://maps.app.goo.gl/your-share-link",
    "https://www.google.com/maps/place/Dishoom+Covent+Garden/data=!4m2!3m1!1s0x487604b7c7d895c5:0x9c3887a3670e0076"
  ],
  "placeIds": ["ChIJCar0f49ZwokR6ozLV-dHNTE"],
  "maxReviews": 0,
  "sort": "newest",
  "reviewsNewerThan": "30 days",
  "language": "en"
}
```

Daily monitoring: schedule the run once a day with `"onlyNew": true` and only reviews you have not received before
come back (and are charged).

### Input

| Field | What it does |
|---|---|
| `startUrls` | Google Maps place links, one per line: the address bar link after opening a place, a Share link (`maps.app.goo.gl`), or any link that contains a feature ID (`0x...:0x...`), a Place ID (`ChIJ...`) or a `cid=` number. |
| `placeIds` | Feature IDs, Google Place IDs (`ChIJ...`) or numeric CIDs. No API key needed. |
| `maxReviews` | Reviews per place (default 100). `0` = every review Google lists for the place. |
| `sort` | `newest` (default), `relevant`, `highest`, `lowest`: the same orders as Google Maps. |
| `language` | Language code (`en`, `fr`, `de`, `es`, `ja`, `pt-BR`...). Sets relative dates, guided rating labels and the translation. The original text always comes too. |
| `reviewsNewerThan` | A date (`2026-01-31`) or a period (`30 days`, `2 weeks`, `6 months`, `1 year`). With `newest` the run stops at the first older review. |
| `onlyNew` | Deliver only reviews not delivered in earlier runs for the same place (for schedules). |
| `proxyConfiguration` | Apify datacenter proxy by default; residential IPs are used by themselves only if Google refuses. |

Inputs written for other Google Maps review tools keep working: `startUrls` as objects with `url`, `placeUrls`,
`urls`, `placeId`, `reviewsSort` (`newest`, `mostRelevant`, `highestRanking`, `lowestRanking`), `sortBy`,
`reviewsStartDate`, `maxReviewsPerPlace`, `reviewsLimit`, `hl` and `onlyNewReviews` are read too.

### Output

Each review is one row with `type: "review"`:

| Field | What it is |
|---|---|
| `featureId`, `placeId` | Google's feature ID (`0x...:0x...`) and Place ID (`ChIJ...`) of the place |
| `placeName`, `placeAddress`, `placeCategory` | Name, address and main category of the place |
| `placeRating`, `placeTotalReviews` | Overall star rating and total review count shown on Google Maps |
| `placeUrl` | Link to the place on Google Maps |
| `reviewId`, `reviewUrl` | Google's review ID and a direct link to the review |
| `rating` | Stars, 1 to 5 |
| `text` | Full review text in the language it was written in (null for rating-only reviews) |
| `textTranslated` | Google's translation into `language`, when the review was written in another language |
| `language` | Language code of the original text (`en`, `fr`, `zh-Hans`...) |
| `publishedAt`, `relativeDate` | Exact publish date (UTC, ISO 8601) and Google's relative label ("2 days ago") |
| `ownerReply` | `{text, relativeDate}` of the business owner's answer, or null |
| `photosCount` | Number of photos attached to the review (the photos themselves are not collected) |
| `reviewerReviewCount` | How many reviews the reviewer has written in total (an anonymous count, no identity) |
| `questionnaire` | Guided answers as a dictionary: `Food`, `Service`, `Atmosphere` (1 to 5), `Price per person`, `Meal type`, `Wait time`, `Reservation`, `Parking`... |
| `sortedBy`, `sourceInput`, `scrapedAt` | Sort used, the link or ID you gave, and when the row was collected |

One real row from 17 Oct 2026:

```json
{
  "type": "review",
  "featureId": "0x487604b7c7d895c5:0x9c3887a3670e0076",
  "placeId": "ChIJxZXYx7cEdkgRdgAOZ6OHOJw",
  "placeName": "Dishoom Covent Garden",
  "placeAddress": "12 Upper St Martin's Ln, London WC2H 9FB, United Kingdom",
  "placeCategory": "Indian restaurant",
  "placeRating": 4.7,
  "placeTotalReviews": 29928,
  "placeUrl": "https://www.google.com/maps/place/?q=place_id:ChIJxZXYx7cEdkgRdgAOZ6OHOJw",
  "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2pOTU1qYzNOamhVTmxaS00ySnJXRGRoYW5ab1ltYxAB",
  "rating": 5,
  "text": "One of the best meals we've ever had. Incredibly impressed by the quality, freshness, and flavours. Service was lovely. We will be back!",
  "textTranslated": null,
  "language": "en",
  "publishedAt": "2026-10-17T12:12:19.021Z",
  "relativeDate": "11 hours ago",
  "ownerReply": null,
  "photosCount": 0,
  "reviewerReviewCount": 272,
  "questionnaire": {
    "Meal type": "Lunch",
    "Price per person": "£80–90",
    "Food": 5,
    "Service": 5,
    "Atmosphere": 5,
    "Reservation": "Reservation required",
    "Wait time": "No wait"
  },
  "sortedBy": "newest"
}
```

An owner reply looks like `{"text": "We're so glad you made the trek to come visit us! ...", "relativeDate": "a week ago"}`.

### Errors you may see

Every error is a row with `errorCode` and is never charged:

| errorCode | Meaning |
|---|---|
| `INVALID_INPUT` | A field has a wrong value, or a line is not a Google Maps place link or ID |
| `NOT_FOUND` | The link or ID does not point to a place (for example a search or a map point instead of a place) |
| `NO_REVIEWS` | The place has no reviews, or none newer than `reviewsNewerThan` |
| `BLOCKED` | Google refused every attempt for this place; run it again in a few minutes |
| `UNEXPECTED` | Something else stopped the run; the message says what |

### Integrations, scheduling and AI agents

- **Schedule** a daily run with `onlyNew` in [Apify schedules](https://docs.apify.com/platform/schedules) to get
  only the new reviews of your places every morning.
- **Export** as JSON, CSV, Excel or XML, or read the dataset from the [Apify API](https://docs.apify.com/api/v2).
- **Connect** it to Make, n8n, Zapier, Slack or Google Sheets through
  [Apify integrations](https://docs.apify.com/platform/integrations), for example to post every new 1 or 2 star
  review to a support channel.
- **AI agents:** call it as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp)
  in Claude, ChatGPT, Cursor or any MCP client, for example "get the newest 200 reviews of this restaurant and
  summarize the complaints about service".

### FAQ

**Do I need a Google account or an API key?** No. The reviews come from the same public data Google Maps shows
to any visitor, without login.

**How do I get the place link?** Open the place on Google Maps and copy the address bar, or use Share and copy
the link. A plain search link (`/maps/search/...`) or a link with only a name and no ID is not enough: open the
place first.

**Can I use a Google Place ID?** Yes, put it in `placeIds` (`ChIJ...`). Feature IDs (`0x...:0x...`) and numeric CIDs
work too.

**In which language does the text come?** Always in the language the reviewer wrote it, plus `textTranslated` in
your `language` when they differ. `language` also changes `relativeDate` and the questionnaire labels.

**How many reviews can I get per place?** As many as Google lists for the place: thousands for popular places
(we collected more than 2,000 per place in tests and the list kept going). Use `maxReviews: 0` for all of them.

**How does `onlyNew` work?** The Actor keeps the IDs of the reviews it delivered for each place in a key-value store
in your account. With the `newest` sort it stops as soon as it reaches a review it delivered before, so a daily run
of a busy place costs only a few requests.

**Why is there no reviewer name?** Reviewers are private individuals. This Actor deliberately leaves out names,
profile links, avatars and reviewers' photos; the reviewer is only described by an anonymous review count.

**Is it legal?** The Actor reads public reviews and leaves personal data of reviewers out by design. You are
responsible for how you use the data under the laws that apply to you.

**Something broke or a field is missing?** Open an issue on the Actor page; issues are answered within a day.

### Limitations

- Google Maps does not offer text search inside reviews here; filter the dataset after the run.
- Likes on reviews are not included, because their value could not be confirmed as reliable.
- `questionnaire` exists mainly for restaurants and some hotels and stores; for other places it is an empty object.
- The owner reply has a relative date only (Google does not send the exact date for it).
- Reviews are listed as Google serves them; very old places may stop at the oldest review Google keeps in the list.

### Changelog

- **17 Oct 2026:** first version: place links, Share links, feature IDs, Place IDs and CIDs; four sort orders;
  original text plus translation; owner replies; guided ratings; `reviewsNewerThan`; `onlyNew` for schedules.

# Actor input Schema

## `startUrls` (type: `array`):

Google Maps place links, one per line: the link from the address bar after opening a place, a Share link (maps.app.goo.gl) or any link that contains the feature ID 0x...:0x... or a Place ID (ChIJ...).

## `placeIds` (type: `array`):

Optional: feature IDs (0x89c2598f7ff4aa09:0x313547e757cb8cea), Google Place IDs (ChIJ...) or numeric CIDs, one per line. No API key needed.

## `maxReviews` (type: `integer`):

Reviews to collect for each place. 0 = every review Google lists.

## `sort` (type: `string`):

Order of the reviews, same options as Google Maps.

## `language` (type: `string`):

Language code for relative dates, guided rating labels and the translation (en, fr, de, es, ja...). The review text always comes in its original language too.

## `reviewsNewerThan` (type: `string`):

A date (2026-01-31) or a period (30 days, 2 weeks, 6 months). With the Newest sort the Actor stops at the first older review, so you pay only for the recent ones.

## `onlyNew` (type: `boolean`):

On: remembers the reviews delivered in earlier runs for each place (in your account) and delivers only reviews not seen before. Skipped reviews are free.

## `proxyConfiguration` (type: `object`):

Apify datacenter proxy by default, which Google Maps accepts for reviews. If Google refuses it, the run switches to residential IPs by itself.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.google.com/maps/place/Katz's+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"
  ],
  "maxReviews": 50,
  "sort": "newest",
  "language": "en",
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://www.google.com/maps/place/Katz's+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"
    ],
    "maxReviews": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/google-maps-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": ["https://www.google.com/maps/place/Katz's+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"],
    "maxReviews": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/google-maps-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://www.google.com/maps/place/Katz'\''s+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea"
  ],
  "maxReviews": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/google-maps-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/google-maps-reviews-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/xMSi9eBoLLY5haPzI/builds/6bhWaZZSCljIrDkGc/openapi.json
