# Zomato Reviews Scraper (`maximedupre/zomato-reviews`) Actor

Collect public Zomato restaurant reviews from the URLs you choose. Get full review text, ratings, reviewer details, and available comments and management replies for feedback research.

- **URL**: https://apify.com/maximedupre/zomato-reviews.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Business, Travel, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.60 / 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

### 🍽️ Read Zomato restaurant feedback in one dataset

Restaurant teams and researchers can collect public Zomato reviews from restaurant URLs. Get full review text, ratings, and available reviewer details, comments, and management replies to study customer feedback without copying each review by hand.

**Use cases**

- Gather feedback for a restaurant with **[Zomato Reviews](https://apify.com/maximedupre/zomato-reviews/examples/zomato-reviews)**.
- Build a review dataset with **[Zomato Reviews Scraper](https://apify.com/maximedupre/zomato-reviews/examples/zomato-reviews-scraper)**.
- Read customer feedback across venues with **[Zomato Restaurant Reviews](https://apify.com/maximedupre/zomato-reviews/examples/zomato-restaurant-reviews)**.
- Keep review text and source links together with **[Zomato Review Scraper](https://apify.com/maximedupre/zomato-reviews/examples/zomato-review-scraper)**.
- Prepare feedback for your own analysis with **[Restaurant Reviews](https://apify.com/maximedupre/zomato-reviews/examples/restaurant-reviews)**.

#### 📄 Zomato review text and source details

Each saved row is one public restaurant review. It includes full text and a restaurant link. Other fields appear when Zomato provides them, such as ratings, posting times, dining or delivery labels, reviewer profiles, likes, tags, photo links, comments, and management replies.

The Actor returns source data. It does not calculate sentiment scores or restaurant summaries, and it does not download photos.

#### ▶️ Collect reviews from your restaurant URLs

1. Add one or more Zomato restaurant or review-page URLs.
2. Set a review limit per restaurant, or leave it empty to collect all available reviews until the source is exhausted.
3. Start the run and open **Restaurant reviews** in the output.

If one restaurant is unavailable, the run continues with the other URLs. Public access and available review counts can vary by restaurant.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `startUrls` | array of objects | Required list of Zomato restaurant or review-page URLs. Each object has a `url` value. |
| `maxReviewsPerRestaurant` | integer | Optional positive review limit for each restaurant. Leave it empty to return all available reviews until the source is exhausted. The source may provide fewer reviews than requested. |

**Successful default input**

This public input is copied from the successful hosted default-input run.

```json
{
  "startUrls": [
    {
      "url": "https://www.zomato.com/bangalore/meghana-foods-jayanagar"
    }
  ],
  "maxReviewsPerRestaurant": 10
}
```

#### 🧾 Output

**Dataset link**

| Field | Type | What it does |
| --- | --- | --- |
| `reviews` | string | Link to the collected restaurant reviews in a table. |

**Review fields**

Only `restaurantUrl` and `text` are required. Other fields may be absent when the source does not provide them.

| Field | Type | What it does |
| --- | --- | --- |
| `reviewId` | string | Source ID for matching the review across runs. |
| `reviewUrl` | string | Source link to the review. |
| `restaurantUrl` | string | Source link to the restaurant. |
| `restaurantId` | string | Source ID for grouping reviews from the same restaurant. |
| `restaurantName` | string | Restaurant name shown by Zomato. |
| `text` | string | Full review text shown by the source. |
| `rating` | number | Source-reported review rating. |
| `postedTime` | string | Posting date or relative time shown by the source. |
| `experience` | string | Dining or delivery category shown for the review. |
| `reviewer` | object | Public reviewer details. |
| `reviewer.id` | string | Source ID for the reviewer. |
| `reviewer.name` | string | Reviewer name. |
| `reviewer.profileUrl` | string | Source link to the reviewer profile. |
| `reviewer.imageUrl` | string | Source link to the reviewer image. |
| `reviewer.reviewCount` | integer | Review total reported for the reviewer. |
| `reviewer.followerCount` | integer | Follower total reported for the reviewer. |
| `likeCount` | integer | Review like total reported by the source. |
| `commentCount` | integer | Comment total reported by the source, which may include comments not returned here. |
| `tags` | array of strings | Review tags shown by the source. |
| `photoUrls` | array of strings | Source links to attached review photos. |
| `comments` | array of objects | Available public comments. |
| `comments[].id` | string | Source ID for a comment. |
| `comments[].text` | string | Full comment text. |
| `comments[].postedTime` | string | Comment posting date or relative time. |
| `comments[].author` | object | Public comment author details. |
| `comments[].author.id` | string | Source ID for the comment author. |
| `comments[].author.name` | string | Comment author name. |
| `comments[].author.profileUrl` | string | Source link to the comment author profile. |
| `managementResponses` | array of objects | Available public restaurant management replies. |
| `managementResponses[].text` | string | Full reply text. |
| `managementResponses[].postedTime` | string | Reply posting date or relative time. |
| `managementResponses[].authorName` | string | Name shown for the person or restaurant replying. |
| `externalReferences` | array of objects | External references attached to the review by the source. |
| `externalReferences[].url` | string | Source link to the external reference. |
| `externalReferences[].title` | string | Reference title shown by the source. |

**Example review**

This complete row is copied from a successful run on the current beta build. Source text may contain HTML tags.

```json
{
  "reviewId": "37792563",
  "reviewUrl": "https://www.zoma.to/vpmnke",
  "restaurantUrl": "https://www.zomato.com/ahmedabad/behrouz-biryani-vejalpur",
  "restaurantId": "18371311",
  "restaurantName": "Behrouz Biryani",
  "text": "Biryani is An Emotion<br/>Behrouz serves one of the Finest Biryani made with all the Amazing spices which makes you Drool while opening.××××××××××××××××××××××××××××××××××××××××××××××<br/>                    <br/>I ordered Dum Gosht Biryani (Boneless)<br/>Read The Full Review On My Blog :)",
  "rating": 4,
  "postedTime": "Jul 24, 2018",
  "experience": "dining",
  "reviewer": {
    "id": "48022357",
    "name": "Durgam",
    "profileUrl": "https://www.zomato.com/RuthwikKumar",
    "imageUrl": "https://b.zmtcdn.com/data/user_profile_pictures/927/3e91d5cfb17c1fa75dcb4f736358d927.jpg?fit=around%7C100%3A100&crop=100%3A100%3B%2A%2C%2A",
    "reviewCount": 0,
    "followerCount": 2890
  },
  "likeCount": 4,
  "commentCount": 1,
  "tags": [],
  "photoUrls": [],
  "comments": [],
  "managementResponses": [
    {
      "text": "We hereby declare you as an official dweller of The kingdom of Behrouz!! (AA)",
      "postedTime": "Aug 26, 2020",
      "authorName": "Behrouz Biryani"
    }
  ],
  "externalReferences": [
    {
      "url": "https://www.zomato.com/spoonback?u=https%3A%2F%2Fnomnomfoodieinzo.wordpress.com%2F2018%2F07%2F24%2Fbehrouz-biryani%2F&r=37792563&to=48022357&k=08b63067f41044368e324d3b565a1622",
      "title": "Read full post on https://nomnomfoodieinzo.wordpress.com/2018/07/24/behrouz-biryani/"
    }
  ]
}
```

#### 💳 Pricing

One review event is charged for each public restaurant review with full text saved to your dataset. The current event price appears in the pricing panel. A run with no saved reviews does not trigger this event.

#### 🔌 Integrations

Open the review dataset in Apify, export it as JSON or CSV, or read its rows through the Apify dataset API for your own analysis.

https://www.youtube.com/watch?v=bNACk1_S_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens if one restaurant is unavailable?

The run continues with the other restaurant URLs. Access to every review or a full review history is not guaranteed.

##### Why can the comment total be larger than the comments array?

The source may report comments that are not publicly returned. The row keeps the source total and the available public comments.

##### Can I collect all available reviews?

Yes. Leave the review limit empty to collect all available reviews until the source is exhausted. A number sets a separate limit for each restaurant.

##### Does it find restaurants by city or keyword?

No. Add the restaurant or review-page URLs you want to read.

##### Does it score the feedback or download photos?

No. It returns source review data for your own analysis. Photos are returned as links when available.

### 📝 Changelog

**v0.0** (04-10-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~zomato-reviews/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- **[Yelp Business Review Scraper](https://apify.com/maximedupre/yelp-business-reviews)**: Collect full-text Yelp reviews for restaurant feedback research.
- **[Yelp Scraper: Review Reputation Monitor](https://apify.com/maximedupre/yelp-reputation-monitor)**: Track review themes and changes across Yelp businesses.
- **[Swiggy Dineout Restaurants Scraper](https://apify.com/maximedupre/dineout)**: Find restaurant listings, ratings, prices, and dining offers by location.
- **[OpenTable + Resy Scraper](https://apify.com/maximedupre/opentable-resy-scraper)**: Collect restaurant profiles, cuisines, ratings, and prices from two dining platforms.
- **[Google Maps Shared List Scraper](https://apify.com/maximedupre/google-maps-shared-list-scraper)**: Export saved restaurant lists with place details and ratings.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

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

Add one or more Zomato restaurant or review-page URLs to collect their public reviews.

## `maxReviewsPerRestaurant` (type: `integer`):

Stop after this many reviews from each restaurant. Leave blank to collect all available reviews until the source is exhausted. The source may provide fewer reviews than requested.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.zomato.com/bangalore/meghana-foods-jayanagar"
    }
  ],
  "maxReviewsPerRestaurant": 10
}
```

# Actor output Schema

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

Open the collected reviews in a table.

# 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.zomato.com/bangalore/meghana-foods-jayanagar"
        }
    ],
    "maxReviewsPerRestaurant": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/zomato-reviews").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.zomato.com/bangalore/meghana-foods-jayanagar" }],
    "maxReviewsPerRestaurant": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/zomato-reviews").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.zomato.com/bangalore/meghana-foods-jayanagar"
    }
  ],
  "maxReviewsPerRestaurant": 10
}' |
apify call maximedupre/zomato-reviews --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/zomato-reviews"
        }
    }
}
```

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/cmCPgabItkm2Xxde7/builds/kZHgMQHnULqfYue7o/openapi.json
