# Google Maps Contributor & Local Guide Reviews Scraper (`steadyscrape/google-maps-contributor-reviews-scraper`) Actor

Scrape every public review a Google Maps contributor (Local Guide) wrote, with the place, stars, text, photos and owner replies, plus their profile: level, points, review, rating and photo counts. Check a business's newest reviewers for fake reviews. Export to JSON, CSV or Excel, or via API.

- **URL**: https://apify.com/steadyscrape/google-maps-contributor-reviews-scraper.md
- **Developed by:** [Steady Scrape](https://apify.com/steadyscrape) (community)
- **Categories:** SEO tools, Marketing, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.

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 Contributor & Local Guide Reviews Scraper

Scrape **every public review a Google Maps contributor has written** — the Local Guide's whole review history across
every place they reviewed — from their **contributor profile link or id**: each review's **stars, text, Google's
translation, photos, dates, owner reply and the reviewed place** (name, address, category, rating, CID, place id,
coordinates), plus the **contributor's profile**: **Local Guide level and points**, and their counts of reviews,
ratings, photos, videos, answers and edits.

Give it a **business** instead and it reads the business's **newest reviewers** and scrapes each of their profiles and
histories: the quickest way to spot **fake Google reviews** — brand-new accounts, one-review profiles, reviewers who
only ever give five stars, or whole review histories in another country. No login, no browser, no Google API key.

### What a Google Maps contributor scrape returns

One `contributor` row per profile, followed by one `review` row per review (newest first):

| Row | Fields |
|---|---|
| `contributor` | `name`, `contributorId`, `profileUrl`, `photoUrl`, `isLocalGuide`, `localGuideLevel`, `localGuidePoints`, `contributions` (reviews, ratings, photos, videos, captions, tips, answers, edits, reportedIncorrect, placesAdded, roadsAdded, qa, tripFeedback, incidentReports), `reviewsListed`, `reviewsReturned`, `historyComplete`, `shortfallReason`, `reviewStats`, `source`, `reviewedBusiness`, `input` |
| `review` | `contributorId`, `contributorName`, `position` (1 = newest), `reviewId`, `reviewUrl`, `stars`, `text`, `language`, `textTranslated`, `publishedAt`, `editedAt`, `relativeDate`, `details` (Food 5, Service 4, Price per person "$20–30", Wait time…), `photoUrls`, `ownerReply` (`text`, `repliedAt`), `placeName`, `placeId`, `cid`, `placeUrl`, `address`, `city`, `category`, `lat`, `lng`, `placeRating`, `placeReviewCount`, `priceRange` |
| `input` (free) | `status` (`contributor_not_found`, `business_not_found`, `no_reviewers`, `invalid`, `blocked`, `spending_limit`), `reason`, `input` |

Star-only ratings (a rating with no text) are included as review rows with `text: null`. A review of a place Google
Maps no longer shows keeps its `cid` and `placeUrl`; its `placeName` and other place fields are `null`.

`reviewStats` summarises the returned reviews for a quick fake-review check: `sampleSize`, `averageStars`,
`fiveStar`, `oneStar`, `withText`, `withPhotos`, `withOwnerReply`, `newestAt`, `oldestAt`, `distinctCities`.

### Use cases for Google Maps reviewer data

- **Report fake reviews**: check who left the newest reviews on your client's (or a competitor's) Google Business
  Profile — one-review accounts, all-five-star histories, a burst of reviews on the same day, reviews in cities the
  reviewer never visits — before you flag them to Google.
- **Reputation management**: export a disgruntled reviewer's public history to see whether they review every place
  they visit the same way.
- **Influencer and Local Guide outreach**: find high-level Local Guides who review your category in your city.
- **Research**: what a set of reviewers rates, where, and how their ratings compare with each place's average.

### Input example

```json
{
    "contributors": [
        "https://www.google.com/maps/contrib/112533194102203327973/reviews",
        "115659172211656792609"
    ],
    "businesses": ["https://www.google.com/maps/place/Franklin+Barbecue/data=!4m2!3m1!1s0x8644b5a4ae3bcc33:0x31aba8abf8f64c84"],
    "maxReviewsPerContributor": 50,
    "reviewersPerBusiness": 5,
    "language": "en",
    "country": "us"
}
```

- **Contributors**: a profile link (`…/maps/contrib/<21 digits>…`, open a reviewer's name on any Google Maps review to
  get it), a `maps.app.goo.gl` share link of the profile, or the 21-digit contributor id.
- **Businesses** (optional): a Google Maps link, place id (`ChIJ…`), CID, or "name, city". Each business gives its
  newest reviewers (up to 5, the ones Google Maps shows first); the business itself is free.
- **maxReviewsPerContributor**: 0–200 (default 200). 0 returns the profile and its counts only.

### Output example (shortened)

```json
[
    {
        "rowType": "contributor",
        "contributorId": "112533194102203327973",
        "name": "三浦祐介",
        "profileUrl": "https://www.google.com/maps/contrib/112533194102203327973",
        "isLocalGuide": true,
        "localGuideLevel": 5,
        "localGuidePoints": 649,
        "contributions": { "reviews": 11, "ratings": 4, "photos": 76, "videos": 5, "answers": 59, "edits": 1, "…": 0 },
        "reviewsListed": 14,
        "reviewsReturned": 14,
        "historyComplete": true,
        "shortfallReason": null,
        "reviewStats": { "sampleSize": 14, "averageStars": 4.36, "fiveStar": 11, "oneStar": 2, "withText": 10, "withPhotos": 9, "withOwnerReply": 5, "newestAt": "2026-10-19T04:12:55.206Z", "oldestAt": "2022-06-21T13:49:36.479Z", "distinctCities": 14 },
        "source": "contributor",
        "reviewedBusiness": null
    },
    {
        "rowType": "review",
        "contributorName": "三浦祐介",
        "position": 1,
        "stars": 5,
        "text": "オースティンを代表するお店ということで…",
        "language": "ja",
        "textTranslated": "Franklin's is considered one of Austin's most famous restaurants…",
        "publishedAt": "2026-10-19T04:12:55.206Z",
        "editedAt": null,
        "relativeDate": "a week ago",
        "details": [{ "label": "Food", "stars": 5, "answer": null }, { "label": "Wait time", "stars": null, "answer": "10-30 min" }],
        "photoUrls": ["https://lh3.googleusercontent.com/…"],
        "ownerReply": null,
        "placeName": "Franklin Barbecue",
        "placeId": "ChIJM8w7rqS1RIYRhEz2-KuoqzE",
        "cid": "3579139785445756036",
        "address": "900 E 11th St, Austin, TX 78702",
        "city": "Austin",
        "category": "Barbecue restaurant",
        "placeRating": 4.7,
        "placeReviewCount": 7332,
        "priceRange": "$20–70"
    }
]
```

### Full history or not: `historyComplete` and `shortfallReason`

`reviewsListed` is how many reviews and ratings Google lists on the profile; `historyComplete` is true when all of them
were returned. When not, `shortfallReason` says why:

- `max_reviews` — you asked for fewer (`maxReviewsPerContributor`).
- `google_limit` — **this Actor returns at most a contributor's newest 200 reviews** (the most one Google Maps answer
  holds); older reviews of a very active Local Guide are not returned.
- `restricted_profile` — the profile shows its counts but **no reviews to visitors** (the contributor restricted their
  profile, or Google holds the reviews back). The profile row is still returned.
- `spending_limit` — your run's spending limit was reached.

`contributions.reviews` is the profile's own figure ("213 reviews"); it can be a little higher than what Google lists.

### Pricing

Pay per event, no start fee:

| Event | Price |
|---|---|
| `contributor` — one profile with its level, points and contribution counts | **US$0.002** |
| `review` — one review or star-only rating | **US$0.001** |

A contributor with 50 reviews: US$0.052. A business's 5 newest reviewers with 20 reviews each: US$0.11. Free:
contributors or businesses not found, invalid inputs, businesses without reviews, blocked rows, and inputs left out by
your spending limit. The limit is checked before each contributor is read, and reviews are returned only as far as it
pays.

### Stops when Google asks for verification

The Actor reads the same answers Google Maps gives its own web page, at a moderate pace (two requests in flight).
**If Google ever asks for verification** — its "unusual traffic" page, a CAPTCHA, a JavaScript check, or any answer
that is not Google Maps' normal data — **the run stops sending requests**: every input left is a free `blocked` row
that says so, and the run ends normally with a message. It never solves, bypasses or replays a challenge. Plain
overloads (HTTP 429 or 5xx without a challenge) are retried through Apify's datacenter proxy.

### Limits

- Up to 500 contributors and 500 businesses per run; up to the newest 200 reviews per contributor.
- A business gives at most its 5 newest reviewers (Google orders "newest" by last edit).
- No emails, phone numbers or private data exist on a contributor profile, and none are returned.

### Is it legal?

This is an unofficial tool, **not affiliated with, endorsed by or sponsored by Google**. It reads only public
contributions — what Google Maps shows any signed-out visitor on a contributor's public profile — without logging in,
at a pace a person browsing could produce. Reviewer names and reviews are personal data in many jurisdictions (GDPR,
CCPA): use them for a legitimate purpose, keep only what you need, and follow Google's terms and the laws that apply to
you.

# Actor input Schema

## `contributors` (type: `array`):

One per line: a Google Maps <b>contributor profile link</b> (<code>https://www.google.com/maps/contrib/112533194102203327973/reviews</code>, open a reviewer's name on any review to get it), a <code>maps.app.goo.gl</code> share link of the profile, or the <b>21-digit contributor id</b>. Up to 500.

## `businesses` (type: `array`):

One per line: a business's <b>Google Maps link</b>, place id (<code>ChIJ…</code>), CID, or <b>name and city</b> (<code>Franklin Barbecue, Austin TX</code>). The Actor reads the business's newest reviews and scrapes the profile and reviews of each reviewer (up to 5 per business, the ones Google Maps shows first). The business itself is free; each reviewer is charged as a contributor. Up to 500.

## `maxReviewsPerContributor` (type: `integer`):

How many of each contributor's newest reviews (star-only ratings included) to return. This Actor returns at most the newest 200 per contributor. 0 returns the profile and its counts only.

## `reviewersPerBusiness` (type: `integer`):

How many of each business's newest reviewers to scrape (Google Maps shows a business's 5 newest reviews to visitors).

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

Language of place names, categories and Google's review translations, as a code: <code>en</code>, <code>es</code>, <code>de</code>, <code>pt-BR</code>. Reviews keep their own text; <code>textTranslated</code> carries Google's translation into this language when it offers one.

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

Two-letter country code Google answers for (<code>us</code>, <code>gb</code>, <code>au</code>).

## Actor input object example

```json
{
  "contributors": [
    "https://www.google.com/maps/contrib/112533194102203327973/reviews"
  ],
  "maxReviewsPerContributor": 20,
  "reviewersPerBusiness": 5,
  "language": "en",
  "country": "us"
}
```

# Actor output Schema

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

No description

## `reviews` (type: `string`):

No description

## `summary` (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 = {
    "contributors": [
        "https://www.google.com/maps/contrib/112533194102203327973/reviews"
    ],
    "maxReviewsPerContributor": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/google-maps-contributor-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 = {
    "contributors": ["https://www.google.com/maps/contrib/112533194102203327973/reviews"],
    "maxReviewsPerContributor": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/google-maps-contributor-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 '{
  "contributors": [
    "https://www.google.com/maps/contrib/112533194102203327973/reviews"
  ],
  "maxReviewsPerContributor": 20
}' |
apify call steadyscrape/google-maps-contributor-reviews-scraper --silent --output-dataset

```

## MCP server setup

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