# Restaurant Review Analyzer – Google Maps Complaints AI (`nebulosa/restaurant-review-insights`) Actor

Turn Google Maps reviews into complaint analytics: each review tagged by issue (service, wait time, food, price, cleanliness, allergens, staff, noise, booking) with sentiment and severity, plus a summary of top issues with example quotes.

- **URL**: https://apify.com/nebulosa/restaurant-review-insights.md
- **Developed by:** [Nebulosa Data](https://apify.com/nebulosa) (community)
- **Categories:** AI, Travel, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 results

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

## Restaurant Review Analyzer – Google Maps Complaints AI

Give this actor a restaurant’s Google Maps reviews (a reviews dataset ID from a Google Maps reviews scraper, JSON items or pasted text) and it tags every review by issue (service, wait time, food, price, cleanliness, allergens, staff, noise, booking) with sentiment and severity. The summary ranks the top complaints with real example quotes, so an owner or agency sees what to fix first.

**Find out exactly why guests leave bad reviews.** This Actor takes Google Maps reviews (for example the output of the popular *Google Maps Reviews Scraper*) and tags every review with complaint types, **sentiment** and **severity**, then writes a **summary record** with the top issues, their share and real example quotes.

Built for restaurant owners, multi-location groups, hospitality consultants, agencies and review-management tools.

### What it detects

| Issue | Examples |
|---|---|
| Service | forgotten orders, inattentive service |
| Wait time | "waited 45 minutes", slow kitchen |
| Food quality | cold, bland, undercooked dishes |
| Price / value | overpriced, small portions, bill errors |
| Cleanliness | dirty toilets, sticky tables |
| Allergens / dietary | gluten, vegan, allergy mistakes |
| Staff attitude | rude or unfriendly staff |
| Noise / atmosphere | loud music, can't talk |
| Booking / reservations | lost reservations, no table |

Severity: `none`, `low`, `medium`, `high`, `critical` (health, safety or allergen incidents). Works on reviews in any language. AI classification uses TypeSafe Jev; a multilingual keyword engine (EN/ES/FR/DE/IT/PT/PL) is the fallback.

### Input

- **Reviews dataset ID**: paste the dataset ID from a Google Maps reviews scraper run. Fields used: `text`, `textTranslated`, `stars`, `title`, `placeId`, `reviewId`, `reviewUrl`, `publishedAtDate`.
- **Review items (JSON)**: the same items pasted directly.
- **Pasted reviews**: plain texts, one per line.
- Run with empty input to see a demo on sample reviews.

AI classification with the built-in key is capped at 300 reviews per run (the rest use keyword rules). Add your own TypeSafe API key to lift the cap and skip the AI fee.

### Output

One record per review:

```json
{"type":"review","placeName":"Demo Tapas Bar","stars":1,"sentiment":"negative","severity":"critical",
 "issues":["service","allergens_dietary","staff"],"issueProbabilities":{"allergens_dietary":0.97,"...":0},
 "text":"Pedí sin gluten y me trajeron croquetas normales...","method":"ai"}
```

Plus one `summary` record (also in the key-value store as `SUMMARY`): total reviews, average stars, sentiment and severity counts, and `topIssues` with `count`, `sharePct`, `shareOfNegativePct`, `criticalCount` and example quotes.

### Use cases

- Monthly review report for a restaurant or chain
- Benchmark competitors' weak spots before opening
- Feed a dashboard or alert on new critical (allergen, hygiene) reviews

### Pricing

**$20 per 1,000 reviews** classified (pay-per-event, from 4 Nov 2026), plus a tiny per-run start fee.

### FAQ

**Does it scrape Google?** No. It only analyses reviews you provide or that another Actor already collected.
**Is it accurate?** AI tags come with per-issue probabilities so you can set your own threshold. Check a sample for your use case.

### More questions

**Where do the reviews come from?**
Pass the dataset of any Google Maps reviews scraper run (e.g. compass/google-maps-reviews-scraper), JSON items or pasted texts.

**Which languages?**
AI handles any language; the keyword fallback covers EN/ES/FR/DE/IT/PT/PL.

**Need a per-place summary with reply drafts instead?**
Use Google Maps Review Insights (nebulosa/google-maps-review-insights).

### Pairs with

- [google-maps-review-insights](https://apify.com/nebulosa/google-maps-review-insights)
- [osm-business-leads](https://apify.com/nebulosa/osm-business-leads)
- [menu-allergen-translator](https://apify.com/nebulosa/menu-allergen-translator)

### Reports from Revunda

Prefer a finished document for a restaurant owner? [Revunda Google profile audit](https://revunda.xyz/local/) gives a PDF with 10 fixes ranked by impact (free sample report on the page). Free: [AI visibility check for restaurants](https://revunda.xyz/ai/).

### More questions (FAQ)

#### How do I analyze my restaurant’s Google reviews?

Scrape the reviews with a Google Maps reviews scraper (e.g. compass/google-maps-reviews-scraper), pass the dataset ID here, and open the summary for the ranked issues. To fetch reviews from a place URL in one step, use nebulosa/google-maps-review-insights.

#### Does it work in Spanish and other languages?

Yes, reviews in any common language are classified.

#### Can I analyze only negative reviews?

Yes. Turn on "Only reviews with 1-3 stars".

# Actor input Schema

## `datasetId` (type: `string`):

Dataset ID from a Google Maps reviews scraper run (e.g. compass/google-maps-reviews-scraper). Fields used: text, textTranslated, stars, name, publishedAtDate, reviewUrl, title, placeId, reviewId.

## `reviews` (type: `array`):

Items in the Google Maps reviews scraper format, e.g. \[{"text":"...","stars":2,"title":"Bar X"}].

## `reviewTexts` (type: `array`):

Plain review texts, one per line.

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

Max reviews to analyse.

## `onlyNegative` (type: `boolean`):

Skip 4-5 star reviews (text-only reviews are kept).

## `useAi` (type: `boolean`):

Uses AI for issue tags, sentiment and severity. Falls back to multilingual keyword rules if off or unavailable.

## `typesafeApiKey` (type: `string`):

With your own key there is no AI fee and no 300-review cap.

## `maxAiCalls` (type: `integer`):

Built-in key is capped at 300 per run; the rest use keyword rules.

## `examplesPerIssue` (type: `integer`):

Quotes in the summary record.

## Actor input object example

```json
{
  "reviewTexts": [
    "We waited 45 minutes for our mains and the food arrived cold.",
    "Great tapas and friendly staff, will come back!",
    "Pedí sin gluten y me trajeron pan normal, nadie sabía qué alérgenos tenía el plato.",
    "Too noisy and overpriced for the portion size."
  ],
  "maxReviews": 500,
  "onlyNegative": false,
  "useAi": true,
  "maxAiCalls": 300,
  "examplesPerIssue": 3
}
```

# Actor output Schema

## `results` (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 = {
    "reviewTexts": [
        "We waited 45 minutes for our mains and the food arrived cold.",
        "Great tapas and friendly staff, will come back!",
        "Pedí sin gluten y me trajeron pan normal, nadie sabía qué alérgenos tenía el plato.",
        "Too noisy and overpriced for the portion size."
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nebulosa/restaurant-review-insights").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 = { "reviewTexts": [
        "We waited 45 minutes for our mains and the food arrived cold.",
        "Great tapas and friendly staff, will come back!",
        "Pedí sin gluten y me trajeron pan normal, nadie sabía qué alérgenos tenía el plato.",
        "Too noisy and overpriced for the portion size.",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("nebulosa/restaurant-review-insights").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 '{
  "reviewTexts": [
    "We waited 45 minutes for our mains and the food arrived cold.",
    "Great tapas and friendly staff, will come back!",
    "Pedí sin gluten y me trajeron pan normal, nadie sabía qué alérgenos tenía el plato.",
    "Too noisy and overpriced for the portion size."
  ]
}' |
apify call nebulosa/restaurant-review-insights --silent --output-dataset

```

## MCP server setup

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

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/OYQmJcczFsUcJIHe4/builds/TeAdfPZ5teocUPjzo/openapi.json
