# Booking.com Hotels Scraper (`nice_dev/booking-hotels-scraper`) Actor

Scrape Booking.com hotels by place and dates: prices, availability, property details, rooms and guest reviews. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/nice_dev/booking-hotels-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** Travel, Lead generation, MCP servers
- **Stats:** 7 total users, 3 monthly users, 97.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.42 / 1,000 property saveds

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

### 🏨 What is Booking.com Hotels Scraper?

**Booking.com Hotels Scraper** extracts **hotels, apartments, villas and every other stay from [Booking.com](https://www.booking.com)**: **name, price for your dates with taxes, availability, guest rating, address, GPS position and photos** for a whole destination, a map point, a list of property names or ids, or any Booking.com search or property link you paste. Switch on the options you need to add the **full property profile, every room offer, a day-by-day price calendar, guest reviews, the review summary, nearby places and the host or company contact details**. It works as a **Booking.com API alternative**: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.

Type a **destination** (`Paris`), pick your dates, guests and currency, click **Start**, and download the properties in JSON, CSV or Excel. No login, nothing to set up. Several destinations, property names, property ids, map points and links can run together in one run, and a search that holds more than 1,000 properties is read in full automatically.

### 📋 What data can you extract from Booking.com?

One item per property, 107 fields. The rows marked **option** are filled only when you tick the matching option; each option is charged on its own, only when ticked (see Pricing).

| Category                          | What you get                                                                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 🏨 **Property**                   | name, link, type (hotel, apartment, villa…), stars, host type — `My Story Hotel Tejo`, `hotel`, `3 stars`                      |
| 💰 **Price and taxes**            | price for the whole stay, price per night, crossed-out price, discounts, taxes to pay on site, currency — `156 EUR`            |
| 🛎️ **Availability and conditions** | available or sold out, free cancellation and its last date, rooms left, the room Booking.com recommends, the stay priced      |
| ⭐ **Ratings**                    | guest score out of 10, its wording, number of reviews, score per category (staff, cleanliness, location…) — `9.1`, `Superb`   |
| 📍 **Location**                   | address, district, city, country, GPS, distance from the center in km and as Booking.com words it                 |
| 🖼️ **Photos and badges**          | main photo (every photo with the full profile), deal badges, Preferred Partner, sustainability          |
| 🧾 **Full property profile** (option) | description, amenities by group, house rules, check-in and check-out times, languages, licence numbers, chain, guests' questions and answers, full address with postal code, Genius and Travel Proud badges |
| 🛏️ **Room offers** (option)       | every room and rate: size, beds, meals, price, taxes, cancellation, prepayment, rooms left                                     |
| 📅 **Price calendar** (option)    | day by day: bookable or not, indicative price of a one-night stay, minimum stay                                                |
| 💬 **Guest reviews** (option)     | rating, date, title, positive and negative text, traveler type, country, room, stay dates, the property's reply; number of reviews per language, traveler type and season |
| 🧠 **Review summary** (option)    | Booking.com's own summary of the reviews, scores by topic and by traveler type                                                 |
| 🚉 **Nearby places** (option)     | airports, landmarks, restaurants, public transport, beaches — name, category, distance, time on foot and by car                |
| 🏢 **Host contact** (option)      | company name, registration number, address, e-mail, phone; the name of a private host                                          |

Every field, with an example, is listed in the **Output** section below.

A field of an option you did not tick is `null`, a list too (`reviews`, `roomOffers`, `calendar`, `nearbyPlaces`, `reviewsByLanguage`), never missing, so every row has the same columns: test for `null` before you read a list, except the lists of the full profile (`amenities`, `highlights`, `meals`), which are empty when the profile is not ticked.

### ✅ Why use Booking.com Hotels Scraper?

- 🌍 **Many sources in one run**: destinations, map point and radius, property names, property ids and pasted links, each with its own cap if you want one.
- 📈 **Past the 1,000 results of a search**: a big city is read in full (Rome holds more than 5,000 properties), without any setting.
- 🎯 **Filters Booking.com applies itself**: price, stars, rating, type, amenities, meals, free cancellation, distance, chains and any other filter of the site, so unwanted properties are never read nor charged.
- 💶 **Your dates, guests and currency**: prices are for your stay, with taxes and the taxes to pay on site detailed. Flexible dates are supported.
- 🧩 **Pay for what you use**: the base row is cheap and every heavy block (profile, room offers, calendar, reviews, review summary, nearby places, host contact) is an option, unticked by default.
- 🔔 **Monitoring built in**: tick **Only new properties**, schedule the Actor, and each run saves (and charges) only what it has never delivered before.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.

### 🚀 How to scrape Booking.com

1. Create a free Apify account.
2. Open **Booking.com Hotels Scraper** and type a **Destination** (a city, region, district, airport or landmark, e.g. `Paris`).
3. Or paste your own Booking.com links into **Start URLs** (search results pages: their dates, guests, currency and filters are kept; or single property pages), or fill **Property names**, **Property IDs**, or a map point with **Latitude**, **Longitude** and **Radius**.
4. Pick the stay (**Check-in date**, **Nights**, **Adults**, **Currency**) and set **Max properties** (100 by default, 0 = no limit) — and **Max properties per search** when you run several searches — then click **Start**.
5. Tick the options you want (profile, room offers, calendar, reviews…) and download the dataset in JSON, CSV, Excel or via API.

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

This Actor uses **pay per event** pricing: a price per property saved plus a small fee per run start. The exact amounts, for every Apify plan, are on the **Pricing** tab of this page. Platform usage (compute, proxy) is included in the price.

Every option is **unticked by default** and charged only when ticked, per unit it delivers:

| Option                                  | Charged per                                                                           |
| --------------------------------------- | ------------------------------------------------------------------------------------- |
| **Extract full property profile**       | property whose profile is read                                                        |
| **Room offers (every room and rate)**   | room offer saved (a sold-out property has none and costs nothing for this option)     |
| **Price calendar**                      | day saved                                                                             |
| **Include reviews**                     | review saved                                                                          |
| **Include review summary**              | property that has a summary                                                           |
| **Nearby places**                       | property whose places are saved                                                       |
| **Company / host contact details**      | contact found                                                                         |

Filters Booking.com applies itself (price, stars, rating step, type, amenities, meals, free cancellation, distance, chains, raw filters, available only) cost nothing: the other properties are never read. A property dropped by a filter the Actor runs itself (exact rating, minimum reviews, excluded words or ids) costs a small filter fee instead of a full property price, see Pricing. Set the run option **maximum cost per run** to cap what a run can spend: the Actor stops saving rows when the cap is reached.

### ⚙️ Input

Search one destination for a stay that starts in 30 days:

```json
{
    "location": "Paris",
    "checkIn": "30 days",
    "nights": 2,
    "adults": 2,
    "currency": "EUR",
    "maxItems": 200
}
```

Several destinations, only 4-star hotels with free cancellation, only the properties not delivered before:

```json
{
    "locations": ["Rome", "Florence"],
    "propertyTypes": ["hotel"],
    "minStars": 4,
    "freeCancellationOnly": true,
    "maxItemsPerQuery": 500,
    "onlyNew": true,
    "stateKey": "italy-4-stars"
}
```

Your own links and property names (a pasted search keeps its dates, guests and filters):

```json
{
    "startUrls": [
        { "url": "https://www.booking.com/searchresults.html?ss=Lisbon&checkin=2026-12-20&checkout=2026-12-22" },
        { "url": "https://www.booking.com/hotel/fr/lutetia.html" }
    ],
    "hotelNames": ["Lutetia Paris"],
    "maxItems": 500
}
```

Properties around a map point, nearest first, until the first one beyond the radius:

```json
{
    "latitude": 48.8584,
    "longitude": 2.2945,
    "radiusKm": 2,
    "adults": 2,
    "children": 1,
    "childrenAges": ["5"],
    "sortBy": "distance_from_search",
    "maxItems": 100
}
```

Three properties by id, with every option on (profile, room offers, calendar, reviews, review summary, nearby places, host contact):

```json
{
    "hotelIds": ["535429", "59015", "6966158"],
    "checkIn": "120 days",
    "nights": 2,
    "adults": 2,
    "currency": "EUR",
    "language": "en-gb",
    "maxItems": 3,
    "extractDetails": true,
    "includeRoomOffers": true,
    "maxRoomOffersPerHotel": 50,
    "includeCalendar": true,
    "calendarDays": 70,
    "includeNearbyPlaces": true,
    "includeHostContact": true,
    "includeReviews": true,
    "maxReviewsPerHotel": 30,
    "reviewsSort": "NEWEST_FIRST",
    "includeReviewSummary": true
}
```

| Field                                                                   | Notes                                                                                                                                                                                                                      |
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `location`, `locations`                                                 | A city, region, district, airport or landmark, as typed in the Booking.com search box (`Paris`, `Tuscany`, `Orly Airport`). `locations` adds more destinations: one search each.                                           |
| `startUrls`                                                             | Search results pages (`https://www.booking.com/searchresults.html?ss=Paris&checkin=2026-12-20`) or property pages (`https://www.booking.com/hotel/fr/lutetia.html`). Dates, guests, currency and site filters are kept.     |
| `hotelNames`                                                            | Properties named as Booking.com completes them (`Lutetia Paris`): each name is looked up before the run. Type the name without a first word such as "Hotel" if nothing is found.                                           |
| `hotelIds`                                                              | Booking.com numeric property ids (`54642`), the `propertyId` of a result.                                                                                                                                                  |
| `latitude`, `longitude`, `radiusKm`                                     | A map point (`48.8584`, `2.2945`) and a radius in kilometres: both coordinates are needed, or neither. Results nearest first.                                                                                              |
| `checkIn`, `checkOut`, `nights`, `flexWindow`                           | First night: a date (`2026-12-20`) or a period from the run date (`7 days`, `2 weeks`, `1 year`). Empty = a stay starting 30 days from the run date, and Booking.com takes bookings up to about 495 days ahead (a later date is refused). Check-out empty = check-in plus nights. Flexible dates move the stay by up to 7 days. |
| `adults`, `children`, `childrenAges`, `rooms`                           | Guests and rooms for the whole stay; rooms not above adults (Booking.com needs an adult per room). One age per child in `childrenAges` (`5`), in the same order as on the site.                                                                                                          |
| `currency`                                                              | Currency of every price (`EUR`, `USD`, `GBP`…). A pasted search keeps its own currency.                                                                                                                                    |
| `language`                                                              | Language of the names, descriptions and labels (`en-gb`, `fr`, `de`…) when Booking.com has a translation. A pasted link keeps the language of its address (a language code before html such as fr, or lang=fr); a link with none uses this one.                                                                            |
| `sortBy`                                                                | The 10 orders of the site: `popularity` (default), `price`, `price_from_high_to_low`, `class`, `distance_from_search`, `bayesian_review_score`… Ignored for a map point (always nearest first) and for hotel names, property ids and property links (one property each).                                                                            |
| `maxItems`, `maxItemsPerQuery`                                          | Stop after this many properties for the run (`0` = no limit) and for each search (`0` = no per-search cap).                                                                                                                |
| `extractDetails`                                                        | Option: the full property profile (description, every photo, amenities, house rules, licence numbers…).                                                                                                                    |
| `includeRoomOffers`, `maxRoomOffersPerHotel`                            | Option: every room offer of each property for your dates, up to the cap per property (50 covers almost every property).                                                                                                    |
| `includeCalendar`, `calendarDays`                                       | Option: day-by-day availability, indicative one-night price and minimum stay, from the check-in date, up to 365 days (nothing beyond about 495 days ahead).                                                                                                                   |
| `includeNearbyPlaces`                                                   | Option: airports, landmarks, restaurants, public transport, beaches around each property.                                                                                                                                  |
| `includeHostContact`                                                    | Option: the company or host that runs each property, as Booking.com publishes it (see the FAQ on personal data).                                                                                                           |
| `includeReviews`, `includeReviewSummary`, `maxReviewsPerHotel`          | Option: the guest reviews of each property up to the cap (0 = every review the site serves), and Booking.com's own review summary with the scores by topic. Either one also gives the number of reviews per language, traveler type and season and the topics guests mention, at no extra charge.                                                                |
| `reviewsSort`                                                           | Order of the reviews: `MOST_RELEVANT`, `NEWEST_FIRST`, `OLDEST_FIRST`, `SCORE_DESC`, `SCORE_ASC`.                                                                                                                          |
| `reviewsLanguages`                                                      | Keep only the reviews written in these languages, as two-letter codes (`en`, `fr`, `de`).                                                                                                                                  |
| `reviewsTravelerType`                                                   | Keep only one type of traveler: `FAMILIES`, `COUPLES`, `GROUP_OF_FRIENDS`, `SOLO_TRAVELLERS`, `BUSINESS_TRAVELLERS`.                                                                                                       |
| `reviewsScore`                                                          | Keep only one score band of Booking.com: `REVIEW_ADJ_SUPERB` (9+), `REVIEW_ADJ_GOOD`, `REVIEW_ADJ_AVERAGE_PASSABLE`, `REVIEW_ADJ_POOR`, `REVIEW_ADJ_VERY_POOR`.                                                            |
| `reviewsTimeOfYear`                                                     | Keep only the stays of one season: `_03_05`, `_06_08`, `_09_11`, `_12_02`.                                                                                                                                                 |
| `reviewsSearchText`                                                     | Keep only the reviews that mention a word or phrase (`breakfast`).                                                                                                                                                         |
| `reviewsAfter`, `reviewsBefore`                                         | Review date range: `2026-01-01`, or a period before now (`7 days`, `3 months`). `7 days` on a schedule = the new reviews only.                                                                                             |
| `reviewsMinRating`, `reviewsMaxRating`                                  | Keep only the reviews scored between these two values (out of 10, `0` = no bound).                                                                                                                                         |
| `minPrice`, `maxPrice`, `minStars`, `maxStars`, `minRating`, `minReviewCount` | Price per night in the chosen currency, stars, guest score and review count. 0 = no filter. Price, stars and rating are asked from Booking.com; the exact rating and the review count are checked by the Actor.      |
| `propertyTypes`                                                         | Keep only these types: `hotel`, `apartment`, `holiday_home`, `villa`, `guesthouse`, `hostel`…                                                                                                                              |
| `amenities`                                                             | Keep only properties that have ALL the ticked amenities (the form lists them by name; `107` is Free Wifi, `2` is Parking).                                                                                                 |
| `mealPlan`                                                              | Keep only properties with this meal option: `breakfast`, `breakfast_dinner`, `kitchen`.                                                                                                                                    |
| `freeCancellationOnly`, `availableOnly`                                 | Free cancellation only (off by default); available properties only (on by default: sold-out properties are left out).                                                                                                      |
| `maxDistanceFromCenterKm`                                               | Within this distance of the center, in the three steps of the site: `0.8`, `1.6` or `3.2` km.                                                                                                                              |
| `chains`                                                                | Keep only these brands, by name (`ibis`, `Mercure`) or brand id.                                                                                                                                                           |
| `rawFilters`                                                            | Any filter of the site that has no field here, as Booking.com writes it in a search link (`class=4;review_score=80`, `ht_id=204;hotelfacility=107`; `stay_type=2` keeps adults-only properties, `1` pets allowed, `4` LGBTQ+ friendly). Separate filters with a semicolon.                                    |
| `excludeKeywords`                                                       | Drop the properties whose name contains one of these words (`hostel`), case and accents ignored.                                                                                                                           |
| `excludePropertyIds`                                                    | Booking.com property ids to skip even when they match (`54642`), for example your own hotels.                                                                                                                              |
| `onlyNew`, `stateKey`, `resetState`                                     | Monitoring: only the properties never delivered under this memory key (`paris-hotels`); `resetState` forgets the memory.                                                                                                   |
| Advanced                                                                | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `minRequestIntervalMs`, `maxRequestRetries`, `debugLog`.            |

### 📦 Output

One real item, from a run for Lisbon (stay of 2 nights, every option on). It is shortened: long texts are cut, lists keep their first entries, and about half of the fields are left out (the host contact among them); every field is listed below.

```json
{
    "id": 39719,
    "propertyId": 39719,
    "name": "My Story Hotel Tejo",
    "url": "https://www.booking.com/hotel/pt/my-story-tejo.html",
    "pageName": "my-story-tejo",
    "countryCode": "pt",
    "propertyType": "hotel",
    "starRating": 3,
    "starRatingType": "stars",
    "rating": 9.1,
    "ratingText": "Superb",
    "reviewCount": 4958,
    "ratingBreakdown": {"staff": 9.4, "services": 9.1, "cleanliness": 9.4, "comfort": 9.4, "valueForMoney": 8.9, "location": 9.8},
    "price": 156,
    "currency": "EUR",
    "pricePerNight": 78,
    "taxesAndFeesExcluded": 0,
    "priceWithAllTaxes": 156,
    "isAvailable": true,
    "freeCancellation": false,
    "freeCancellationUntil": null,
    "recommendedRoom": {
        "name": "Double Room",
        "beds": 1,
        "bedrooms": 0,
        "units": 1,
        "bathrooms": 0,
        "kitchens": 0,
        "livingRooms": 0
    },
    "stay": {
        "checkIn": "2026-12-01",
        "checkOut": "2026-12-03",
        "nights": 2,
        "adults": 2,
        "children": 0,
        "childrenAges": [],
        "rooms": 1
    },
    "address": "Rua Condes de Monsanto Nº2",
    "formattedAddress": "Rua Condes de Monsanto Nº2, Santa Maria Maior, 1100-159 Lisbon, Portugal",
    "postalCode": "1100-159",
    "city": "Lisboa",
    "country": "Portugal",
    "latitude": 38.7136009994135,
    "longitude": -9.13665130734444,
    "distanceFromCenter": "250 m from centre",
    "distanceFromCenterKm": 0.25,
    "images": [
        "https://cf.bstatic.com/xdata/images/hotel/max1024x768/304605677.jpg?k=290a15c841c998cc8817640cb06f58007d96d51ec3689f2c5208cd7812136163&o=",
        "https://cf.bstatic.com/xdata/images/hotel/max1024x768/171205095.jpg?k=eebcfc8eb75c1e7644d38598751a9a01a7f2eef59bf7a9dfdfd1ec83bec61007&o="
    ],
    "imageCount": 65,
    "hostType": "professional",
    "description": "Set in the heart of the Baixa, My Story Hotel Tejo is a creative renovation of an historic building. It is in a prime location within Lisbon's histor…",
    "nearbyPlaces": [
        {
            "name": "Humberto Delgado Airport",
            "category": "Airports",
            "distanceKm": 5.49,
            "distanceText": "5 km",
            "walkTime": "1 hr 16 min",
            "walkMinutes": 76,
            "driveTime": "7 min",
            "driveMinutes": 7,
            "latitude": 38.7699,
            "longitude": -9.12951
        },
        {
            "name": "Cascais Municipal Airport",
            "category": "Airports",
            "distanceKm": 18.7,
            "distanceText": "18 km",
            "walkTime": null,
            "walkMinutes": null,
            "driveTime": "16 min",
            "driveMinutes": 16,
            "latitude": 38.7251052856475,
            "longitude": -9.35599040992859
        }
    ],
    "calendar": [
        {"date": "2026-12-01", "available": true, "price": 78, "minNights": 1},
        {"date": "2026-12-02", "available": true, "price": 78, "minNights": 1}
    ],
    "roomOffers": [
        {
            "offerId": "3971902_88531738_2_2_0",
            "roomName": "Double Room",
            "roomSizeSqm": 16,
            "maxOccupancy": 2,
            "mealPlan": "BREAKFAST_EXCLUDED",
            "price": 156,
            "pricePerNight": 78,
            "priceBeforeDiscount": null,
            "currency": "EUR",
            "taxesAndFeesIncluded": 23.92,
            "freeCancellation": false,
            "cancellationText": "Non-refundable",
            "prepaymentText": "Pay the property before arrival",
            "roomsLeft": 10,
            "breakfastPrice": 15
        }
    ],
    "roomOfferCount": 28,
    "reviews": [
        {
            "reviewId": "9c06019b57488a26",
            "rating": 9,
            "date": "2026-09-29T08:20:33.000Z",
            "title": "wonderful experience",
            "positive": "Unbelievably friendly staff. Everyone was so nice and helpful. From the moment we arrived…",
            "negative": "Only one small problem was that housekeeping didn't always leave a full set of towels. Bu…",
            "reviewerCountry": "United States",
            "reviewerCountryCode": "us",
            "travelerType": "SOLO_TRAVELLERS",
            "roomType": "Double Room",
            "nights": 4,
            "checkIn": "2026-09-24",
            "checkOut": "2026-09-28",
            "stayStatus": "stayed",
            "helpfulVotes": 0
        }
    ],
    "reviewsIncomplete": false,
    "reviewsByLanguage": [
        {"code": "it", "name": "Italian", "count": 595, "flag": "it"},
        {"code": "en", "name": "English", "count": 1566, "flag": "gb"},
        {"code": "de", "name": "German", "count": 527, "flag": "de"}
    ],
    "reviewsByTravelerType": [
        {"travelerType": "FAMILIES", "name": "Families", "count": 1173},
        {"travelerType": "COUPLES", "name": "Couples", "count": 2462}
    ],
    "reviewsBySeason": [
        {"season": "_03_05", "name": "Mar–May", "count": 1262},
        {"season": "_06_08", "name": "Jun–Aug", "count": 1432}
    ],
    "reviewTopics": [
        {"id": 249, "name": "Location"},
        {"id": 270, "name": "Room"},
        {"id": 245, "name": "Breakfast"}
    ],
    "reviewSummary": {
        "language": "en",
        "basedOnReviews": 3763,
        "summary": "- Guests appreciated the <b>central location</b> near major attractions\n- <b>Breakfast</b> was gene…",
        "pros": [],
        "cons": []
    },
    "rank": 2,
    "searchLocation": "Lisbon",
    "searchUrl": "https://www.booking.com/searchresults.html?ss=Lisbon&checkin=2026-12-01&checkout=2026-12-03&group_adults=2&no_rooms=1&group_children=0&selected_currency=EUR&lang=en-gb&nflt=oos%3D1&page=1",
    "totalResults": 3870,
    "cityId": -2167973,
    "scrapedAt": "2026-10-02T00:57:28.417Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### All 107 fields

| Fields                                                                                 | What you get                                                                                              |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `id`, `propertyId`, `name`, `url`, `bookingUrl`, `pageName`, `countryCode`             | ids (`id` is a copy of `propertyId`), name, property page, the same page with your stay in the link       |
| `propertyType`, `propertyTypeId`, `starRating`, `starRatingType`                       | `hotel`, `204`, `3`, `stars` (`tiles` = Booking.com's quality rating for homes, `circles` = rating Booking.com shows as circles, not official stars) |
| `rating`, `ratingText`, `reviewCount`, `ratingBreakdown`, `externalRating`, `externalReviewCount` | `9.1`, `Superb`, `4958`, score per category, outside review score and its number of reviews when the site shows one |
| `price`, `currency`, `pricePerNight`, `priceBeforeDiscount`, `discountPercent`, `discounts` | price of the recommended offer for the whole stay, `EUR`, per night, crossed-out price, discount         |
| `taxesAndFeesExcluded`, `taxesAndFees`, `priceWithAllTaxes`                            | taxes to pay on site (null when Booking.com says charges may apply without an amount), every tax line, price plus those taxes |
| `priceInHotelCurrency`, `hotelCurrency`, `priceNote`                                   | the price in the property's own currency when it differs, the note under the price                        |
| `isAvailable`, `isClosed`, `roomsLeft`, `freeCancellation`, `freeCancellationUntil`, `noPrepayment`, `mealPlan`, `recommendedRoom` | availability, rooms left, cancellation, prepayment, meals and room of the recommended offer |
| `stay`, `datesAdjusted`                                                                | check-in, check-out, nights, guests, rooms priced; whether flexible dates moved the stay                  |
| `address`, `district`, `displayLocation`, `city`, `region`, `country`, `latitude`, `longitude` | where the property is |
| `distanceFromCenter`, `distanceFromCenterKm`, `publicTransport`, `isCentral`, `isWithinBestLocationScoreArea` | distance as the site words it and in km, nearest public transport, location flags              |
| `mainImage`, `images`, `imageCount`, `badges`, `sponsored`                             | photos (1024 px), deal badges, whether the result is an ad                                                |
| `isPreferred`, `isPreferredPlus`, `isSustainable`, `sustainabilityCertifications`, `isNewlyOpened`, `isTpiExclusive`, `hostType` | Booking.com badges; `professional` or `private` host |
| `formattedAddress`, `postalCode`, `isGenius`, `isTravelProud` | **option, full profile**: the full address in one line, the postal code read from it (only where the format of the country is known), Genius programme and Travel Proud badges |
| `description`, `descriptionHtml`, `finePrint`, `highlights`                            | **option, full profile**: description as text and as HTML, important information, highlights               |
| `amenities`, `amenityGroups`, `meals`, `languagesSpoken`                               | **option, full profile**: amenities flat and by group, meals served, languages of the staff               |
| `checkInTime`, `checkOutTime`, `policies`, `questionsAnswers`, `averageResponseTime`   | **option, full profile**: times, house rules (children, beds, pets, payment, deposit), guests' questions with the answers (50 at most) |
| `licenseNumbers`, `licensePhrases`, `chain`, `brands`, `hostProfile`                   | **option, full profile**: licence numbers, chain and brands, the host's own presentation                  |
| `hostContact`                                                                          | **option, host contact**: company name, trade register, registration number, address, e-mail, phone, name of a private host |
| `nearbyPlaces`                                                                         | **option, nearby places**: name, category, distance in km, time on foot and by car (text and minutes), GPS |
| `calendar`                                                                             | **option, price calendar**: date, available, indicative one-night price, minimum stay                     |
| `roomOffers`, `roomOfferCount`                                                         | **option, room offers**: every offer (room, beds, meals, price, taxes, cancellation, rooms left) and how many Booking.com gave |
| `reviews`, `reviewsIncomplete`                                                         | **option, reviews**: the reviews, and whether some could not be read                                      |
| `ratingScores`, `scoreDistribution`                                                    | **option, reviews**: score per category with the city average, number of reviews per score band           |
| `reviewsByLanguage`, `reviewsByTravelerType`, `reviewsBySeason`, `reviewTopics`        | **option, reviews or review summary**: number of reviews per language, per type of traveler and per season, and the topics guests mention (Location, Breakfast…) |
| `reviewSummary`, `reviewTopicScores`                                                   | **option, review summary**: Booking.com's summary, score per topic and per traveler type                  |
| `rank`, `searchLocation`, `searchUrl`, `totalResults`, `cityId`, `scrapedAt`           | position in the search, what the property was found for, the search page, properties of the search, city id, ISO timestamp |

### 💡 Tips

#### How to get more results

Set `maxItems` to `0`: a search that holds more than 1,000 properties is cut into map areas automatically and read in full (those properties come without a rank and not in the order you asked). Give each destination its own cap with `maxItemsPerQuery` so that one big city does not use up the whole budget.

#### How to reduce costs

The price is per property plus what the options you tick deliver, so the levers are `maxItems`, `maxItemsPerQuery`, the filters Booking.com applies itself (a filtered-out property is never read), `maxRoomOffersPerHotel`, `calendarDays` and `maxReviewsPerHotel`, and `onlyNew` for recurring runs (you never pay twice for the same property). Leave an option unticked when you do not need it.

#### Several sources in one run

Fill `locations`, `hotelNames`, `hotelIds`, `startUrls` and / or a map point: the Actor runs one search per destination, name, id, link and map point. A property found by several searches is saved — and charged — once. Without `maxItemsPerQuery` the first searches can use up the whole `maxItems` budget.

#### Monitoring: only the new properties

Tick **Only new properties** (`onlyNew`) and schedule the Actor. The first run returns everything; each later run skips the properties already delivered: they are not saved, not charged, and their profile is not fetched. The memory lives in a named key-value store of your account (`booking-hotels-scraper-seen`, up to 150,000 properties per key) and is only updated with properties that really reached the dataset, so a failed run never hides anything. With **Only new properties**, a property that your own filters drop (exact rating, minimum reviews, excluded words or ids) is checked (and charged the small filter fee) once; the next runs with the same filters skip it for free. The exception is a property that does not pass a count that only grows yet (the minimum number of reviews): it is checked again on the next run, and charged the small filter fee again while it is still refused, so it is delivered as soon as it passes. Change a filter, or tick **Reset the memory**, to check them again. Give each schedule its own `stateKey` (two schedules sharing a key would hide each other's properties), and tick `resetState` once to start over. Booking.com has no "newest first" order, so a monitoring run still reads the whole search and saves only what it has not delivered before. To follow the new reviews of known properties instead, set `reviewsAfter` to a short period (`7 days`) with `reviewsSort` set to `NEWEST_FIRST`.

#### Choose the stay

Prices on Booking.com only exist for a given stay. With **Check-in date** empty the Actor uses a stay that starts 30 days from the run date, for 1 night, so a saved task never goes stale; use a period such as `60 days` to keep the same distance ahead.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per Booking.com property. Actor id: `nice_dev/booking-hotels-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/booking-hotels-scraper`.

Smallest input, for a cheap first call:

```json
{
    "location": "Paris",
    "maxItems": 10
}
```

Key output fields: `name`, `url`, `starRating`, `rating`, `reviewCount`, `price`, `currency`, `isAvailable` and `address`. The options (`roomOffers`, `calendar`, `reviews`…) are `null` unless ticked.

Cost: see the pricing section above and the Pricing tab. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

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

The Actor only reads what Booking.com shows publicly to any anonymous visitor. It logs in to nothing and solves no captcha. Results can contain personal data (a reviewer's first name and country, the name of a private host), which is protected by GDPR: do not store it without a legitimate reason. The host contact option returns business contact details that Booking.com publishes for trader traceability; you stay responsible for how you use them (marketing, GDPR). You are responsible for using the data in compliance with Booking.com's Terms of Use and applicable law. This Actor is not affiliated with Booking.com.

#### Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

#### Are the prices the ones I see on Booking.com?

They are the prices Booking.com shows to a visitor who is not logged in, for the stay and the currency you asked for: `price` is for the whole stay with the taxes Booking.com includes, `taxesAndFeesExcluded` is what is paid on site on top, and `priceWithAllTaxes` is the sum. When Booking.com only writes that additional charges may apply, without an amount (often the city tax per person), both are null and `priceNote` carries its words. In some markets Booking.com shows visitors who are not logged in a price that already takes off a Genius member discount, with a "log in to get this price" note: `price` is that shown price, and the discount is listed in `discounts` (its name says Genius), so you can add it back for the price without an account (`isGenius`, with the full profile option, only says whether the property takes part in the programme). Prices are live: two runs a few minutes apart can differ.

#### Is the data safe to open in Excel or to show on a web page?

Names, descriptions and review texts are written by third parties, copied as they are. A text can begin with `-`, `+`, `=` or `@`: Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import the text columns as text. `descriptionHtml` (full profile option) and the review summary carry the HTML markup Booking.com sends, and the Actor does not sanitize it: strip or escape it before showing it on a web page, and escape every other field like any text written by a stranger.

#### Known limitations

- **Dates**: with no check-in date the stay starts 30 days after the run date and lasts 1 night (or the **Nights** you set). Booking.com gives no price without dates, so there is no "no dates" mode.
- **Currency and language**: Booking.com converts the prices to the currency you ask for. If a search comes back in another currency, the log says so and `currency` tells which one the prices are in. Every amount has the decimals of its currency (whole numbers in JPY or KRW, cents in EUR or USD), as Booking.com shows it. Names, descriptions and labels come in the language you pick when Booking.com has them in it; reviews and guests' questions stay in the language of their author.
- **Distances** come as Booking.com words them in the language asked (miles with `en-us` for instance); `distanceFromCenterKm` and the distances of `nearbyPlaces` are always converted to kilometres.
- **Calendar prices** (option) are indicative: the price of a day is the price of a stay of ONE night that starts that day, for one room and the guests you asked (asking for 2 rooms does not change it), rounded to the unit, and it is the same whatever `nights` is. In Europe it usually equals the bookable price rounded; it can differ, because Booking.com may leave some discounts in (a New York hotel showed 418 against 282.52 bookable). The exact price of your stay is `price`.
- **Room offers** (option): the `price` of an offer is for ONE room of that type for the whole stay. With 2 rooms asked each offer still shows the price of one room, while `price` of the row is the total of all the rooms asked.
- **Property by link, name or id**: `region` is empty, and so are `rank` and `totalResults`. The property appears only if Booking.com lists it for your dates: otherwise the log says it is sold out or not bookable for them.
- **Names**: Booking.com completes a name from its start ("Lutetia Paris", not "Hotel Lutetia Paris"). When no property has exactly that name the closest one is taken and the log says so, with its id.
- **Reviews**: a property's reviews are saved up to 6 MB per row; past that the row is saved with the reviews read so far and `reviewsIncomplete` is `true`. With `maxReviewsPerHotel` at `0` ("every review") the maximum cost of the run counts 5,000 reviews per property. Filters Booking.com does not apply itself (review dates, exact rating range) are applied by the Actor: after 1,000 reviews read and dropped for a property it stops reading its reviews and the row says `reviewsIncomplete`. With the newest first order and `reviewsAfter` it stops by itself at the first review that is too old. With many reviews per property the Actor reads fewer properties at a time so the run fits in its memory (the log says so): more memory means more properties at a time. For every review (`0`) or several thousand reviews per property, give the run more memory (Run options → Memory): when it is too small, the log says so at the start, with the memory to give.
- **Genius prices** are never returned (a logged-in account is needed).
- **Filters the site does not know** (a wrong `rawFilters` value) are ignored by Booking.com without an error: the log warns when a filter you set was not applied, and the results are then NOT filtered by it.
- **1,000 results per search** is what Booking.com serves; the Actor goes past it for a destination or a link by cutting the map into areas, and the properties found that way come without `rank` or `totalResults`, without `distanceFromCenter` (Booking.com gives a distance from the centre of a place, not from a map area) and not in the order asked. A city search keeps only the properties of that city (the map areas reach into the towns around it: those are left out, not saved, not charged, and counted in the summary of the log); for a country or a region it keeps those of its country; for a district, a landmark or an airport there is no such rule, so a few properties just beyond its edge can come back. A search by map point (`latitude`, `longitude`, `radiusKm`) is not cut: it gives at most the 1,000 nearest properties. The count of a search moves by a few units between two calls (live availability), and Booking.com repeats a few properties from one page to the next: each property is saved once.
- `onlyNew` remembers property ids, not their content: a property whose price changed is not returned again, and a property your filters dropped is not checked again while the filters stay the same, except for the minimum number of reviews (a property under the minimum is checked again on the next run, as its reviews may have grown).
- Two runs sharing the same `stateKey` at the same time may both return the same new property.

**A run that reaches its timeout** stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with `onlyNew`, remembered, and the run ends *Succeeded* with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).

**A run the platform stops without warning** (out of memory)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the properties already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the properties it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the properties of its last 2 seconds once more.

#### Something doesn't work?

The last line of the log counts the properties saved, filtered out and no longer on Booking.com (removed while the run was reading them), and the requests that failed after every retry. Those requests and the removed properties are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. The line also counts the hotel names and property links of your input that Booking.com does not have: they are skipped with a warning in the log and the other sources are read. A run that saved nothing and had failed requests fails, and its last message gives the cause.

If Booking.com changes its pages, you are told instead of paying for blank rows. A results page that counts properties but gives none the Actor can read is an error (listed in `FAILED_REQUESTS`), never a quiet "No properties found". If the first 20 properties read all lack their name or their type, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first properties are charged. A run of fewer properties (a scheduled `onlyNew` run that finds a few new ones, a small **Max properties**) is checked at its end, from 5 properties: its properties are already saved, and the run fails with the missing field instead of ending green.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which requests failed and why.

# Actor input Schema

## `location` (type: `string`):

A city, region, district, airport or landmark, as typed in the Booking.com search box (e.g. `Paris`, `Tuscany`, `Orly Airport`, `Eiffel Tower`). Booking.com resolves it the way its own search bar does. Empty = no destination from this field.

## `locations` (type: `array`):

Several destinations in one run: one search per destination. Added to **Destination**. Properties found by several searches are saved once.

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

Booking.com search-result URLs copied from the address bar (`https://www.booking.com/searchresults.html?ss=Paris&checkin=...`): their dates, guests, rooms, currency and filters (`nflt`) are kept - or single property URLs (`https://www.booking.com/hotel/fr/<name>.html`, in any site language). Added to the destinations, hotel names and map point of this form: all of them run together. Max 1 000 URLs.

## `hotelNames` (type: `array`):

Properties named as you would type them on Booking.com (e.g. `Hotel Lutetia Paris`): each name is looked up in Booking.com's own suggestions before the run and the property it proposes is read, with its price for your dates. Added to the other sources.

## `hotelIds` (type: `array`):

Booking.com numeric property ids (the `propertyId` of a result, e.g. `54642`): each one is looked up through Booking.com's own search and read with its price for your dates. Added to the other sources.

## `latitude` (type: `number`):

Latitude of a map point (e.g. `48.8584`). Use it with **Longitude** and **Radius**: properties around that point, nearest first, until the first one beyond the radius. Added to the other sources.

## `longitude` (type: `number`):

Longitude of the map point (e.g. `2.2945`). Both **Latitude** and **Longitude** are needed, or neither.

## `radiusKm` (type: `number`):

Search radius around the map point, in kilometres. Only used with **Latitude** and **Longitude**.

## `checkIn` (type: `string`):

First night: a date (`2026-12-20`), or a period from the run date such as `7 days`, `2 weeks` or `1 year` - a saved task then always looks the same distance ahead. Empty = 30 days from the run date. Booking.com takes bookings up to about 495 days ahead: a later date is refused.

## `checkOut` (type: `string`):

Departure day, `YYYY-MM-DD`. Empty = check-in plus **Nights** (the way to keep the length of a stay whose check-in moves with the run date). Must be after the check-in date, at most 30 nights after check-in.

## `nights` (type: `integer`):

Length of stay, used when **Check-out date** is empty.

## `flexWindow` (type: `integer`):

Let Booking.com move the stay up to this many days before or after **Check-in date** for each property, as its "flexible dates" search does: each result is priced for its best dates (`stay`, `datesAdjusted`) and more properties are found. 0 = exact dates. The site offers 1, 2, 3 and 7.

## `adults` (type: `integer`):

Adults for the whole stay (all rooms together, as on the Booking.com search box).

## `children` (type: `integer`):

Children for the whole stay. When above 0, fill **Children ages** with one age per child.

## `childrenAges` (type: `array`):

One age (0-17) per child, in the same order as on the site. Must hold exactly **Children** values.

## `rooms` (type: `integer`):

Number of rooms requested. Not above the number of adults: Booking.com needs at least one adult per room and ignores the rooms in excess.

## `currency` (type: `string`):

Currency of every price (`EUR`, `USD`, `GBP`...). Booking.com converts server-side. Each result also gives the price in the property's own currency when it differs (`priceInHotelCurrency`). A search URL pasted in **Start URLs** keeps its own `selected_currency`.

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

Booking.com language of names, descriptions, texts and reviews' labels. `distanceFromCenterKm` is always in kilometres, whatever the language (the text `distanceFromCenter` follows the language: miles with `en-us`). A search or property URL pasted in **Start URLs** keeps its own language (the one in its address: a language code before html such as fr, or lang=fr); an address with none, or a language not in this list, uses this one.

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

Order asked from Booking.com for a destination or a pasted search link. Ignored for a map point (always nearest first) and for hotel names, property ids and property links (one property each). `popularity` (Our top picks) is the site's default ranking; the other orders sort by the criterion they name (price, stars, score, distance from downtown). Whatever the order, Booking.com repeats a few properties from one page to the next: the Actor absorbs them by de-duplicating, so the first N results can vary slightly between two runs.

## `maxItems` (type: `integer`):

Maximum number of properties saved for the whole run (after de-duplication and filters). 0 = no limit - a big city holds thousands of properties (Rome: more than 5 000); the Actor splits the map into tiles to go past the 1 000 results the site serves per search.

## `maxItemsPerQuery` (type: `integer`):

Cap for EACH search (destination, hotel name, map point or search URL), so the first one cannot use up the whole **Max properties** budget. 0 = no per-search cap.

## `extractDetails` (type: `boolean`):

Description, every photo, grouped amenities, house rules (children, beds, pets, payment, deposit), check-in / check-out times, all the category scores, languages spoken, licence numbers, chain and brand, host profile, full address with postal code. One request per property, charged apart (see Pricing). Off = search-result fields only (name, stars, price, rating, address, GPS, one photo). The company / host contact details are a separate option below.

## `includeRoomOffers` (type: `boolean`):

Add every room offer of each property for your dates (`roomOffers`): room name, size, occupancy, beds, meal plan, price of one room for the whole stay, crossed-out price, taxes included, free cancellation and its date, prepayment, rooms left - the whole room list of the property page, not only the recommended offer (`price`, always there). One request more per property; charged per offer saved (see Pricing). A sold-out property has no offer and costs nothing for this option.

## `maxRoomOffersPerHotel` (type: `integer`):

Cap on the room offers saved for each property, in Booking.com's own order. 50 covers almost every property (2 to 87 offers measured for 2 adults and 2 nights); `roomOfferCount` always says how many Booking.com gave. Your maximum cost counts each property at this many offers.

## `includeCalendar` (type: `boolean`):

Add, day by day from the check-in date, whether the property is bookable, an indicative price and the minimum stay (`calendar`), for your guests. The price of a day is for a ONE-night stay that starts that day, for one room, rounded to the unit; it may not take off some discounts, so the exact price of your stay is `price`. One request per 61 days; charged per day saved (see Pricing).

## `calendarDays` (type: `integer`):

Number of days of the price calendar, counted from the check-in date. The site serves 61 days per request: 365 days = 6 requests per property. Booking.com serves no day beyond about 495 days ahead: the calendar stops there.

## `includeNearbyPlaces` (type: `boolean`):

Add the places around each property (`nearbyPlaces`): airports, landmarks, restaurants and cafes, public transport, beaches, natural beauty - name, category and distance. One request per property; charged per property enriched (see Pricing).

## `includeHostContact` (type: `boolean`):

Add the company or host that runs each property (`hostContact`), as Booking.com publishes it for trader traceability: company name, registration number, address, e-mail, phone and, for a private host, the name. These are business contact details published by the site; you stay responsible for how you use them (marketing, GDPR). One request per property, shared with **Extract full property profile** when both are on; charged per contact found (see Pricing).

## `includeReviews` (type: `boolean`):

Add the guest reviews to each property (`reviews`), charged per review saved (see Pricing). One request per 25 reviews, read only as far as **Max reviews per property** or a review filter needs. Off = only the score and the review count. The same request also gives the number of reviews per language, traveler type and season and the topics guests mention (`reviewsByLanguage`, `reviewsByTravelerType`, `reviewsBySeason`, `reviewTopics`), at no extra charge.

## `includeReviewSummary` (type: `boolean`):

Add Booking.com's own summary of the guest reviews (`reviewSummary`: pros and cons with how many reviews mention them) and the scores by topic and traveler type (`reviewTopicScores`), charged per property that has them (see Pricing). The number of reviews per language, traveler type and season and the topics guests mention (`reviewsByLanguage`, `reviewsByTravelerType`, `reviewsBySeason`, `reviewTopics`) come with it, at no extra charge. Works without **Include reviews**: read in a request the Actor already makes when possible, else one small request per property.

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

Cap on the reviews saved for each property. 0 = every review the site serves (the full history: a big hotel holds 9 000 and more). A property whose reviews could not all be read is saved with the ones read so far and `reviewsIncomplete: true`. Each review saved is charged on its own (see Pricing).

## `reviewsSort` (type: `string`):

Order of the saved reviews: with the cap on reviews per property, it picks which ones are kept. `NEWEST_FIRST` is the order to use with **Reviews after**.

## `reviewsLanguages` (type: `array`):

Keep only the reviews written in these languages, as two-letter codes (`en`, `fr`, `de`, `es`, `it`, `nl`...). Asked from Booking.com. Empty = every language.

## `reviewsTravelerType` (type: `string`):

Keep only the reviews of this type of traveler. Asked from Booking.com.

## `reviewsScore` (type: `string`):

Keep only the reviews in this score band of Booking.com (out of 10). Asked from Booking.com; for an exact range use **Minimum review rating** and **Maximum review rating**.

## `reviewsTimeOfYear` (type: `string`):

Keep only the reviews of stays in this season. Asked from Booking.com.

## `reviewsSearchText` (type: `string`):

Keep only the reviews that mention this word or phrase (e.g. `breakfast`). Asked from Booking.com.

## `reviewsAfter` (type: `string`):

Keep only the reviews written on or after this date: `2026-01-01`, or a period before now such as `7 days`, `3 months`, `1 year`. `7 days` with a schedule = the new reviews only.

## `reviewsBefore` (type: `string`):

Keep only the reviews written on or before this date (the whole day is included).

## `reviewsMinRating` (type: `number`):

Keep only the reviews scored at least this (out of 10). 0 = every review.

## `reviewsMaxRating` (type: `number`):

Keep only the reviews scored at most this (out of 10). 0 = every review. Set it low to collect complaints only.

## `minPrice` (type: `number`):

Keep properties whose price per night is at least this, in **Currency**. 0 = no filter. Asked from Booking.com.

## `maxPrice` (type: `number`):

Keep properties whose price per night is at most this, in **Currency**. 0 = no filter. Asked from Booking.com.

## `minStars` (type: `integer`):

Keep properties with at least this many stars (1-5). 0 = no filter. Asked from Booking.com. Properties with no star rating are dropped when this is set.

## `maxStars` (type: `integer`):

Keep properties with at most this many stars. 0 = no filter. Asked from Booking.com. Properties with no star rating are dropped when this is set.

## `minRating` (type: `number`):

Keep properties whose guest score is at least this (Booking.com scores out of 10). 0 = no filter. The site is asked for the step just below (6, 7, 8 or 9), then the exact score is checked. Properties without any review are dropped when this is set.

## `minReviewCount` (type: `integer`):

Keep properties with at least this many reviews. 0 = no filter.

## `propertyTypes` (type: `array`):

Keep only these types of property. Asked from Booking.com, so the other types are never read. Empty = every type.

## `amenities` (type: `array`):

Keep only the properties that have ALL the ticked amenities (the site's own amenity filters). Asked from Booking.com. Empty = no filter.

## `mealPlan` (type: `string`):

Keep only the properties with this meal option. Asked from Booking.com.

## `freeCancellationOnly` (type: `boolean`):

Keep only the properties with free cancellation for your stay. Asked from Booking.com.

## `maxDistanceFromCenterKm` (type: `string`):

Keep only the properties within this distance of the center of the destination. Booking.com offers three steps (1/2 mile, 1 mile and 2 miles, shown here in kilometres). Asked from Booking.com.

## `chains` (type: `array`):

Keep only these brands, by name as listed on Booking.com (e.g. `ibis`, `Mercure`, `Best Western`) or by brand ID (e.g. `1053`). One brand or more: a property of any of them is kept. Asked from Booking.com. Empty = no filter.

## `rawFilters` (type: `string`):

Any filter of the site that has no field above, as Booking.com writes it in a search URL (`nflt`): e.g. `class=4;review_score=80` or `ht_id=204;hotelfacility=107`; `stay_type=2` keeps adults-only properties (`stay_type=1` pets allowed, `stay_type=4` LGBTQ+ friendly: the site's "Travel group" filter). Separate filters with `;`. Combined with the fields above. A filter the site does not know is ignored by Booking.com, without error.

## `availableOnly` (type: `boolean`):

Leave out the properties with no bookable room for your dates (asked from Booking.com in a search by place, so they are never read; a property searched by link, name or id is dropped when its own card says sold out). Off =the site's own list, which may keep some sold-out properties (`isAvailable: false`, no price).

## `excludeKeywords` (type: `array`):

Drop the properties whose name contains one of these words (case and accents ignored).

## `excludePropertyIds` (type: `array`):

Booking.com property ids to skip, even when they match the search (e.g. your own hotels).

## `onlyNew` (type: `boolean`):

Skip the properties that a previous run (same **Memory key**) already delivered: they are not saved and not charged, and their profile is not even fetched. First run = everything is new.

## `stateKey` (type: `string`):

Name of the memory used by **Only new properties**. Give each schedule / task its own key (e.g. `paris-hotels`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every property again. Untick it afterwards.

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

Apify Proxy or your own proxies. Keep the default: it is included in the price. The residential Apify proxy is not available in this Actor.

## `maxConcurrency` (type: `integer`):

Maximum number of requests processed in parallel.

## `maxRequestsPerMinute` (type: `integer`):

Most requests to the site in any 60 seconds, all of them counted: results pages, listing pages, the extra page read for a listing and, before the crawl, the lookups of hotel names and property links. A budget, not an even pace: up to this many can leave at once when the minute starts (spread them with the minimum delay below). Lower it if the site answers HTTP 429 / 403 in the log.

## `minRequestIntervalMs` (type: `integer`):

Smallest gap between two requests, in milliseconds. Unlike the per-minute rate, this spreads the requests evenly instead of letting them go out in a burst. 0 = no gap.

## `maxRequestRetries` (type: `integer`):

Retries per request before it is marked as failed. Behind a proxy, a request the site turns away is also retried on a new proxy session up to 10 times without using up these retries.

## `debugLog` (type: `boolean`):

Include debug messages in the run log.

## Actor input object example

```json
{
  "location": "Paris",
  "locations": [],
  "startUrls": [],
  "hotelNames": [],
  "hotelIds": [],
  "radiusKm": 2,
  "nights": 1,
  "flexWindow": 0,
  "adults": 2,
  "children": 0,
  "childrenAges": [],
  "rooms": 1,
  "currency": "EUR",
  "language": "en-gb",
  "sortBy": "popularity",
  "maxItems": 20,
  "maxItemsPerQuery": 0,
  "extractDetails": false,
  "includeRoomOffers": false,
  "maxRoomOffersPerHotel": 50,
  "includeCalendar": false,
  "calendarDays": 61,
  "includeNearbyPlaces": false,
  "includeHostContact": false,
  "includeReviews": false,
  "includeReviewSummary": false,
  "maxReviewsPerHotel": 25,
  "reviewsSort": "NEWEST_FIRST",
  "reviewsLanguages": [],
  "reviewsTravelerType": "ALL",
  "reviewsScore": "ALL",
  "reviewsTimeOfYear": "ALL",
  "reviewsMinRating": 0,
  "reviewsMaxRating": 0,
  "minPrice": 0,
  "maxPrice": 0,
  "minStars": 0,
  "maxStars": 0,
  "minRating": 0,
  "minReviewCount": 0,
  "propertyTypes": [],
  "amenities": [],
  "mealPlan": "any",
  "freeCancellationOnly": false,
  "maxDistanceFromCenterKm": "any",
  "chains": [],
  "availableOnly": true,
  "excludeKeywords": [],
  "excludePropertyIds": [],
  "onlyNew": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "maxRequestsPerMinute": 120,
  "minRequestIntervalMs": 0,
  "maxRequestRetries": 5,
  "debugLog": 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 = {
    "location": "Paris",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/booking-hotels-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 = {
    "location": "Paris",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/booking-hotels-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 '{
  "location": "Paris",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/booking-hotels-scraper --silent --output-dataset

```

## MCP server setup

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