# AI-Enhanced Google Maps Reviews (`rainminer/google-maps-place-reviews-scraper`) Actor

\[$0.29/1k] Need more than raw Google Maps reviews? Try this high-performance Google Maps scraper to get place details and reviews, along with AI-generated review themes, and draft responses matching the place owner's writing style.

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

## Pricing

from $0.19 / 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

[![Google Maps place details and reviews](https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/BNQWWUJ8lcaBhP8HG-actor-IokQjMl8tufxrsD1W-TnVajsWdeD-4010e8a192d882bfbf48e9c6a3a510f1.jpg)](https://console.apify.com/actors/qHNfVQ2GRUATtOY6d)

## Google Maps Reviews & AI Insights Scraper

**Google Maps Reviews & AI Insights Scraper** is a Google Maps API alternative for **place details**, **newest-first reviews**, and two AI add-ons Compass does not ship. Paste a Maps URL or Place ID and export name, address, phone, rating, star histogram, exact review timestamps, and owner replies — then optionally add **AI themes with evidence quotes** and **draft owner replies** written in the same style as that listing's last 5 owner responses.

You pick which unanswered ratings get a draft: negative (1–2★), negative & neutral (1–3★), neutral (3★), positive & neutral (3–5★), or positive (4–5★). **$0.29 per 1,000 reviews** on the Free plan (Compass is **$0.60/1K**). Each AI add-on is a separate per-place event. No Google account, no official API key.

***

### What does Google Maps Reviews & AI Insights Scraper do?

This Actor scrapes **public Google Maps listings** you already know. It does not search a city or keyword — you bring the places, it returns structured details, reviews, and optional AI insights.

Give it:

- Google Maps **place URLs** (`/maps/place`, `/maps/search`, `cid` links, short links)
- or Google **Place IDs** (`ChIJ…`)

Get back one dataset row per place: contact fields, coordinates, opening hours, rating, review count, **1–5 star histogram**, a nested `reviews` array sorted **newest first** with exact `publishedAtDate` values, an **unanswered count** for the star band you pick, and — when the add-ons are on — `reviewThemes` and/or `draftReplies`.

Set **Stop after this review date** (`90 days`, `2025-01-01`, or an ISO timestamp) to cut the feed as soon as older reviews appear. That is the incremental-sync path for reputation products.

***

### What can this Google Maps reviews scraper do?

- Extract **place details**: name, address parts, phone, website, categories, coordinates, hours, claim/closed flags, photos
- Extract **newest Google reviews** with text, stars, exact publish time, likes, photos, reviewer profile fields, and owner replies
- Flag **unanswered reviews** in the star band you pick (`needsOwnerReply`, `unansweredReviewCount`) with no extra model call
- **AI themes** add-on: recurring topics with evidence quotes, top praise, and complaints
- **Draft owner replies** add-on: paste-ready replies in the listing's own voice (last 5 owner responses) for the ratings you choose
- **Stop at a date** (absolute or relative) so nightly runs only collect what is new
- Accept **Place IDs or Maps URLs** — same contract teams already send to Compass
- Run **details-only** (`maxReviews: 0`) when you need histogram and contact fields without review text
- Export **JSON, CSV, Excel, XML, or HTML** and schedule via the Apify API

***

### Why scrape Google Maps place details and reviews?

Public Maps listings are the default source for local reputation and store-locator enrichment. Typical jobs:

1. **Reputation monitoring** — pull last night's reviews for a fixed venue list
2. **Incremental sync** — `reviewsStartDate: "8 days"` instead of re-reading the full history
3. **Lead enrichment** — attach phone, address, rating, and histogram to known Place IDs
4. **Competitive research** — compare star mix and recent comments across nearby businesses
5. **Hotel guest feedback** — newest-first reviews for hospitality ops
6. **Restaurant quality tracking** — watch 1–2 star spikes after a menu or staff change
7. **Agency client reporting** — weekly review velocity and owner-reply coverage
8. **Store locator enrichment** — rating, hours, and photos on a location directory
9. **Review-velocity trends** — count new reviews per week without a Google API quota
10. **Owner-reply SLA** — count unanswered 1–3 star reviews and generate draft replies
11. **Theme mining** — recurring praise and complaints with quotes you can show a client
12. **Reply-queue automation** — push `suggestedReplies` into a helpdesk or Sheets column
13. **Local SEO audits** — categories, claim status, and public review volume
14. **Market-entry research** — recent visitor language for a shortlist of sites

***

### How to scrape Google Maps reviews

1. Open this Actor in [Apify Console](https://console.apify.com/actors/qHNfVQ2GRUATtOY6d).
2. Add Google Maps **place URLs** and/or **Place IDs**.
3. Set **Max reviews per place** (or `0` for details only).
4. Optionally set **Stop after this review date** (`30 days` or `2025-06-01`).
5. Keep **Newest** sort when you use a date cutoff.
6. Optionally turn on **AI themes** and/or **Draft owner replies** (off unless you set the flags via API).
7. If drafts are on, pick **Draft replies for these ratings** (3★ = neutral).
8. Run and download the dataset.

`maxReviews` applies **per place**. Ten places at `maxReviews: 20` return up to 200 reviews.

***

### How much does it cost to scrape Google Maps reviews?

Pay per event. We absorb platform usage — the prices below are what you pay.

| Event | Free | What you get |
| --- | --- | --- |
| **Review scraped** | **$0.29 / 1,000 reviews** | One Google review (text, stars, exact date, owner reply) |
| **Place details** | **$0.49 / 1,000 places** | One listing (contact, rating, histogram, hours) |
| **AI review themes** | **$5.00 / 1,000 places** | Themes, evidence quotes, praise/complaints for that place |
| **Draft owner replies** | **$5.00 / 1,000 places** | Style-matched drafts for unanswered reviews in your star band |
| Actor start | $0.00005 / GB | Standard Apify start fee |

**Vs Compass (Free tier, September 2026):** Compass Google Maps Reviews Scraper charges **$0.60/1K reviews** and returns a raw dump — no themes, no unanswered queue, no reply drafts. Compass Google Maps Scraper charges **$4.00/1K places** plus **$0.50/1K reviews** as an add-on; its paid “competitor AI analysis” compares businesses, it does not draft owner replies in the listing's voice. This Actor is the place-ID + newest + date-cutoff job **plus** two optional AI add-ons.

Example: 1,000 new reviews across 20 places with both add-ons ≈ **$0.30** in review fees + **$0.01** in place fees + **$0.20** in AI add-ons.

Higher Apify Store plans pay less per review (down to **$0.19/1K** on Gold).

***

### Input

```json
{
  "startUrls": [
    {
      "url": "https://www.google.com/maps/search/?api=1&query=Dumpling%20House&query_place_id=ChIJD2l2k7ZL0YkRC80d-3MV1lM"
    }
  ],
  "placeIds": ["ChIJD2l2k7ZL0YkRC80d-3MV1lM"],
  "maxReviews": 5,
  "reviewsStartDate": "3 months",
  "reviewsSort": "newest",
  "includeReviewThemes": true,
  "includeDraftReplies": true,
  "draftReplyRatings": "negativeAndNeutral",
  "language": "en"
}
```

**Provide at least one place URL or Place ID.**

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `startUrls` | Array of `{ url }` | — | Google Maps place URLs (`/maps/place`, `/maps/search`, `/maps?cid=`, short links) |
| `placeIds` | Array of strings | — | Google Place IDs (`ChIJ…` / `GhIJ…`) |
| `maxReviews` | Integer | `5` | Max reviews per place. `0` = details only (histogram still included) |
| `reviewsStartDate` | String | — | Stop when a review is older than this. `2024-05-03`, ISO datetime (UTC), or relative (`8 days`, `3 months`) |
| `reviewsSort` | String | `newest` | `newest`, `mostRelevant`, `highestRating`, or `lowestRating` |
| `includeReviewThemes` | Boolean | `false` | AI themes add-on. Console try-for-free prefills this on. |
| `includeDraftReplies` | Boolean | `false` | Draft owner replies add-on, styled like the listing's last 5 owner responses. |
| `draftReplyRatings` | String | `negativeAndNeutral` | Unanswered ratings to draft: `negative`, `negativeAndNeutral`, `neutral`, `positiveAndNeutral`, `positive`. 3★ = neutral. |
| `language` | String | `en` | Google Maps UI language — affects relative dates and opening-hours labels |
| `proxyConfiguration` | Object | Apify Proxy | Recommended on the platform; switch to residential groups if you hit blocks |

The date cutoff needs the default `newest` sort: the Actor walks newest → oldest and stops at the first review older than `reviewsStartDate`.

***

### Output

Each dataset item is **one place**, with reviews nested on the same row (the shape reputation products already consume).

```json
{
  "name": "OG Dumpling House",
  "title": "OG Dumpling House",
  "address": "410 Jefferson Rd, Rochester, NY 14623, United States",
  "street": "410 Jefferson Rd",
  "city": "Rochester",
  "postalCode": "14623",
  "state": "NY",
  "countryCode": "US",
  "website": "http://ogdumplinghouseny.com/",
  "phone": "+1 585-413-0353",
  "phoneUnformatted": "+15854130353",
  "categoryName": "Dumpling restaurant",
  "categories": ["Dumpling restaurant", "Chinese restaurant"],
  "location": { "lat": 43.0903574, "lng": -77.6429184 },
  "openingHours": [{ "day": "Wednesday", "hours": "11 AM–9 PM" }],
  "totalScore": 4.5,
  "reviewsCount": 1255,
  "reviewsDistribution": {
    "oneStar": 52,
    "twoStar": 22,
    "threeStar": 66,
    "fourStar": 180,
    "fiveStar": 935
  },
  "placeId": "ChIJD2l2k7ZL0YkRC80d-3MV1lM",
  "url": "https://www.google.com/maps/search/?api=1&query_place_id=ChIJD2l2k7ZL0YkRC80d-3MV1lM",
  "imageUrl": "https://lh3.googleusercontent.com/gps-cs-s/...",
  "reviewsScrapedCount": 1,
  "unansweredReviewCount": 0,
  "reviewThemes": {
    "summary": "Guests praise fast service and dumplings; a few mention weekend waits.",
    "themes": [
      {
        "name": "Speed of service",
        "sentiment": "positive",
        "mentionCount": 4,
        "evidenceQuotes": ["fast service and delicious food!"]
      }
    ],
    "topPraise": ["Fast service", "Dumplings"],
    "topComplaints": [],
    "reviewsAnalyzed": 5
  },
  "draftReplies": [],
  "reviews": [
    {
      "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT25SVWIzWjVhR1p1TW5WVGJucE9jblJXVFRCSlZIYxAB",
      "name": "Jeffrey Brewster",
      "text": "fast service and delicious food!",
      "publishAt": "a day ago",
      "publishedAtDate": "2026-08-31T22:20:38.429Z",
      "stars": 5,
      "rating": 5,
      "likesCount": 0,
      "reviewUrl": "https://www.google.com/maps/reviews/data=...",
      "reviewerId": "106919063158098904284",
      "isLocalGuide": false,
      "responseFromOwnerDate": "2026-09-01T21:07:13.000Z",
      "responseFromOwnerText": "Thank you so much, Jeffrey!",
      "needsOwnerReply": false
    }
  ]
}
```

| Field | Description |
| --- | --- |
| `title` / `name` | Business name (both aliases are always set) |
| `address` | Formatted address, split into `street`, `city`, `postalCode`, `state`, `countryCode` |
| `phone` / `phoneUnformatted` | Public phone when listed |
| `openingHours` | Day and hours pairs as shown on the listing |
| `totalScore` | Average rating |
| `reviewsCount` | Number of Google reviews on the listing |
| `reviewsDistribution` | Star histogram (`oneStar` … `fiveStar`) |
| `placeId` | Google Place ID |
| `imageUrl` / `imageUrls` | Primary listing photo and gallery |
| `reviewsScrapedCount` | How many reviews this run returned for the place |
| `unansweredReviewCount` | Scraped reviews in your star band with no owner reply (always computed, no AI) |
| `reviewThemes` | AI themes add-on output. `null` when that add-on is off or the model call is skipped |
| `draftReplies` | Draft owner replies add-on output. `null` when that add-on is off; `[]` when it ran but nothing matched |
| `draftReplyStyleExamples` | The 5 most recent owner replies used as the voice to copy. `null` when drafts are off |
| `reviews` | Newest-first review objects with text, stars, exact dates, IDs, links, public reviewer fields, likes, photos, owner responses, and `needsOwnerReply` |

The run **Output** tab has two views: **Overview** (one row per place) and **Reviews** (one row per review: stars, text, date, owner reply, reviewer). You can also download JSON, CSV, Excel, XML, or HTML from **Storage**.

***

### Does this search Google Maps by keyword?

No. It only scrapes the places you pass as URLs or Place IDs, which keeps runs cheap and predictable. For keyword or area search, use a dedicated Google Maps search Actor, then feed those Place IDs here.

Related rainminer Actors:

- [Google Maps Menu Scraper](https://apify.com/rainminer/google-maps-menu-scraper) — menu items and prices from listing photos
- [Google Maps Review Summary Scraper](https://apify.com/rainminer/google-maps-review-summary-scraper) — Google's own short review-summary text on the listing (not themes or reply drafts)

***

### FAQ

#### Do I get exact review dates?

Yes. Every review has `publishedAtDate` as an exact ISO timestamp, alongside Google's relative `publishAt` label ("a day ago"). The exact timestamp is what makes the date cutoff and incremental runs work.

#### How many reviews can I get per place?

The feed paginates until Google stops returning pages, so several hundred per place is normal. Set `maxReviews` to the number you need — very large values simply run longer. Combine with `reviewsStartDate` for cheap nightly syncs.

#### How is this different from Compass Google Maps Reviews Scraper?

Compass returns the raw review dump. This Actor matches that place-ID + newest + date-cutoff job, then adds two optional add-ons: AI themes with evidence quotes, and draft owner replies written like the listing's last 5 responses for the star band you pick (3★ = neutral). Existing Compass-shaped integrations that omit the flags keep the same fields and cost.

#### Do I need a Google API key or login?

No. This Actor reads **public** Maps listing and review pages. There is no Google Cloud key, OAuth, or end-user login.

#### Do I need a proxy?

Google throttles heavy traffic from single IP ranges. Apify Proxy is enabled by default; if you scrape many places or see repeated empty responses, switch the proxy configuration to residential groups.

#### Is it legal to scrape Google Maps?

This Actor collects **public** listing and review information, including public reviewer names and profile fields. Do not process personal data unless you have a legitimate reason. GDPR and similar laws may apply. If you are unsure, consult a lawyer. See also [Apify's guidance on scraping](https://blog.apify.com/is-web-scraping-legal/).

#### Where can I get help?

Open an issue on this Actor's **Issues** tab in Apify Console.

***

### Image Credit

Image credit: [Google Maps](https://www.google.com/maps)

# Actor input Schema

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

Place page URLs. Valid URLs contain google.com/maps/ (place, search, or reviews). Also supports google.com/maps?cid= and goo.gl/maps short links.

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

Google Place IDs (ChIJ… / GhIJ…). Used together with start URLs.

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

Maximum number of reviews to collect per place. Set to 0 to skip reviews and only return place details (name, address, phone, rating, review count, star histogram). Use a large number (e.g. 99999) to collect all reviews until the stop date or Google's limit.

## `reviewsStartDate` (type: `string`):

Stop collecting reviews once one is older than this cutoff. Absolute dates (2024-05-03 or 2024-05-03T20:00:00 UTC) or relative windows (8 days, 3 months, 1 year). Leave empty to keep going until maxReviews. Works with the default newest → oldest sort.

## `reviewsSort` (type: `string`):

Order Google returns reviews in. Keep newest for incremental scraping and date cutoffs.

## `includeReviewThemes` (type: `boolean`):

One AI pass per place: recurring themes with evidence quotes, plus top praise and complaints. Off by default for API callers. Console try-for-free has this on.

## `includeDraftReplies` (type: `boolean`):

One AI pass per place: paste-ready owner replies for unanswered reviews in the star band you pick. Drafts copy the style of the 5 most recent owner responses on that listing. Off by default for API callers. Console try-for-free has this on.

## `draftReplyRatings` (type: `string`):

Which unanswered reviews get a draft. 1–2 stars = negative, 3 stars = neutral, 4–5 stars = positive. Only used when Draft owner replies is on.

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

Google Maps interface language (ISO 639-1), e.g. en, es, de, fr, ja. Affects relative review dates and opening-hours labels.

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

Google rate-limits datacenter IP ranges, so Apify Proxy is recommended on the platform. Switch to residential groups if you see repeated empty responses.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.google.com/maps/search/?api=1&query=Dumpling%20House&query_place_id=ChIJD2l2k7ZL0YkRC80d-3MV1lM"
    }
  ],
  "maxReviews": 5,
  "reviewsSort": "newest",
  "includeReviewThemes": true,
  "includeDraftReplies": true,
  "draftReplyRatings": "negativeAndNeutral",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `reviews` (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": [
        {
            "url": "https://www.google.com/maps/search/?api=1&query=Dumpling%20House&query_place_id=ChIJD2l2k7ZL0YkRC80d-3MV1lM"
        }
    ],
    "maxReviews": 5,
    "reviewsStartDate": "",
    "reviewsSort": "newest",
    "includeReviewThemes": true,
    "includeDraftReplies": true,
    "draftReplyRatings": "negativeAndNeutral",
    "language": "en",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rainminer/google-maps-place-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": [{ "url": "https://www.google.com/maps/search/?api=1&query=Dumpling%20House&query_place_id=ChIJD2l2k7ZL0YkRC80d-3MV1lM" }],
    "maxReviews": 5,
    "reviewsStartDate": "",
    "reviewsSort": "newest",
    "includeReviewThemes": True,
    "includeDraftReplies": True,
    "draftReplyRatings": "negativeAndNeutral",
    "language": "en",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("rainminer/google-maps-place-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": [
    {
      "url": "https://www.google.com/maps/search/?api=1&query=Dumpling%20House&query_place_id=ChIJD2l2k7ZL0YkRC80d-3MV1lM"
    }
  ],
  "maxReviews": 5,
  "reviewsStartDate": "",
  "reviewsSort": "newest",
  "includeReviewThemes": true,
  "includeDraftReplies": true,
  "draftReplyRatings": "negativeAndNeutral",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call rainminer/google-maps-place-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rainminer/google-maps-place-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/qHNfVQ2GRUATtOY6d/builds/AgrPIPXDOfPUSOhle/openapi.json
