# Booking.com Reviews Scraper & Hotel Reviews API (`zenomastro/booking-reviews-reliable`) Actor

Extract Booking.com hotel reviews with guest scores, positive and negative feedback, traveler type, room and stay details, reviewer country, helpful votes, photos, property replies, filters, retries, deduplication, and spend controls.

- **URL**: https://apify.com/zenomastro/booking-reviews-reliable.md
- **Developed by:** [Rosario Vitale](https://apify.com/zenomastro) (community)
- **Categories:** Travel, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 booking.com 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

## Booking.com Reviews Scraper & Hotel Reviews API

Extract public Booking.com hotel reviews into clean structured data for hospitality analytics, reputation monitoring, competitor research, guest-experience analysis, customer-support workflows, travel research, and AI/LLM pipelines.

The Actor starts a real browser only to initialize the public Booking.com review session for each property, then reuses Booking.com's own review data flow for efficient pagination. This avoids brittle DOM-only scraping while still validating the live hotel page at run time.

### What you get

Successful review rows can include:

- Booking.com review score and review date
- review title, positive text, and negative text
- reviewer display name, country, country code, and traveler label
- Booking traveler/customer type
- room type, check-in, check-out, and number of nights
- helpful-vote count
- public hotel/property reply when available
- public review photos when available
- hotel ID, hotel country code, hotel score, and canonical source URL
- scan/runtime metadata for reproducibility

Optional free hotel-summary rows include the total public review count and aggregate rating, score, language, and traveler-type information returned by Booking.com.

### Input

Provide one or more full Booking.com hotel URLs in `hotelUrls`.

Example:

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/us/ace-new-york.html"
  ],
  "maxReviewsPerHotel": 500,
  "maxTotalReviews": 5000,
  "sortBy": "newest",
  "minScore": 1,
  "maxScore": 10,
  "reviewedAfter": "",
  "reviewedBefore": "",
  "containsText": "",
  "reviewerCountries": [],
  "customerTypes": [],
  "languageCodes": [],
  "minHelpfulVotes": 0,
  "partnerReply": "any",
  "includePhotos": true,
  "includeHotelSummary": true,
  "maxPagesPerHotel": 100,
  "autoProxyFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

### Filters

Filters are applied before paid review rows are emitted. You can combine score range, date range, text substring, reviewer country, traveler/customer type, language, minimum helpful votes, and hotel-reply presence.

Filtered-out source reviews are not billed.

For country filtering, use a Booking country code such as `us`, `gb`, or `it`, or the full country name returned by Booking.com.

Common Booking traveler types include values such as `COUPLES`, `SOLO`, `FAMILY`, `GROUP`, and `BUSINESS`. Availability depends on the source property and review.

### Reliability design

Booking.com changes its web application over time, so the Actor does not hard-code a single hidden token or fixed review payload. It initializes the current hotel page, observes the live public review request generated by Booking.com, and then paginates using that session.

The run also includes:

- strict Booking.com hotel-URL validation
- duplicate hotel removal
- per-hotel review deduplication
- bounded browser and review-request timeouts
- bounded retries
- direct-first mode to avoid unnecessary proxy cost
- optional automatic Apify Proxy fallback if direct access is blocked
- source-page, per-hotel, and global result limits
- diagnostic rows instead of crashing the entire batch when one hotel fails
- maximum-charge handling for pay-per-event runs

### Output row types

#### `review`

A successful, billable Booking.com review.

#### `hotel_summary`

An optional free aggregate row for the property. It can contain total review count, rating categories, score distribution, language breakdown, and traveler-type breakdown.

#### `status`

A free informational row, for example when the selected filters find no matching review inside the configured scan window.

#### `error`

A free diagnostic row for an invalid/unavailable hotel source or another per-hotel failure.

### Pricing

Launch pricing target: **$0.00045 per successfully emitted review**, or about **$0.45 per 1,000 Booking.com reviews**, plus the small Actor-start event shown by Apify.

Only successful `review` rows trigger the review event. Summary, status, error, retries, duplicates, and reviews rejected by filters are free.

### Spend controls

Use `maxReviewsPerHotel`, `maxTotalReviews`, and `maxPagesPerHotel` to bound work and result volume. Apify's maximum-total-charge setting is also respected when the Actor is monetized with pay-per-event pricing.

### Limits and source behavior

Booking.com controls how many public reviews and fields are exposed for each property. Some fields, such as photos, room details, traveler type, or hotel replies, are absent on individual reviews and are returned empty rather than invented.

Very selective filters may require scanning more source pages than the number of emitted reviews. The Actor automatically allows extra scan room, bounded by `maxPagesPerHotel`.

### Responsible use

This Actor reads public hotel review information. Use reviewer names, review text, travel details, and other public data in accordance with applicable privacy, copyright, data-protection requirements, and Booking.com's applicable terms. Do not use the output to harass, deanonymize, or build sensitive profiles of reviewers.

### Support

For a reproducible issue, provide the public Booking.com hotel URL, relevant filters, whether proxy mode was enabled, and the Apify run ID. Never include API tokens, proxy passwords, or private credentials.

# Actor input Schema

## `hotelUrls` (type: `array`):

Full Booking.com hotel-detail URLs. Up to 50 hotels per run.

## `maxReviewsPerHotel` (type: `integer`):

Maximum matching review rows emitted for each unique hotel.

## `maxTotalReviews` (type: `integer`):

Hard cap across all hotels for predictable runtime and spend.

## `sortBy` (type: `string`):

Sort reviews by newest first or Booking.com's most relevant order.

## `minScore` (type: `number`):

Only emit reviews with a Booking.com score at or above this value.

## `maxScore` (type: `number`):

Only emit reviews with a Booking.com score at or below this value.

## `reviewedAfter` (type: `string`):

Optional inclusive lower date boundary: YYYY-MM-DD or ISO 8601.

## `reviewedBefore` (type: `string`):

Optional inclusive upper date boundary: YYYY-MM-DD or ISO 8601.

## `containsText` (type: `string`):

Optional case-insensitive substring across title, positive text, and negative text. Filtered rows are not billed.

## `reviewerCountries` (type: `array`):

Optional country codes or country names, e.g. US, GB, Italy. Empty means all.

## `customerTypes` (type: `array`):

Optional Booking traveler types such as COUPLES, SOLO, FAMILY, GROUP, BUSINESS. Empty means all.

## `languageCodes` (type: `array`):

Optional Booking review language codes. Empty means all languages.

## `minHelpfulVotes` (type: `integer`):

Only emit reviews with at least this many helpful votes.

## `partnerReply` (type: `string`):

Return any reviews, only reviews with a property reply, or only reviews without a reply.

## `includePhotos` (type: `boolean`):

Include public photo URLs attached to reviews when Booking.com exposes them.

## `includeHotelSummary` (type: `boolean`):

Add one free summary row per hotel with review count and Booking.com rating/filter aggregates.

## `maxPagesPerHotel` (type: `integer`):

Safety ceiling for Booking.com review pagination. Each source page is currently requested in small batches for reliability.

## `browserTimeoutSecs` (type: `integer`):

Maximum seconds for hotel-page initialization and review-session capture.

## `graphqlTimeoutSecs` (type: `integer`):

Maximum seconds for each Booking.com review GraphQL request.

## `retries` (type: `integer`):

Retries a hotel session after transient browser/network failures.

## `autoProxyFallback` (type: `boolean`):

Start direct for lower cost; if Booking.com blocks the session, retry through Apify Proxy when available.

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

Optional explicit proxy configuration. Leave disabled for direct-first mode.

## Actor input object example

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/us/ace-new-york.html"
  ],
  "maxReviewsPerHotel": 500,
  "maxTotalReviews": 5000,
  "sortBy": "newest",
  "minScore": 1,
  "maxScore": 10,
  "reviewedAfter": "",
  "reviewedBefore": "",
  "containsText": "",
  "reviewerCountries": [],
  "customerTypes": [],
  "languageCodes": [],
  "minHelpfulVotes": 0,
  "partnerReply": "any",
  "includePhotos": true,
  "includeHotelSummary": true,
  "maxPagesPerHotel": 100,
  "browserTimeoutSecs": 60,
  "graphqlTimeoutSecs": 30,
  "retries": 2,
  "autoProxyFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("zenomastro/booking-reviews-reliable").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("zenomastro/booking-reviews-reliable").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 '{}' |
apify call zenomastro/booking-reviews-reliable --silent --output-dataset

```

## MCP server setup

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

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/jmEbJroXQEWztBLFR/builds/q4yht1ufun5xrifFH/openapi.json
