# Google Maps Reviews Scraper: Ratings, Text, Replies, Photos (`quarra/google-maps-reviews-scraper`) Actor

Google reviews of any place from its Google Maps link, place ID, CID or name and city: rating, full text and translation, date, owner reply, review photos and likes, plus the place's rating and review count. No reviewer names or profiles. Pay per review.

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

## Pricing

from $0.38 / 1,000 reviews

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, Text, Owner Replies & Photos

Get the Google reviews of any place: give its Google Maps link, place ID, CID, or its name and city. Each review comes
with its rating, full text (and Google's translation when it was written in another language), date, the owner's reply
with its date, the review's photos and likes, plus the place's name, address, rating and review count.

**No reviewer data.** We never deliver a reviewer's name, profile, photo, ID or review count: only what the review says
about the place. The owner's reply is cleaned of people's names too: a name recognition model (any of the main European
languages) removes the greeting name and the signature, and a name inside a sentence becomes `[name]`; the reviewer's own
name is removed from the reply wherever it matches the name Google gives (whole, or a word of it in a greeting or thank-you). Business names and teams ("The Ange team") are kept; an email address in a reply can be replaced by `[email]`. The model is
good, not perfect: a rare or misspelled name in the middle of a sentence can slip through, and an unusual word can be taken
for a name. Known weak spots: a first name that is also a common word or the place's own name, a name written in a script the
model cannot read (Cyrillic, Greek, Korean, Japanese, Chinese, Arabic, Hebrew, Thai) when it sits in the middle of a sentence
rather than in a greeting or sign-off, a reviewer's single initial or a nickname that is also an ordinary word, and unusual
sign-off layouts. On our own tests of 2,700 written cases plus 163 real replies we found no leaked name in the standard
layouts, and a few leaks and a few damaged words in the hardest sets; we do not promise zero. The review text itself is
delivered as its author wrote it.

**From $0.38 per 1,000 reviews**, plus $0.0025 per place looked up and $0.004 per run. 100 reviews of one place cost
$0.0445 to $0.0595 depending on your Apify plan.

### Quick start

1. Paste one or more **places**: a Google Maps link, a place ID (`ChIJ...`), a CID, or a name with its city.
2. Choose **how many reviews per place** (0 = all) and the **order** (newest, most relevant, highest or lowest rating).
3. Click **Start** and read the reviews in the **Output** tab.

It also runs from the Apify API, on a schedule, and connects to webhooks, Make, Zapier, n8n or Apify's MCP server.
Run it every week with "Newest first" to follow new reviews of your places and your competitors.

### What it is used for

- Reputation monitoring: new reviews and low ratings of your locations, and whether they got a reply.
- Competitor research: what customers praise or complain about at nearby places.
- Sentiment analysis and AI datasets: review text with its rating, date and language.
- Local SEO and agencies: reply rate and review volume per location.

### What you get

One record per review:

| Field | Example |
|---|---|
| `rating` | `5` |
| `text` | `"Great view from the second floor, the queue moved fast."` |
| `originalText`, `originalLanguage`, `translated` | the text as written, its language, and whether `text` is Google's translation |
| `publishedAt`, `publishedAgo` | `"2026-10-18T09:12:44Z"`, `"4 days ago"` |
| `ownerResponse`, `ownerResponseAt` | the owner's reply (without names, see above) and its date |
| `photos`, `photosCount` | links to the review's photos |
| `likesCount` | likes on the review (`null` when Google shows none) |
| `highlights` | ratings by aspect, when given (`Food`, `Service`, `Atmosphere`...) |
| `reviewId`, `reviewUrl` | Google's ID of the review and its link |
| `placeName`, `placeAddress`, `placeRating`, `placeReviewsCount` | the place, as Google shows it |
| `placeId`, `cid`, `placeUrl` | the place's identifiers and Google Maps link |
| `order`, `position` | the order the review was read in, and its rank there |

A place that cannot be read gets one free error record (`type: "error"`) with the reason and whether a retry may help.
The run summary (`OUTPUT` record) lists, per place, the reviews delivered next to the count Google shows.

### Inputs

| Field | What it does |
|---|---|
| `places` | Links, place IDs, CIDs or names with their city. Share links (`maps.app.goo.gl`) work. A name is checked against the place Google finds (the city can be written in any language, "Colosseum Rome"): a different place gets an error record, not charged, never someone else's reviews. |
| `maxReviewsPerPlace` | Reviews per place. Default 100; 0 = all (see Limits). |
| `sort` | `newest`, `relevant`, `highest`, `lowest`. |
| `language` | Language of the texts: reviews written in another language come with Google's translation and the original. |
| `country` | Used only to find a place given by its name. |
| `maxItems` | Stop after this many reviews in total. |

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Run start | $0.004 per run |
| Place looked up | $0.0025 per place, once per run, even when the place has no reviews or Google has no such place. A name is never charged when Google's best match is a different place, and nothing is charged when the lookup could not be made on our side |
| Review delivered | by Apify plan, below |

| Apify plan | Per 1,000 reviews |
|---|---|
| Free | $0.53 (live reviews need a paid plan, see the FAQ) |
| Bronze | $0.43 |
| Silver, Gold and above | $0.38 |

Examples:

| Run | Free | Bronze | Silver, Gold and above |
|---|---|---|---|
| One place, 20 reviews | $0.0171 | $0.0151 | $0.0141 |
| One place, 100 reviews | $0.0595 | $0.0495 | $0.0445 |
| Ten places, 100 reviews each | $0.559 | $0.459 | $0.409 |

Never charged: error records themselves, notices, a review already delivered in the run, and a share link that leads
to no place (it is refused before any lookup). The same place given twice is read once and charged once, except a CID and
a place ID of the same place that can only be matched after the lookup: each counts as one place looked up.

### Limits

- **Google lists at most 4,490 reviews per order**, and in the two rating orders at most 76 reviews per star (380 per
  place; measured on the Eiffel Tower, 22/10/2026). For more than that, use "Newest first" or "Most relevant".
- **Deep reading is limited per run.** How far a run reads grows with the reviews it has already delivered: a place alone
  in a run stops at about 280 to 400 reviews (280 on Silver and above, 390 on Bronze in our tests), with a message saying
  so. Several big places in one run go much deeper (4 places of 1,000 reviews each came out complete in our tests); a
  small place next to a big one adds little.
- **Rating orders can skip a review.** On a town hall with 88 reviews (22/10/2026), "newest" and "most relevant" listed
  all 88, the two rating orders 87: Google left one out. The summary shows delivered vs Google's count per place.
- **No date filter.** Use "Newest first" with a limit and keep what is newer than your last run.
- `likesCount` is often `null`: Google does not show likes on most reviews.

### FAQ

**Do I need a Google account or an API key?** No.

**Do you deliver who wrote the review?** No. No name, profile link, photo, ID or review count of the reviewer, on purpose.

**Is anything different on Apify's free plan?** Live reviews need a paid Apify plan. On the free plan, the prefilled
example (the Eiffel Tower link, 20 newest reviews, English, no other option) returns a stored sample, marked
`sample: true` with its date. Any other input looks nothing up and says so in the run. Only the run start is charged.

**What if a run is restarted?** It resumes where it was: reviews and places already charged are not charged again. A run
restarted on request (reboot, resurrect, or restart on error) more than 3 times stops and says so; start a new run instead.

**Does the Actor send anything to Quarra?** Only when a run fails, runs out of time or the review service is down: the Actor, its build, the error type, the line of our code where it happened, and the memory and time the run was given, so we can fix it fast. Never your places, your results, your account or the run ID.

# Actor input Schema

## `places` (type: `array`):

Google Maps links (place page, share link, ?cid= link), place IDs (ChIJ...), CIDs, or a place name with its city ("Hedonism Wines, London"). A name is checked against the place Google finds; a link is always exact.

## `maxReviewsPerPlace` (type: `integer`):

How many reviews to get from each place. 0 = all of them. A place alone in a run stops at a few hundred reviews; with several places in the same run, each goes much deeper (see Limits in the README).

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

The order Google lists the reviews in. With a limit per place, you get the first reviews of this order. Rating orders list at most 76 reviews per star.

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

Language code (en, fr, de, es, it, pt, ja...) or name. Reviews written in another language come with Google's translation into it, and the original text.

## `country` (type: `string`):

Two-letter country code or country name, used to find a place given by its name. Links, place IDs and CIDs do not need it.

## `maxItems` (type: `integer`):

Stop after this many reviews in total, all places together. Leave empty for no limit.

## Actor input object example

```json
{
  "places": [
    "https://www.google.com/maps/place/Eiffel+Tower/@48.8583701,2.2944813,17z/data=!3m1!4b1!4m6!3m5!1s0x47e66e2964e34e2d:0x8ddca9ee380ef7e0!8m2!3d48.8583701!4d2.2944813!16zL20vMDJqODE"
  ],
  "maxReviewsPerPlace": 20,
  "sort": "newest",
  "language": "en",
  "country": "US"
}
```

# Actor output Schema

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

Every review with its place, and free rows with the reason when a place could not be read.

## `overview` (type: `string`):

One line per review: place, stars, text, date, owner reply.

## `summary` (type: `string`):

Reviews per place against Google's count, why the run stopped.

# 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 = {
    "places": [
        "https://www.google.com/maps/place/Eiffel+Tower/@48.8583701,2.2944813,17z/data=!3m1!4b1!4m6!3m5!1s0x47e66e2964e34e2d:0x8ddca9ee380ef7e0!8m2!3d48.8583701!4d2.2944813!16zL20vMDJqODE"
    ],
    "maxReviewsPerPlace": 20,
    "sort": "newest",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("quarra/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 = {
    "places": ["https://www.google.com/maps/place/Eiffel+Tower/@48.8583701,2.2944813,17z/data=!3m1!4b1!4m6!3m5!1s0x47e66e2964e34e2d:0x8ddca9ee380ef7e0!8m2!3d48.8583701!4d2.2944813!16zL20vMDJqODE"],
    "maxReviewsPerPlace": 20,
    "sort": "newest",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("quarra/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 '{
  "places": [
    "https://www.google.com/maps/place/Eiffel+Tower/@48.8583701,2.2944813,17z/data=!3m1!4b1!4m6!3m5!1s0x47e66e2964e34e2d:0x8ddca9ee380ef7e0!8m2!3d48.8583701!4d2.2944813!16zL20vMDJqODE"
  ],
  "maxReviewsPerPlace": 20,
  "sort": "newest",
  "language": "en"
}' |
apify call quarra/google-maps-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,quarra/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/CmrmCSgL2U8rf7cdi/builds/g1syooJwhBdgaUtm8/openapi.json
