# Booking.com Reviews Scraper: Anonymous Scores (`myth84/booking-reviews-scraper`) Actor

Scrape Booking.com reviews from hotel URLs: score, month, language, title, liked and disliked texts, trip type, nights, room type and the hotel's 7 sub-scores. Anonymous: no reviewer name, country or photo, property replies left out. No personal data.

- **URL**: https://apify.com/myth84/booking-reviews-scraper.md
- **Developed by:** [Flatrow Data Studio](https://apify.com/myth84) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 – anonymous scores, texts and stay types, no personal data

- Verified daily by an automated run on Apify with the default input.
- Price: $1.20 per 1,000 reviews on the Free plan; on paid plans, from $0.79 for 1,000 (Business plan).
- Start fee: $0.00005 per run (Apify's minimum).

Booking.com reviews scraper — anonymous, no reviewer names: get the reviews of any Booking.com hotel with the score on 10, title, what guests liked and disliked, trip type, nights, month of the stay and room type, plus the hotel's 7 sub-scores, as a clean table or through an API — no login. Use it as a Booking reviews scraper for hotel review analysis, sentiment analysis, competitor benchmarking and monitoring new reviews.

**No login, no cookies, no personal data:** nothing to sign in to, no cookies to paste. Anonymous Booking.com reviews: no reviewer name, country or photo, property replies left out.

- **What you get:** one flat row per Booking.com review of the hotels you give: month, score on 10, language, title, what the guest liked and disliked, trip type (family, couple, group, solo, business), nights, month of the stay, room type, whether the property replied, and the hotel's score, review count and 7 sub-scores on every row. No personal data.
- **For whom:** hoteliers and revenue managers benchmarking competitors, reputation and guest-experience teams, travel and market analysts, product teams building sentiment or topic datasets, AI agents through MCP.
- **How much:** from $1.20 per 1,000 reviews on the Free plan, lower on paid plans; Apify's free monthly credit of $5 covers about 4,166 reviews. A fixed price per review saved and nothing else (see the Pricing tab); `maxReviewsPerHotel` and `maxResults` cap every run.

**Sample output**: one real review of a Lisbon hotel, key columns only, nothing about its author (the full row is under *Output example*):

```json
{
  "platformListingId": "10131840",
  "reviewMonth": "2026-10",
  "rating": 8,
  "language": "es",
  "title": "Comodidad cerca del aeropuerto",
  "positiveText": "La cercanía con el aeropuerto. Cuentan con estacionamiento en las inmediaciones.",
  "negativeText": "El desayuno empieza muy tarde",
  "tripType": "solo",
  "nights": 1,
  "roomType": "Superior Double or Twin Room",
  "hasHostResponse": false,
  "listingRating": 8.5
}
```

Give this Booking.com reviews scraper a list of **hotel URLs** and get **one flat row per review**, in the order you choose (newest, most relevant, oldest, highest or lowest scores first), up to the full published history of each hotel. Each row has the **month** of the review, the **score** (1 to 10), the **language** of the text, the **title** and the two parts of a Booking.com review, **what the guest liked** and **what they disliked**, plus the **type of traveller**, the **number of nights**, the **month of the stay** and the **room type** booked. The hotel's overall score, review count and its **7 sub-scores** (cleanliness, comfort, location, facilities, staff, value for money, free Wi-Fi) are repeated on every row. Use Booking.com's own filters — **languages**, **trip type**, **season**, **score band**, **topic** (breakfast, noise, location…) and **full-text search** — or keep only the reviews **since a date** to monitor new ones cheaply.

**No personal data, by design.** Booking.com review scrapers usually publish the reviewer's name, country and avatar, and the property's reply, which often names the guest. This Actor never even requests them: rows are built from a short list of review facts, links, e-mails and phone numbers are removed from the texts, dates are kept to the month and the review id is replaced by an anonymous key. The dataset is safe to store, share and feed to AI agents.

### What can you do with Booking.com reviews?

- **Benchmark a hotel against its competitors**: overall score and the 7 sub-scores side by side, the share of poor reviews, what guests praise and what they complain about (`sortBy` lowest scores first).
- **Monitor new reviews** of your own or competing hotels: schedule the Actor with `reviewsSince` and compare `reviewKey` from run to run.
- **Build sentiment and topic datasets**: liked and disliked texts already separated, in the languages you choose, filtered by Booking.com topic, traveller type, season or score band.
- **Understand who stays and how long**: trip type, nights, month of the stay and room type on every review.
- **Feed AI agents, spreadsheets and BI tools** with a stable, documented schema (`travel-review/1.1`) shared by the review scrapers of the travel studio (Airbnb reviews have the same columns); join with the Booking.com Scraper and the Booking.com Hotel Details Scraper on `platformListingId`.

### What data does Booking.com Reviews Scraper extract?

Every row has every column: a value Booking.com does not give is `null`, so CSV and Excel exports keep the same columns from run to run.

| Group | Columns |
|---|---|
| Identity | `schemaVersion`, `platform`, `platformListingId`, `listingUrl`, `reviewKey` |
| Review | `reviewMonth`, `rating`, `ratingMax`, `language`, `title`, `text`, `positiveText`, `negativeText`, `hasHostResponse` |
| Stay | `tripType`, `nights`, `stayLength`, `stayMonth`, `roomType` |
| Request | `position`, `sortOrder`, `matchedTopic`, `searchQuery` |
| Hotel ratings | `listingRating`, `listingReviewCount`, `listingRatingCleanliness`, `listingRatingComfort`, `listingRatingLocation`, `listingRatingFacilities`, `listingRatingStaff`, `listingRatingValue`, `listingRatingWifi` |
| Airbnb columns of the shared schema (always `null` here) | `translatedText`, `translatedLanguage`, `stayHighlight`, `listingRatingAccuracy`, `listingRatingCheckIn`, `listingRatingCommunication` |
| Context | `scrapedAt` |

`text` joins the liked part (`positiveText`) and the disliked part (`negativeText`) with an empty line, for tools that expect a single text column. `stayLength` is derived from the nights: `one_night` (1), `few_nights` (2 to 4), `about_a_week` (5 to 9), `over_a_week` (10 and more). The `listingRating…` columns are the hotel's own scores on 10, read once per hotel and repeated on each of its reviews: Booking.com publishes no sub-score per review.

### Privacy by design

The rules below are applied to every review before it is saved, in this order, and tested on real captured responses:

1. **No identity of the author.** Never a name, first name, pseudonym, photo, profile link or id, city or country of the guest; no guest photos. The property's public reply is left out (it usually greets the guest by name): only `hasHostResponse` says whether there is one. These fields are **not even requested** from Booking.com.
2. **Rows are built from a whitelist** of review facts, never by copying Booking.com's response, then pass the studio's privacy filter.
3. **Texts cleaned.** HTML tags, including the `<mark>` highlights of a full-text search, are removed from `title`, `positiveText`, `negativeText` and `text`; links become `[link]`, e-mail addresses and phone numbers `[redacted]`; empty texts are `null`.
4. **Dates to the month.** `reviewMonth` is the month of publication (UTC) and `stayMonth` the month of the check-in; the exact dates are never published.
5. **No review id.** `reviewKey` is the first 16 characters of a SHA-256 hash of Booking.com's review id: stable from run to run (to deduplicate and spot new reviews) but not reversible. The hotel id (`platformListingId`) is kept.

Limit: review texts are written by guests; we remove links, e-mails and phone numbers, but a name a guest writes (a staff member, for instance) can remain.

### How to scrape Booking.com reviews

1. **Paste hotel URLs** copied from your browser (`https://www.booking.com/hotel/pt/masa-campo-grande.html`, any Booking.com domain or language) or just `pt/masa-campo-grande`, one per line.
2. **Choose how many reviews** per hotel (`maxReviewsPerHotel`, up to the full history) and the order (`sortBy`).
3. **Optionally filter**: a date (`reviewsSince`), review languages (`languages`), a trip type, a season, a score band, a Booking.com topic (`topic`) or a word (`searchQuery`); pick the Booking.com interface language (`language`) for room types and topic names.
4. **Run** and open the **Output** tab: the *Overview*, *Texts* and *Hotel ratings* views show the main columns; export everything as JSON, CSV, Excel or through the API.

### Input

Give at least one hotel URL in `hotelUrls`. Field names and defaults are those of the input form.

The input of our validation run: three hotels (a Lisbon hotel with over 11,000 reviews, a London hotel, a small Lisbon guest house with a few dozen reviews), the 60 newest reviews of each (every other field keeps its default):

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html",
    "https://www.booking.com/hotel/gb/the-savoy.html",
    "https://www.booking.com/hotel/pt/al-abade.html"
  ],
  "maxReviewsPerHotel": 60,
  "sortBy": "NEWEST_FIRST",
  "language": "en-us",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "debugStoreResponses": false
}
```

Every field, with its type and default:

| Field | Type | Default | Description |
|---|---|---|---|
| `hotelUrls` | string\[] | — | Booking.com hotel URLs (`/hotel/<country>/<name>.html`, any Booking.com domain, with or without language suffix and parameters) or `<country>/<name>`, up to 1,000. Duplicates are read once. |
| `maxReviewsPerHotel` | integer | `100` | Reviews kept per hotel, in the chosen order (up to 100,000: the full history of any hotel). |
| `maxResults` | integer | `1000` | Stop the run after this many reviews over all hotels (up to 1,000,000). You are never charged for more. Prefilled with `20` in the form for a quick first run. |
| `sortBy` | string | `"NEWEST_FIRST"` | `NEWEST_FIRST`, `MOST_RELEVANT` (Booking.com's ranking, interface language first), `OLDEST_FIRST`, `SCORE_DESC` (highest first) or `SCORE_ASC` (lowest first). |
| `reviewsSince` | string | — | Only reviews published on or after this date, `YYYY-MM-DD` or `YYYY-MM`. With `NEWEST_FIRST`, each hotel stops at the first older review. |
| `languages` | string\[] | `[]` | Only reviews written in these languages (`en`, `fr`, `de`, `es`, `pt`, `it`, `nl`, `pl`, `ja`, `zh`…), up to 40; empty for every language. |
| `tripType` | string | — | Only reviews of `family`, `couple`, `group` (friends), `solo` or `business` travellers. |
| `season` | string | — | Only stays in `mar_may`, `jun_aug`, `sep_nov` or `dec_feb`. |
| `scoreBand` | string | — | Only reviews scored `superb` (9+), `good` (7–9), `fair` (5–7), `poor` (3–5) or `very_poor` (1–3). |
| `topic` | string | — | A Booking.com review topic of the hotel in the interface language, e.g. `Breakfast`, `Room`, `Clean`, `Location`, `Noise`, `Parking`. A hotel without it is skipped and the log lists its topics. |
| `searchQuery` | string | — | Only the reviews containing this word or phrase (Booking.com's full-text search). |
| `language` | string | `"en-us"` | Booking.com interface language of room types, topic names and the most-relevant order (en-us, en-gb, fr, de, es, it, pt-pt, nl…). Texts stay in their own language. |
| `proxyConfiguration` | object | `{"useApifyProxy":true}` | Apify datacenter proxies by default, included in the price; keep them, or bring your own proxy URLs. |
| `maxRequests` | integer | `2000` | Safety cap on requests in one run (one per 25 reviews, plus one per hotel, plus one per hotel with a topic). |
| `delayMs` | integer | `250` | Pause between two pages of the same hotel, in milliseconds. |
| `debugStoreResponses` | boolean | `false` | Debugging only: store every Booking.com response as it is (they never contain reviewer names or countries). |

### Output example

One real row, produced by the Actor from a review of a Lisbon hotel on booking.com (Spanish review with a title, a liked and a disliked part, solo traveller, one night). All columns are present, in this order, for every review:

```json
{
  "schemaVersion": "travel-review/1.1",
  "platform": "booking",
  "platformListingId": "10131840",
  "listingUrl": "https://www.booking.com/hotel/pt/masa-campo-grande.html",
  "reviewKey": "ff18ec5d530f21b9",
  "reviewMonth": "2026-10",
  "rating": 8,
  "ratingMax": 10,
  "language": "es",
  "title": "Comodidad cerca del aeropuerto",
  "text": "La cercanía con el aeropuerto. Cuentan con estacionamiento en las inmediaciones.\n\nEl desayuno empieza muy tarde",
  "positiveText": "La cercanía con el aeropuerto. Cuentan con estacionamiento en las inmediaciones.",
  "negativeText": "El desayuno empieza muy tarde",
  "translatedText": null,
  "translatedLanguage": null,
  "stayLength": "one_night",
  "tripType": "solo",
  "stayHighlight": null,
  "nights": 1,
  "stayMonth": "2026-10",
  "roomType": "Superior Double or Twin Room",
  "hasHostResponse": false,
  "position": 8,
  "sortOrder": "NEWEST_FIRST",
  "matchedTopic": null,
  "searchQuery": null,
  "listingRating": 8.5,
  "listingReviewCount": 11779,
  "listingRatingAccuracy": null,
  "listingRatingCheckIn": null,
  "listingRatingCleanliness": 8.93,
  "listingRatingCommunication": null,
  "listingRatingLocation": 8.7,
  "listingRatingValue": 8.48,
  "listingRatingStaff": 9.14,
  "listingRatingComfort": 8.91,
  "listingRatingFacilities": 8.68,
  "listingRatingWifi": 9.11,
  "scrapedAt": "2026-10-20T08:00:00.000Z"
}
```

### How much does it cost to scrape Booking.com reviews?

This Actor uses **pay-per-event pricing: you pay a fixed price per review** saved to your dataset, and nothing else. On the Free plan, reviews cost $1.20 per 1,000, so Apify's free monthly credit of $5 covers about 4,166 reviews; paid plans pay less per review, and the price of every plan tier is on the **Pricing tab** of this page.

| What you pay for | How it is counted | Price |
|---|---|---|
| `result` event: one anonymous review saved to your dataset | once per unique review of the run, capped by `maxReviewsPerHotel` and `maxResults` | Pricing tab, per plan tier |
| Hotel score, review count and sub-scores | read once per hotel, repeated on its reviews | included |
| Run start | a symbolic amount, once per run | Pricing tab |
| Compute, proxies, storage and data transfer | included: no platform usage is passed on to you | — |

The cost of a run is known before you start: 1,000 reviews cost 1,000 times the `result` price of your tier, whatever the number of hotels or pages fetched. Booking.com returns 25 reviews per request, so 1,000 reviews of one hotel take well under a minute.

### What is not included

- **Reviewer names, countries, avatars and photos, and the property's replies**: never collected, by design (only `hasHostResponse`).
- **Translations**: texts come in the language the guest wrote them in (`language` column); Booking.com's translation is not available in this version (`translatedText` stays `null`). Use `languages` to keep the languages you read.
- **Sub-scores per review**: Booking.com publishes one score per review; the 7 sub-scores belong to the hotel.
- **Exact dates**: months only (`reviewMonth`, `stayMonth`).
- **Finding hotels by city**: give hotel URLs; the Booking.com Scraper finds hotels for a destination.

### Limits and behaviour worth knowing

- **Full history, in Booking.com's order.** Booking.com gives every published review of a hotel (usually the last three years), 25 per request; the order is Booking.com's for the chosen `sortBy` and `position` keeps it. Scores are whole numbers from 1 to 10.
- **Score-only reviews.** About a third of Booking.com reviews have a score and no text: their `title`, `text`, `positiveText` and `negativeText` are `null`, every other column is filled.
- **Most relevant favours your interface language.** With `MOST_RELEVANT`, Booking.com puts reviews written in the `language` of the interface first; `NEWEST_FIRST` mixes every language.
- **Filters count differently.** With filters, Booking.com returns only the matching reviews; the hotel's `listingReviewCount` and sub-scores stay the hotel's totals.
- **Topics depend on the hotel and on the interface language.** Topic names are Booking.com's in the `language` you choose ("Breakfast" in English); a hotel without the topic is skipped and the log lists the topics it has.
- **Unknown pages are reported, not fatal.** A hotel URL that does not exist on Booking.com is named in the log, yields no row and is not charged; the run goes on with the others. A run that saves no review at all ends as failed with a message that says why (hotels not found, without reviews or matching reviews, topic not found, or a Booking.com change), so that your schedules notice (no empty successes).
- **Reliability.** An unusable response gets one retry in a new session, then the hotel is given up and reported in the log. If Booking.com changes its reviews format, the hotel fails with an explicit message instead of returning half-empty rows; the fix is shipped as a new build (see the Changelog).

### Integrations and API

Start the Actor from Apify Console, schedule it, or call it from the [Apify API](https://docs.apify.com/api/v2) with any language (the **API** tab shows ready-made code for Node.js, Python and curl). Webhooks notify your systems when a run finishes; the dataset can be pulled as JSON, CSV, Excel, XML or RSS, or pushed to Google Sheets, Make, Zapier, n8n, Slack, Airtable, Google Drive and more through the Apify integrations.

### Use it from your AI assistant

Add this Actor as a tool to Claude, ChatGPT, Cursor, VS Code or any MCP client with the Apify MCP server URL below (sign in with your Apify account when asked):

`https://mcp.apify.com?tools=myth84/booking-reviews-scraper`

Then ask in plain words. Copy this prompt and change the details:

```text
Use myth84/booking-reviews-scraper to get the 30 newest English reviews of this Booking.com hotel and sum up what guests liked and disliked: https://www.booking.com/hotel/pt/masa-campo-grande.html. Input: {"hotelUrls": ["https://www.booking.com/hotel/pt/masa-campo-grande.html"], "maxReviewsPerHotel": 30, "sortBy": "NEWEST_FIRST", "languages": ["en"]}. Show the month, score, trip type, what the guest liked and what they disliked for each review.
```

### For AI agents (MCP)

Through the [Apify MCP server](https://docs.apify.com/mcp) this Actor is a tool that answers questions such as *"what do guests dislike about this hotel?"*, *"how is this hotel rated for cleanliness and staff, and what did the last 20 guests write?"* or *"what do couples say about breakfast here?"*.

**Minimal input** (every other field keeps its default; raise `maxReviewsPerHotel` only when the question needs more reviews):

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html"
  ],
  "maxReviewsPerHotel": 20
}
```

- **Key output fields**: `platformListingId`, `reviewMonth`, `rating` (on 10), `language`, `title`, `positiveText`, `negativeText`, `text`, `tripType`, `nights`, `stayMonth`, `roomType`, `hasHostResponse`, `listingRating`, `listingReviewCount` and the seven sub-scores `listingRatingCleanliness` … `listingRatingWifi`. Every column is always present, in a fixed order; `null` means Booking.com did not give the value. The full list is in *What data does Booking.com Reviews Scraper extract?* above.
- **Use it when** you have Booking.com hotel URLs and need what guests wrote and how they scored their stay: recent reviews, lowest-scored reviews, reviews about a topic, from a type of traveller, in a language or containing a word, reviews since a date. Pass `hotelUrls` (a few URLs) and a small `maxReviewsPerHotel`; add `sortBy`, `topic`, `searchQuery`, `languages`, `tripType`, `scoreBand` or `reviewsSince` to narrow down.
- **Do not use it for** finding hotels by place or price (use the Booking.com Scraper), rooms, facilities and offers (Booking.com Hotel Details Scraper), reviewer profiles, property replies or guest photos: it collects no personal data and only reads public reviews.
- **Cost per 1,000 results**: 1,000 `result` events, $1.20 per 1,000 on the Free plan and less on paid plans (Pricing tab); nothing else is charged.
- **Typical time**: about one second per hotel plus one second per 25 reviews: 20 reviews of one hotel in a few seconds, 1,000 reviews of one hotel in well under a minute.

### Alternatives and switching

- **Official API.** Booking.com's APIs are made for its accommodation and affiliate partners and need an approved partner account. This Actor reads the reviews any visitor sees for any Booking.com hotel, without the reviewers' identity, with no account, no keys and no approval.
- **Your own scraper.** Nothing to build or maintain: pagination over the full history, Booking.com's filters, retries and Booking.com changes are handled for you, and the anonymisation rules are applied and tested on every row. The columns stay the same from run to run, a run that finds nothing fails with an explicit message instead of succeeding empty, and a scheduled test run catches Booking.com changes early.
- **Another scraper from the Store.** The input names differ from one Actor to the next; the usual ones map to this Actor as follows:

| Usual input | Here | Note |
|---|---|---|
| `startUrls`, `urls`, `hotelUrl` | `hotelUrls` | Booking.com hotel URLs, or `<country>/<name>` |
| `maxReviews`, `maxItems` | `maxReviewsPerHotel` | Reviews per hotel; `maxResults` caps the whole run |
| `sort` | `sortBy` | `NEWEST_FIRST`, `MOST_RELEVANT`, `OLDEST_FIRST`, `SCORE_DESC` or `SCORE_ASC` |
| `cutoffDate`, `startDate` | `reviewsSince` | `YYYY-MM-DD` or `YYYY-MM` |
| `reviewLanguage` | `languages` | A list of review languages, e.g. `["en", "fr"]` |
| `customerType`, `travelerType` | `tripType` | `family`, `couple`, `group`, `solo` or `business` |
| `score` | `scoreBand` | `superb`, `good`, `fair`, `poor` or `very_poor` |
| `keyword`, `search` | `searchQuery` | Booking.com's full-text search of the reviews |
| `proxy` | `proxyConfiguration` | Apify proxies, included in the price |

### FAQ

#### Does Booking.com Reviews Scraper collect personal data?

No. It never requests nor saves the reviewer's name, country, avatar or photos, and no property reply; links, e-mails and phone numbers are removed from the texts, dates are kept to the month and review ids are replaced by an anonymous key. See *Privacy by design* above for the rules and their limit.

#### Why no reviewer names or countries?

Because names, avatars and nationalities of reviewers are personal data under the GDPR and similar laws, and they add nothing to an analysis of what guests think of a hotel; the type of traveller (`tripType`) and the review language (`language`) are kept instead. Leaving them out makes the dataset safe to store, share and process. The `reviewKey` column still lets you deduplicate reviews and follow them from run to run.

#### Can I get only new reviews?

Yes. Set `reviewsSince` to the date (or month) of your last run and keep `sortBy` on `NEWEST_FIRST`: each hotel stops at the first older review, so a daily run costs only the new reviews. You can also compare the `reviewKey` column with your previous dataset: it is stable from run to run.

#### Are sub-scores per review available?

No: Booking.com publishes one score (1 to 10) per review. The sub-scores (cleanliness, comfort, location, facilities, staff, value for money, free Wi-Fi) exist for the hotel as a whole: they are repeated on every review row in the `listingRating…` columns.

#### Why are some reviews empty?

About a third of Booking.com reviews are a score without any text. They are kept, because the score, month, trip type, nights and room type still count; their `title`, `text`, `positiveText` and `negativeText` are `null`. Filter them out on `text` if you only want written reviews, or use `searchQuery` to get only reviews that mention a word.

#### Are texts translated?

Not in this version: every text stays in the language the guest wrote it in, given in the `language` column (`en`, `fr`, `pt`, `en-US`, `pt-BR`…). Use `languages` to keep only the languages you read; `translatedText` is reserved for a later version.

#### How many reviews can I get per hotel?

All published ones: Booking.com gives the full history of a hotel, 25 reviews per request. Set `maxReviewsPerHotel` high enough (up to 100,000) and `maxResults` above the total you expect; `listingReviewCount` tells you how many the hotel has.

#### Is it legal to scrape Booking.com reviews?

The Actor only reads reviews that Booking.com shows to any visitor without an account, and it stores no personal data. Scraping public data is generally lawful, but you are responsible for how you use the results and for complying with Booking.com's terms of service and the laws that apply to you; review texts are the guests' own words, use them for analysis rather than republishing.

#### What if my runs get blocked? Do I need proxies?

Apify datacenter proxies (the default) work for Booking.com reviews and are included in the price. If a run reports blocked responses, increase `delayMs` and try again later, or bring your own proxy URLs; persistent blocking is fixed as a priority, open an issue with your run id.

#### Where do I get support?

Open an issue in the **Issues** tab of this Actor with your run id and input. Bugs and Booking.com changes are fixed as a priority; feature requests (translations, other review platforms of the travel studio) are welcome.

### More scrapers by Flatrow Data Studio

Put what guests say next to prices and availability: the Booking.com scrapers share the property id (`platformListingId`), and the travel scrapers of the studio share the same core columns:

- [Booking.com Hotels Scraper & Price Tracker](https://apify.com/myth84/booking-hotels-scraper): Booking.com hotel prices for your dates with the excluded taxes, review scores and stars, search URLs and price monitoring — the hotel URLs to feed this Actor.
- [Expedia Hotels Scraper: Prices & Ratings](https://apify.com/myth84/expedia-hotels-scraper): Expedia hotel prices per night and for the whole stay, guest ratings and review counts, to compare with the other platforms.
- [Airbnb Listings Scraper & Price Tracker](https://apify.com/myth84/airbnb-listings-scraper): Airbnb prices, ratings, review counts and locations for any place and dates, up to 50 destinations per run, with price monitoring.
- [Airbnb Listing Details & Availability Calendar](https://apify.com/myth84/airbnb-listing-details-scraper): amenities, house rules, six category ratings and a 1–12 month availability calendar for the Airbnb listing URLs you give.

Did this scraper give you the data you needed? A rating on its Store page helps other people find it. For a bug or a missing field, open an issue in the **Issues** tab.

If this Actor saved you time, a short review helps others find it.

### Legal note

This Actor reads publicly available Booking.com reviews without logging in and collects no personal data. You are responsible for your use of the data and for complying with Booking.com's terms and the laws that apply to you.

Not affiliated with, endorsed or sponsored by Booking.com. Booking.com is a trademark of Booking.com B.V.

# Changelog

This Actor's version history is a separate document: https://apify.com/myth84/booking-reviews-scraper/changelog.md

# Actor input Schema

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

One hotel page per line, copied from your browser: <code>https://www.booking.com/hotel/pt/masa-campo-grande.html</code> (any Booking.com domain, language suffixes such as <code>.en-gb.html</code> and query parameters are fine) or just <code>pt/masa-campo-grande</code>. 1 to 1,000 URLs; duplicates are read once. Search result URLs are not accepted: use the Booking.com Scraper to find hotels.

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

Stop reading a hotel after this many reviews, in the chosen order, 1 to 100,000. Booking.com gives the full published history of a hotel: set a high value to get every review. Default 100: the recent opinion of a hotel, about $0.12 per hotel on the Free plan.

## `maxResults` (type: `integer`):

Stop the run after this many reviews over all hotels, 1 to 1,000,000; you are never charged for more. Default 1000: ten hotels at the default 100 reviews each, about $1.20 on the Free plan. The form is prefilled with 20 for a quick first run.

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

Order in which Booking.com returns the reviews of each hotel: newest first (default, all languages), most relevant (Booking.com's own ranking, which puts reviews in the interface language first), oldest first, highest scores first or lowest scores first. The <code>position</code> column keeps this order.

## `reviewsSince` (type: `string`):

Optional date, <code>YYYY-MM-DD</code> or <code>YYYY-MM</code>, e.g. <code>2026-09</code> for September 2026 onwards: only reviews published on or after it are kept. Sorted newest first, each hotel stops at the first older review, which makes monitoring new reviews cheap; with another order the reviews are filtered.

## `languages` (type: `array`):

Optional: only reviews written in these languages, one Booking.com code per line, e.g. <code>en</code>, <code>fr</code>, <code>de</code>, <code>es</code>, <code>pt</code>, <code>it</code>, <code>nl</code>, <code>pl</code>, <code>ja</code>, <code>zh</code>; up to 40, duplicates dropped. Default empty: every language.

## `tripType` (type: `string`):

Optional: only reviews of this type of traveller (Booking.com's own filter): families, couples, groups of friends, solo travellers or business travellers.

## `season` (type: `string`):

Optional: only reviews of stays in these months (Booking.com's own filter).

## `scoreBand` (type: `string`):

Optional: only reviews in this score band (Booking.com's own filter): superb 9+, good 7 to 9, fair 5 to 7, poor 3 to 5, very poor 1 to 3.

## `topic` (type: `string`):

Optional topic among those Booking.com shows above a hotel's reviews, in the interface language below, 2 to 50 characters, e.g. <code>Breakfast</code>, <code>Room</code>, <code>Clean</code>, <code>Location</code>, <code>Noise</code>, <code>Parking</code>. Matched without case or accents. A hotel without this topic is skipped and the log lists its topics. Leave empty: no topic filter.

## `searchQuery` (type: `string`):

Optional word or phrase: only the reviews that contain it (Booking.com's own full-text search, e.g. <i>noise</i>, <i>parking</i>, <i>breakfast</i>).

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

Booking.com interface language of the room types, of the topic names and of the most-relevant order: two lowercase letters, optionally a region, e.g. <code>en-us</code>, <code>en-gb</code>, <code>fr</code>, <code>de</code>, <code>pt-pt</code>. Review texts always stay in the language they were written in (<code>language</code> column). Default en-us: English (US), the language of our validation runs.

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

Proxies of the requests. Default: Apify datacenter proxies, included in the price and enough for Booking.com reviews in our tests. If your runs get blocked, choose another Apify proxy group or give your own proxy URLs.

## `maxRequests` (type: `integer`):

Safety cap on requests for the whole run: one per 25 reviews, plus one per hotel, plus one per hotel with a topic. Default 2000: far more than the default 1,000 reviews need (about 40 pages plus one request per hotel).

## `delayMs` (type: `integer`):

Pause between two pages of reviews of the same hotel, in milliseconds, 0 to 30,000; 0 disables it. Increase it if you get blocked. Default 250: a quarter of a second, a short pause that keeps long histories quick to read.

## `debugStoreResponses` (type: `boolean`):

Debugging only: save every Booking.com response in the run's key-value store as it is. The requests never ask for reviewer names, countries, photos or property replies, so the responses hold none. Default off: it uses storage.

## Actor input object example

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html"
  ],
  "maxReviewsPerHotel": 100,
  "maxResults": 20,
  "sortBy": "NEWEST_FIRST",
  "languages": [],
  "language": "en-us",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxRequests": 2000,
  "delayMs": 250,
  "debugStoreResponses": false
}
```

# Actor output Schema

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

All extracted reviews as dataset items, one flat row per review. Append ?format=csv or ?format=xlsx for spreadsheets. The Overview view is selected by default.

## `runStats` (type: `string`):

Requests made, bytes transferred, blocked responses, reviews pushed, hotels read, not found, without reviews, without the topic or failed, reviews without text, links removed, retries, and the estimated platform cost of the run.

# 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 = {
    "hotelUrls": [
        "https://www.booking.com/hotel/pt/masa-campo-grande.html"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("myth84/booking-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 = {
    "hotelUrls": ["https://www.booking.com/hotel/pt/masa-campo-grande.html"],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("myth84/booking-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 '{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html"
  ],
  "maxResults": 20
}' |
apify call myth84/booking-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,myth84/booking-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/liOhjfdwhi8utl7Ri/builds/EiTlOrd8VtOL8iJZf/openapi.json
