# Review & Rating Monitor (`al_mansouri/review-rating-monitor`) Actor

Watch your Google Business locations and get told only when the reputation actually moves — new reviews, how many stars each one was, and whether the average shifted.

- **URL**: https://apify.com/al\_mansouri/review-rating-monitor.md
- **Developed by:** [Hussein Al-Mansori](https://apify.com/al_mansouri) (community)
- **Categories:** SEO tools, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 90.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

## Review & Rating Monitor

**Know the moment a bad review lands on any of your locations.** Free.

Name your Google Business locations, run it on a schedule, and it publishes a row only when the
reputation actually moved — reviews arrived, **how many stars each one was**, or the average
shifted. Nothing happened means nothing in your dataset.

### What makes this different from a review scraper

Every other review Actor on the Store hands you the corpus: five thousand reviews to analyse.
That is a different job. This one tells you **what changed since the last time it looked**, which
is the thing you act on the same day.

And it does it without reading a single review's text. A Google listing publishes its star
breakdown — how many reviews sit at each rating — so subtracting last check's breakdown from this
one says how many reviews arrived *and at what star rating*. One page read, and the row can say
**"two new reviews, one of them 1-star."**

### Who this is for

| You are | What you get |
|---|---|
| **A multi-location business** | One row the moment a 1-star lands, naming which branch |
| **An agency managing reputations** | Every client's locations in one dataset, only the rows that need answering |
| **A franchise operator** | Rating drift per site, before it shows up in the monthly report |

### What you paste in

Google place IDs, or Maps links containing one — paste the link straight from Google Maps and the
Actor lifts the ID out.

```
https://www.google.com/maps/place/?q=place_id:ChIJN1t_tDeuEmsRUsoyG83frY4
ChIJrRxkYy1ZwokRLLYqjMYzOtI
```

Run it on Apify's scheduler — hourly, daily, whatever suits.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `placeIds` | list | — | The locations to watch. Place IDs or Maps links. Required. |
| `onlyReportChanges` | boolean | `true` | Publish a row only when something moved. Turn off to keep a full reputation history. |
| `stateStoreName` | string | `review-monitor-state` | Where the baseline lives. Change it to run two independent watch lists. |
| `language` | string | `en` | Which language to read the listing in. |
| `proxyConfiguration` | object | off | Leave off unless Google starts refusing your runs. |

### What you get back

```json
{
  "event": "reviews-changed",
  "location": { "placeId": "ChIJ…", "address": "7 Carmine St, New York" },
  "rating": 4.6,
  "previousRating": 4.7,
  "ratingChange": -0.1,
  "reviewsCount": 26471,
  "changeKinds": ["reviews-added", "negative-review", "rating-fell"],
  "starChanges": [
    { "stars": "oneStar", "gained": 1, "lost": 0 },
    { "stars": "fiveStar", "gained": 1, "lost": 0 }
  ],
  "reviewsAdded": 2,
  "negativeAdded": 1,
  "previouslyCheckedAt": "2026-08-26T09:00:00Z",
  "status": "verified"
}
```

**`negativeAdded`** is new 1- and 2-star reviews — the number to alert on. **`changeKinds`**
carries `negative-review` as its own value so you can filter a dataset down to the rows that need
answering today, without parsing anything.

Three stars is deliberately not counted as a complaint. It is what people leave when a place was
fine, and alerting on it would make the alerts worth ignoring.

### How honest a row is

| `status` | Meaning |
|---|---|
| `verified` | Read cleanly. Nothing was uncertain. |
| `warning` | Delivered, but something was uncertain — the reason is on the row. |
| `failed` | The location could not be read. No rating is published, and never a stale one. |

Four rules this Actor does not bend:

- **A star breakdown that could not be read is never a star claim.** Some listings do not publish
  one. You get the review count and a warning saying the ratings are unknown — never a guessed
  1-star, which is the alert nobody forgives.
- **A review being deleted is a deletion.** Google removes reviews it judges fake and merchants
  win appeals. That is reported as `reviews-removed`, never folded into arrivals.
- **Someone editing their own review is not a new review.** One star down and four stars up with
  the total unchanged is a re-rating, and it is reported as one.
- **A page that yields nothing at all is a failure, not "no change".** A monitor that silently
  stopped seeing the listing would report calm forever, which is the worst thing it could do.

### Limits

| Limit | Value |
|---|---|
| Locations per run | 200 |
| Time per location | 45 seconds |
| Time per run | 1,800 seconds |
| Smallest rating move reported | 0.05 |
| Reviews in one check before the row is flagged | 50 |

All locations in a run share **one browser**, opened once and reused. That is what makes checking
a long watch list on a schedule affordable.

### What this deliberately does not do

- **No review text.** The star breakdown says how many arrived and at what rating; reading the
  words is a different and far more expensive job. If you need the text, use a review scraper on
  the locations this Actor flags.
- No replying to reviews, and no Google Business account access. Public listing data only.
- No discovery: it watches the locations you name.
- No email or SMS. Use Apify's integrations to route a run's dataset wherever you want it.

### Pricing

**Free.** Only Apify's platform usage applies. Two events are defined — `location-checked` (every
read) and `reviews-changed` (a real move) — and neither is charged today.

They exist so that adding a price later would be a price change and not a redesign.

***

### FAQ

**How does it know what changed?**
It stores each location's rating, review count and star breakdown in a key-value store on *your*
account, and compares the next check against it. Only those numbers — never review text.

**What happens on the first run?**
Every location is a `baseline` row: the starting point, not a change. You are never told a rating
moved on a location the Actor has not seen before.

**Where do I find a place ID?**
You do not need one — paste the location's link from Google Maps and the Actor extracts it.

**Why does a row sometimes say the ratings are unknown?**
Because that listing did not publish its star breakdown. The count is still honest; the stars
would be a guess.

**Can it tell me what the review said?**
No. It tells you one arrived and what it was rated. That is deliberate: it is the part that can be
checked cheaply enough to run on a schedule.

**Will it tell me twice about the same change?**
It can, in one case: if the row is published but the baseline cannot be saved. That is the
deliberate trade — the alternative is losing the alert silently and forever.

***

### Support

Open an issue on the Actor's Apify page. Include the run ID and the place ID.

*Not affiliated with, endorsed by, or sponsored by Google.*

# Actor input Schema

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

Google place IDs, or Google Maps links containing one — paste the link straight from Maps. Up to 200 locations per run.

## `onlyReportChanges` (type: `boolean`):

On by default, which is what a monitor is for. Turn it off to record every check and keep a full reputation history.

## `stateStoreName` (type: `string`):

The named key-value store on your account that remembers each location's last reading. Change it to run two independent watch lists.

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

Which language to read the listing in. Affects how the star breakdown is labelled, not which reviews exist.

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

Proxy used for requests. Leave off unless Google starts refusing the connection from your runs.

## Actor input object example

```json
{
  "placeIds": [
    "ChIJN1t_tDeuEmsRUsoyG83frY4"
  ],
  "onlyReportChanges": true,
  "stateStoreName": "review-monitor-state",
  "language": "en"
}
```

# Actor output Schema

## `changes` (type: `string`):

Every published check, with what moved and what it was before.

## `csv` (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 = {
    "placeIds": [
        "ChIJN1t_tDeuEmsRUsoyG83frY4"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("al_mansouri/review-rating-monitor").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 = { "placeIds": ["ChIJN1t_tDeuEmsRUsoyG83frY4"] }

# Run the Actor and wait for it to finish
run = client.actor("al_mansouri/review-rating-monitor").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 '{
  "placeIds": [
    "ChIJN1t_tDeuEmsRUsoyG83frY4"
  ]
}' |
apify call al_mansouri/review-rating-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,al_mansouri/review-rating-monitor"
        }
    }
}
```

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/jtf6qAUPwJfyqo2UU/builds/pMxqLVt0fP3xk1TBf/openapi.json
