# Booking.com Scraper: Hotel Prices and Availability (`automation_craft/booking-scraper`) Actor

Scrape Booking.com hotels and homes by place, link, property id or map area, past the 1,000 result cap, no login. Rows: price for your dates with taxes and fees, stars, guest score, free cancellation, meals; add rooms and rates, price calendar, reviews. JSON, CSV, Excel, API; pay per property.

- **URL**: https://apify.com/automation_craft/booking-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** Travel, E-commerce, Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.67 / 1,000 properties

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 Scraper: Hotel Prices and Availability

**Booking.com scraper and API** for hotels, apartments, homes and every other stay on Booking.com: search any city, region, district, landmark, airport or country, paste Booking.com search or property links, give property ids, or draw a map area. Every property comes with the price for your dates and guests, the taxes and charges Booking.com lists apart, discounts, stars, guest score and review count, address, map position, distance from the centre, free cancellation, meal plan, rooms left and the main photo. Turn on **Property details** for every room and rate of the stay, the description, facilities, house rules, category scores, photos, surroundings and the host's business details, **Price calendar** for a day by day calendar of up to 365 days, and **Guest reviews** for the reviews with their own filters.

No login, no cookies to give and no browser: the Actor reads Booking.com's own site data service through Apify's datacenter proxy (included in the price) and runs on 256 MB. It reads on past the 1,000 properties Booking.com shows for one search: on the platform, one Lisbon run delivered 3,373 properties in about 6 minutes, its search marked complete.

#### What you can do with it

- Rate shopping: the prices of a city's hotels for every check-in day of the next weeks (`checkInWindowDays`, up to 60 days, one search per day), with the taxes and charges on every row.
- Track the prices of the hotels you compete with on a schedule: relative dates (`checkInDaysFromToday`, `nights`) keep a scheduled run on "14 days from today" every time.
- Size a market: the number of properties Booking.com reports for a search, and with `includeFilterCounts` every filter of the search with its count (stars, property type, price band, district, brand and more).
- Read the full room and rate grid of a list of properties by link or id, with cancellation and prepayment terms per rate.
- Collect guest reviews by traveller type, score band, season, keyword, language or date window, for sentiment and quality work.
- Build a list of hotels and their business details (company, register number, e-mail, phone, address) where Booking.com shows them in the property's legal block.

### How to use the Booking.com Scraper

1. Open the Actor and type one or more places in **Places to search**, for example `Paris`, `Tuscany`, `Le Marais, Paris` or `Eiffel Tower`, or paste links into **Booking.com links**, ids into **Booking.com property ids**, or a circle or box into **Map areas**.
2. Set the stay: fixed dates (**Check-in date**, **Check-out date**) or **Check-in in N days** and **Nights** (when you give neither: 14 days from the run's day, 2 nights), plus **Adults** (default 2), **Children's ages**, **Rooms**, **Currency** (default USD) and **Language**. A pasted Booking.com link keeps its own dates, guests and currency unless you set them here.
3. Add any filters (price per night or per stay, stars, guest score, property types, free cancellation, meals, facilities and more) and set **Maximum properties per run**.
4. Turn on **Property details**, **Price calendar** or **Guest reviews** if you need them.
5. Click **Start**. Download the rows as JSON, CSV, Excel, XML or HTML, or read them through the Apify API. The run report is in the run's key-value store as `REPORT.html`.

### What data you get

One Property row per property and stay (`type: "property"`), one Review row per guest review when Guest reviews is on (`type: "review"`), and free rows: a search row per search (`type: "search"`), a review walk row per property (`type: "reviews"`), status rows for every miss (`type: "status"`; a property asked by link, id or list that has no offer for your stay gets `not_available` with its `reason`: sold out, the check-in day closed, a longer minimum stay with the nights, no room offered, every day of the stay open yet no offer for your guests, or `unknown` when Booking.com's answer names no cause; Booking.com also flags a stay shorter than the minimum stay as sold out, so the Actor reads the property's date picker first, and a sold out row whose date picker could not be read says so) and one run summary (`type: "summary"`).

| Field | What it holds | Filled |
|---|---|---|
| `id`, `name`, `url`, `pageName` | Booking.com property id, name, the property link with your stay, guests and currency | 100% |
| `propertyType`, `propertyTypeId` | Hotel, Apartment, Hostel, Villa and so on, and Booking.com's type id | 100% |
| `stars` | star rating, 1 to 5 | 90% |
| `reviewScore`, `reviewScoreWord` | guest score out of 10 and its word (Wonderful, Very good) | 93% (every property with a review) |
| `reviewCount` | number of guest reviews (0 when none) | 100% |
| `secondaryScore` | a second score Booking.com shows, such as Location | 54% |
| `externalReviewScore`, `externalReviewCount` | the score from outside reviews Booking.com shows | 16% |
| `address` | street address | 98% (see below) |
| `city`, `countryCode`, `displayLocation` | city, two letter country code and Booking.com's location line | 100% |
| `latitude`, `longitude` | map position | 100% (see below) |
| `district` | the district Booking.com names | 24% |
| `distanceFromCentre`, `isCentrallyLocated` | Booking.com's distance text from the centre | 100% |
| `distanceFromSearchKm` | straight line km from the searched place or point | places and map areas |
| `publicTransport`, `beachDistance`, `skiLiftDistance` | Booking.com's distance texts | 65%, 2%, where shown |
| `checkIn`, `checkOut`, `nights`, `adults`, `childrenAges`, `rooms` | the stay the price is for | 100% |
| `recommendedDates`, `searchedDates` | flexible dates: the stay Booking.com priced and the dates you searched | flexible searches |
| `price.total`, `price.currency` | price for the whole stay in the run's currency | 100% |
| `price.perNight` | price per night (Booking's own average, which can differ from the stay price over its nights, or that when Booking leaves it out) | 100% |
| `price.excludedTaxesAndCharges`, `price.charges` | the taxes and charges Booking.com lists apart (city tax, cleaning fee), each with its mode and amount | 99% |
| `price.chargesInfo`, `price.taxNotes` | Booking.com's note on what the price includes | 5% |
| `price.totalWithTaxesAndCharges` | the stay's price with them | 100% |
| `price.beforeDiscount`, `price.discounts` | the price before discount and each discount by name | 43% |
| `price.badges` | Booking.com's price badges (Limited-time deal, Getaway Deal) | 18% |
| `price.totalInPropertyCurrency`, `price.propertyCurrency` | the price in the property's own currency | 97% |
| `freeCancellation`, `freeCancellationUntil` | free cancellation and until when | 24% |
| `noPrepayment` | a rate you pay at the property | as shown |
| `mealPlan`, `breakfastIncluded` | the meal plan of the shown rate; breakfast read from its text (null when the text is in a language the check does not read) | 19% |
| `onlyLeft` | "We have 1 left at this price" as a number and text | 57% |
| `unit`, `roomsOffered` | the matched unit (bedrooms, bathrooms, beds, kitchens, area) and every unit offered for the stay | 100% |
| `thirdPartyInventory` | the shown price is a partner (third party) offer Booking.com lists | 7% |
| `sponsored`, `preferredPartner`, `preferredPlus`, `geniusDiscount`, `newlyOpened` | Booking.com's own flags | as shown |
| `sustainable`, `sustainabilityCertifications` | sustainability certification | as shown |
| `hostType`, `personalDataHidden` | `professional` or `private` host; `personalDataHidden` is always false (kept so existing integrations keep working) | private hosts: 15% of properties |
| `photo`, `photoSmall` | main photo links | 100% |
| `position` | the row's place in Booking.com's order | searches |
| `outsideDestination` | a property Booking.com added from outside the destination (with `includeNearbyProperties`) | with the setting |
| `search` | the search that found the row | 100% |

Measured on the final platform matrix of 2026-11-02 (build 0.1.13, `platform-results/matrix-rf9.json`): the 401 property rows (346 properties) of its 42 runs that deliver full rows (the runs with `outputFields` left out), one row per property and stay (the last read when several runs met it). That build left out the street address and position of private hosts' lets (62 of the 399 rows); every build since 0.1.15 delivers them, so the address and position figures above are that matrix's figures with those rows added.

#### Property details (add-on)

`details` on the Property row (four reads per property, charged only when all four answered):

- `rooms` (100% of properties): every room of the stay with its `rates` (price, per night, taxes and charges, discounts, meal plan, cancellation and prepayment terms, rooms left, maximum guests), the room's size, beds, bathrooms, floor, cribs and extra beds, its `highlights` (Private bathroom, Balcony, View) and its `facilities` by category (bathroom, bedroom, kitchen, media), photos.
- `partnerRooms` (83%): partner rooms by supplier and supplier room code.
- `description`, `finePrint`, `fullAddress`, `street` (95%), `postalCode` (98%), `district`, `checkIn` and `checkOut` times, `houseRules`, `acceptedCards`, `pets`, `children` (child and extra bed policy), `facilities` and `facilityGroups`, `meals`, `languagesSpoken`, up to 60 `photos` with captions, `licenseNumbers` (14%), `trader` (the legal block: company, register, registration number, e-mail, phone, address), `host` (a host's profile, 8%).
- `categoryScores`: each category score (Staff, Cleanliness, Location, Value for money) with the destination's band for it (`destinationLow`, `destinationHigh`: the range of that score among the destination's properties).
- `reviewSummary` (92%): Booking.com's summary of the reviews, the pros and cons it lists with how many reviews mention each.
- `surroundings`: airports, top landmarks, nearby places, restaurants, cafes and bars, metro, train and bus stops, beaches and nature (peaks, lakes, forests), each with its straight distance in km, position, and Booking.com's walking and driving distance and time.

Measured on the 64 distinct properties read with details in the final matrix (every run). A row whose details were not all read is delivered with `detailsStatus` saying why and without the details charge.

#### Price calendar (add-on)

`calendar` on the Property row: one entry per day from the run's day (default 61 days, up to 365): `date`, `available` (a stay can start that day), `price` (Booking.com's date picker price per night, a display figure, not a bookable rate; `priceRounded` is true where Booking.com shows it abbreviated, such as "¥81.3K", read as 81,300) and `minStay`. Every one of the 3,720 available days of the final matrix carried a price (55 of them abbreviated by Booking.com and flagged `priceRounded`, JPY). `calendarSummary` gives the days, the share available and the lowest, average and highest price.

#### Guest reviews (add-on)

One row per review: `score`, `title` (39%), `liked` (61%), `disliked` (50%), `language` (Booking.com's own codes: `en`, `es`, `de`, and `xu` for American English, `xb` for Brazilian Portuguese), `postedAt`, `stayCheckIn`, `stayCheckOut`, `nights`, `roomName`, `travellerType`, `reviewerName` (first name), `reviewerCountry` (100%), `ratingOnly` (35% are rating only reviews), `helpfulVotes`, `propertyReply` (33%) and `photos`. Measured on the 4,749 distinct reviews of the final matrix (every run). The free review walk row per property gives Booking.com's review count, how many were delivered and the category scores.

#### Free files

- `REPORT.html` in the run's key-value store: every search with Booking.com's count, how many were delivered and whether it is complete.
- `MAP.kml` with **Map file (KML)** on: the delivered properties as pins for Google Earth or My Maps, coloured by guest score or price (**Map pin colour**), up to 50,000 points.

#### Example row (shortened)

```json
{
  "type": "property",
  "id": "318045",
  "name": "Hotel Lunetta",
  "url": "https://www.booking.com/hotel/it/lunetta.html?checkin=2026-11-16&checkout=2026-11-18&group_adults=2&no_rooms=1&group_children=0&selected_currency=USD",
  "propertyType": "Hotel",
  "stars": 4,
  "reviewScore": 9.4,
  "reviewScoreWord": "Wonderful",
  "reviewCount": 1145,
  "address": "Piazza Del Paradiso 68",
  "city": "Rome",
  "countryCode": "it",
  "latitude": 41.8958944615465,
  "longitude": 12.4738530814648,
  "distanceFromCentre": "0.7 km from downtown",
  "checkIn": "2026-11-16",
  "checkOut": "2026-11-18",
  "nights": 2,
  "adults": 2,
  "price": {
    "currency": "USD",
    "total": 634.06,
    "excludedTaxesAndCharges": 33.49,
    "totalWithTaxesAndCharges": 667.55,
    "chargesInfo": "+US$33 taxes and fees",
    "totalInPropertyCurrency": 568,
    "propertyCurrency": "EUR"
  },
  "freeCancellation": true,
  "freeCancellationUntil": "2026-11-12T23:00:00Z",
  "mealPlan": "Breakfast included",
  "onlyLeft": { "count": 1, "text": "We have 1 left at this price" },
  "roomsOffered": [{ "name": "Classic Double Room", "unitId": "31804501", "beds": 1 }],
  "hostType": "professional",
  "personalDataHidden": false,
  "search": { "label": "startUrls[0]", "destination": { "name": "Rome", "type": "CITY", "id": -126693, "countryCode": "it" } }
}
```

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

You pay per row delivered (pay per event). Prices per 1,000 events:

| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| Property | $0.93 | $0.85 | $0.77 | $0.665 |
| Property details (add-on, only when on) | $1.33 | $1.22 | $1.10 | $0.95 |
| Calendar day (add-on, only when on) | $0.40 | $0.365 | $0.33 | $0.285 |
| Review (add-on, only when on) | $0.13 | $0.12 | $0.11 | $0.095 |

Each run also pays a one time Actor start of $0.0025 on every plan. Platinum and Diamond plans pay the Gold price. The Store pricing card shows these same prices per 1,000 events: "$0.93 / 1,000" on the Property row means one property costs less than a tenth of a cent.

- 1,000 properties cost $0.665 to $0.93 plus the $0.0025 start fee ($0.6675 to $0.9325 for the run).
- 1,000 properties with Property details cost $1.615 to $2.26 plus the start fee.
- 100 properties with 30 calendar days each (3,000 days) cost about $0.92 to $1.29 plus the start fee.
- 100 properties with 20 reviews each (2,000 reviews) cost about $0.26 to $0.35 plus the start fee.
- The same property and stay is charged once per run, even when two of your searches find it; the same review is charged once per run.
- Free: properties outside your search or filters, sold out properties, repeats, misses (a place not found, a property not found or not available for your stay), details not read in full (delivered without the details charge), calendar days not read, and every search, status, review walk and summary row. A run with no usable input charges only the start fee.
- Set a maximum cost per run in the Apify Console: the run stops at the first row it cannot pay and delivers no row unpaid; calendar days beyond the limit's room are cut from the row and not charged.

### Input

| Setting | What it does |
|---|---|
| `search` | Places by name: city, region, district, landmark, airport or country (`Paris`, `Tuscany`, `Le Marais, Paris`, `Eiffel Tower`, `Springfield, Missouri`). A name is matched exactly to Booking.com's own destination; a name it does not offer exactly gets a free row listing the closest destinations. A property's full name (`Hotel Adlon Kempinski Berlin`) reads that one property. |
| `startUrls` | Booking.com search links (they keep their own dates, guests, filters and order), property links, and shared list links (`mywishlist.html?wl=...`: every property saved in the list, for the dates saved with it, read through Booking.com's own list service), on www.booking.com, m.booking.com or booking.com. A setting you give replaces the link's own value of that setting. |
| `propertyIds` | Booking.com property ids, each read as one property for your stay. |
| `mapAreas` | A circle `{"latitude": 48.8584, "longitude": 2.2945, "radiusKm": 2}` (0.1 to 50 km) or a box `{"north", "south", "east", "west"}` (at most 1 degree north to south, about 111 km, and 1.5 degrees east to west). |
| `checkIn`, `checkOut` | Fixed dates (at most 90 nights). |
| `checkInDaysFromToday`, `nights` | Relative dates for scheduled runs (default 14 days ahead, 2 nights). |
| `flexibleDays` | Let Booking.com move the stay 0, 1, 2, 3 or 7 days either way: a row then carries the stay Booking.com priced (`checkIn`, `checkOut`, `recommendedDates`) and the dates you searched (`searchedDates`). |
| `checkInWindowDays` | Rate shopping: every search and every property asked by link, id or name once per check-in day for up to 60 days in a row, same nights. |
| `adults`, `childrenAges`, `rooms` | Guests (default 2 adults), one age per child, rooms (default 1). |
| `currency`, `language` | Currency of every price (default USD) and language of the texts Booking.com translates (default en-us). |
| `minPrice`, `maxPrice`, `priceIncludesTaxes`, `priceLimitsPerStay` | Price limits per night, or for the whole stay with `priceLimitsPerStay`; on Booking.com's shown price or, with `priceIncludesTaxes`, on the price with the taxes and charges listed apart. Checked on every row. |
| `stars` | 1 to 5 and `unrated`. |
| `minReviewScore`, `minReviewCount` | Lowest guest score (1 to 10 with one decimal) and fewest reviews. |
| `propertyTypes`, `entireHomesOnly` | Property types to keep (24 types), and entire places only. |
| `freeCancellation`, `noPrepayment`, `bookWithoutCreditCard` | Booking terms. |
| `meals`, `facilities`, `roomFacilities`, `bedTypes`, `minBedrooms`, `minBathrooms` | Meal plans, property and room facilities, bed types, bedrooms, bathrooms. |
| `petFriendly`, `adultsOnly`, `lgbtqFriendly`, `sustainableOnly` | Booking.com's own property flags. |
| `maxDistanceKm` | Leave out properties farther than this from the place's centre. |
| `bookingFilters` | Any other Booking.com filter code from a search link's `nflt` (`di=8` a district, `chaincode=1053` a brand). A star code (`class=`) or guest score code (`review_score=`) only when `stars` or `minReviewScore` is left empty. |
| `includeNearbyProperties` | Keep the properties Booking.com adds from outside the destination (flagged). |
| `sortBy` | 11 Booking.com orders: `popularity`, `price`, `price_from_high_to_low`, `review_score_and_price`, `bayesian_review_score`, `class`, `class_asc`, `class_and_price`, `distance_from_search`, `upsort_bh`, `business_popularity`. |
| `maxItems`, `maxItemsPerSearch` | Property rows for the run and per search. `maxItems` empty means no run cap: each search still stops at Booking.com's 1,000 results (a window of 60 check-in days can then deliver up to 60,000 rows); set it to bound the run's cost. Per search default 1,000; above 1,000 the search is split by property type and price bands to read past Booking.com's limit. |
| `includeDetails`, `maxPropertiesWithDetails` | The Property details add-on, and for how many properties. |
| `includeCalendar`, `calendarDays` | The Price calendar add-on, and how many days (default 61, up to 365). |
| `includeReviews`, `maxReviewsPerProperty` | The Guest reviews add-on, and reviews per property (default 10). |
| `reviewsSort`, `reviewsLanguages`, `reviewsTravellerType`, `reviewsScoreBand`, `reviewsSeason`, `reviewsKeyword`, `reviewsFrom`, `reviewsTo` | Review order and filters, and a date window. |
| `includePersonalData` | Has no effect: all public data is always delivered (kept so saved inputs keep working). |
| `includeFilterCounts` | Every filter of each search with its code and count, on the free search row. |
| `mapFile`, `mapColorBy` | The free KML map file and its pin colour (`score` or `price`). |
| `outputFields` | Keep only these top level fields. |
| `proxyConfiguration` | Apify's datacenter proxy, included (no proxy group or country can be chosen: a run that asks one is refused free); give your own proxy links only if you need them. |

Filters Booking.com applies are also checked on each row where the row shows the value (type, stars, guest score, review count, price, free cancellation, no prepayment, breakfast, sustainability, bedrooms, bathrooms, map area, distance), and a row outside them is skipped free. Property types too: Booking.com's own type filter lists related types, and the Actor keeps only the types you asked for. Filters a row does not show (facilities, room facilities, bed types, other meal plans, pets, adults only) are Booking.com's own.

#### Getting past 1,000 results

Booking.com shows at most 1,000 properties for one search. Set `maxItemsPerSearch` above 1,000 and the Actor splits the search by property type, then by price per night bands, and reads every slice. The free search row says Booking.com's count (`totalReported`), how many properties were met (`propertiesMet`) and delivered, and whether the search is `complete`, or why not (`stoppedBy`).

#### Personal data

Every run delivers all the public data Booking.com shows, whatever the `includePersonalData` setting says (it has no effect and is kept so saved inputs keep working). A property whose host Booking.com labels a private person comes with its street address, map position, distances and, with Property details, the host's name, the EU trader block and the surroundings, exactly as Booking.com serves them. Reviewer first names and countries are part of each review. You are responsible for using personal data lawfully (the GDPR included).

### What this Actor does not do

- No attractions, tours or tickets: those are another Booking.com product.
- No "only new rows since the last run" memory or monitor: schedule the Actor and compare the rows in your own sheet.
- No room rates of partner (third party) offers in Property details: Booking.com's room list does not carry them (8 of 8 properties checked in Paris, Tokyo and Rome). The partner rooms come with their supplier codes (`partnerRooms`), and when the search row's own price is a partner offer the row says so (`thirdPartyInventory`).
- No Genius member prices: Booking.com shows them only to signed in members.
- Shared lists are read through Booking.com's own list service: at launch this was tested against that service's answer shape and live against unknown list links, not yet against a real shared list (one needs a Booking.com account to make).
- The breakfast filter is checked on each row's meal text: in English always; in another language, a text the check does not read is left out free and the search row says so (run in English to read them).
- No concurrency or retry settings: the pace is fixed to Booking.com's own limits.
- A property found by link, id or full name is that property: search settings such as filters do not filter it.
- Booking.com may move properties between pages while a large search is read; the search row then says not complete and how many properties were met.
- The calendar price is Booking.com's date picker figure per night, not a bookable rate; where Booking.com abbreviates it ("¥81.3K") it is read as 81,300 and flagged `priceRounded`.
- Booking.com serves the reviews of the last 36 months only.
- Work that earns nothing has a limit: a long list of places or ids Booking.com does not know, or searches that find no property, stop on that limit, and the rest is counted as not reached in the free summary row (nothing is charged for it).

### FAQ

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

This Actor reads only data Booking.com shows to every visitor without a login. Booking.com's terms restrict automated access to its platform; whether and how you use the data is your decision and responsibility.

#### Does Booking.com have an API?

Booking.com's Demand API is for its Managed Affiliate Partners, who get an API key with the partnership. This Actor works like an API without one: send a JSON input through the Apify API and read the properties, rates and reviews as JSON.

#### How do I get more than 1,000 results from a Booking.com search?

Booking.com shows at most 1,000 properties for one search. Set `maxItemsPerSearch` above 1,000: the Actor splits the search by property type and price bands, and the free search row compares the distinct properties met with Booking.com's own count: it says complete when it met them all, allowing 2 percent for properties Booking.com lists, removes or reorders while the search is read, and otherwise how many were met.

#### Do Booking.com prices include taxes and fees?

Often not: many properties show a price with taxes and charges such as a city tax or a cleaning fee listed apart. Every Property row gives `price.total`, the charges listed apart (`price.excludedTaxesAndCharges`, `price.charges`) and their sum (`price.totalWithTaxesAndCharges`), and `priceIncludesTaxes` applies your price limits to that sum.

#### Can I scrape Booking.com reviews?

Yes, with the Guest reviews add-on: each review is a row with its score, title, liked and disliked text, stay dates, room, traveller type, and the reviewer's first name and country. Filter by traveller type, score band, season, keyword, language and a date window; Booking.com serves the last 36 months of reviews.

#### Why does this Actor run with limited permissions?

It needs nothing beyond its own run storage (the dataset it writes and its own key-value store), so it runs with Apify's limited permissions: it cannot read or change anything else in your account.

### Use it through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~booking-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"search": ["Lisbon"], "checkInDaysFromToday": 30, "nights": 3, "adults": 2, "currency": "EUR", "maxItems": 200}'
```

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("automation_craft~booking-scraper").call(run_input={"search": ["Paris"], "checkInDaysFromToday": 14, "nights": 2, "includeReviews": True, "maxReviewsPerProperty": 20, "maxItems": 50})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
```

The Actor also runs from Apify's MCP server for AI agents, and from Make, Zapier and n8n through Apify's integrations.

### Changelog

- 0.1 (2026-11-02): first version.

### More data tools by Automation Craft

- [Airbnb Scraper: Airbnb Data, Prices, Calendar](https://apify.com/automation_craft/airbnb-scraper)
- [Zillow Scraper: Homes for Sale, Rent and Sold](https://apify.com/automation_craft/zillow-scraper)
- [Idealista Scraper: Spain, Italy, Portugal Homes](https://apify.com/automation_craft/idealista-scraper)
- [Immobiliare.it Scraper: Italy Homes and Agencies](https://apify.com/automation_craft/immobiliare-scraper)
- [realestate.com.au Scraper: Buy, Rent, Sold Prices](https://apify.com/automation_craft/realestate-com-au-scraper)
- [Realtor.com Scraper: Homes for Sale, Rent & Sold](https://apify.com/automation_craft/realtor-com-scraper)
- [Luma Event Scraper: Hosts, Tickets, New Events](https://apify.com/automation_craft/luma-event-scraper)

# Changelog

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

# Actor input Schema

## `search` (type: `array`):

City, region, district, landmark, airport or country names, for example "Paris", "Tuscany", "Le Marais, Paris", "Eiffel Tower" or "Springfield, Missouri". A property's full name as Booking.com shows it ("Hotel Adlon Kempinski Berlin") reads that one property. A name Booking.com does not offer exactly gets a free row listing the closest destinations to copy from.

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

Booking.com search result links (they keep their own dates, guests, filters and order) and property page links (www.booking.com/hotel/<country>/<name>.html, with or without dates) and shared list links (www.booking.com/mywishlist.html?wl=...: every property saved in the list). A setting you give below replaces the link's own value of that setting.

## `propertyIds` (type: `array`):

Booking.com property ids (digits, for example 128735), each read as one property for your stay.

## `mapAreas` (type: `array`):

Search around a point or inside a box: {"latitude": 48.8584, "longitude": 2.2945, "radiusKm": 2} (0.1 to 50 km) or {"north": 48.88, "south": 48.84, "east": 2.37, "west": 2.30} (at most 1 degree north to south, about 111 km, and 1.5 degrees east to west). Properties outside the circle or box are left out free.

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

Check-in date, YYYY-MM-DD. Give it with "checkOut", or use the relative dates below instead.

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

Check-out date, YYYY-MM-DD (at most 90 nights after check-in).

## `checkInDaysFromToday` (type: `integer`):

Relative dates for scheduled runs: check-in this many days after the day the run starts (0 is that day). Use with "nights"; not with fixed dates.

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

Length of the stay in nights, with "checkInDaysFromToday".

## `flexibleDays` (type: `integer`):

Let Booking.com move the stay up to this many days either way to find a lower price (0, 1, 2, 3 or 7). A property Booking.com prices for other dates in that window comes with those dates as its check-in and check-out (its link, price and add-ons are for them) and the dates you searched in "searchedDates".

## `checkInWindowDays` (type: `integer`):

Run every search once per check-in day for this many days in a row from the check-in date, same number of nights (for daily rate tracking). Each property row carries its own dates.

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

Number of adults (default 2).

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

One age (0 to 17) per child, for example \[5, 9]. Prices and availability change with children's ages.

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

Number of rooms (default 1).

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

Three letter currency code of every price (default USD, or the link's own).

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

Language of names and texts Booking.com translates (default en-us, or the link's own).

## `minPrice` (type: `integer`):

Lowest price per night (or for the whole stay with "priceLimitsPerStay"), in the run's currency.

## `maxPrice` (type: `integer`):

Highest price per night (or for the whole stay with "priceLimitsPerStay"), in the run's currency.

## `priceIncludesTaxes` (type: `boolean`):

Off: the price limits apply to the price Booking.com shows per night. On: they apply to the price per night with the taxes and charges Booking.com lists apart (city tax, cleaning fee), checked on every row.

## `priceLimitsPerStay` (type: `boolean`):

Off: "minPrice" and "maxPrice" are per night. On: they are for the whole stay (all nights), checked on every row's price for the stay.

## `stars` (type: `array`):

Star ratings to keep (any of them). "Unrated" keeps properties without a star rating; Booking.com has no filter for it, so with it every row is checked by its own rating.

## `minReviewScore` (type: `string`):

Lowest guest review score, 1 to 10 with at most one decimal. 6, 7, 8 and 9 are Booking.com's own bands (Pleasant, Good, Very good, Wonderful); a score between them, such as 8.4, is checked on every row.

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

Leave out properties with fewer guest reviews (checked on each row).

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

Property types to keep (any of them).

## `entireHomesOnly` (type: `boolean`):

Keep only places you have to yourself.

## `freeCancellation` (type: `boolean`):

Keep only properties with a free cancellation rate.

## `noPrepayment` (type: `boolean`):

Keep only properties with a rate you pay at the property.

## `bookWithoutCreditCard` (type: `boolean`):

Keep only properties bookable without a credit card.

## `meals` (type: `array`):

Meal plans to keep (any of them).

## `facilities` (type: `array`):

Facilities every kept property must have (all of them).

## `roomFacilities` (type: `array`):

Room facilities every kept property must offer (all of them).

## `bedTypes` (type: `array`):

Bed types to keep (any of them).

## `minBedrooms` (type: `integer`):

Entire places with at least this many bedrooms.

## `minBathrooms` (type: `integer`):

Properties with at least this many bathrooms.

## `petFriendly` (type: `boolean`):

Keep only pet friendly properties.

## `adultsOnly` (type: `boolean`):

Keep only adults only properties.

## `lgbtqFriendly` (type: `boolean`):

Keep only Travel Proud properties.

## `sustainableOnly` (type: `boolean`):

Keep only properties with a sustainability certification.

## `maxDistanceKm` (type: `number`):

For places and map areas: leave out properties farther than this from the place's centre (straight line, checked on each row).

## `bookingFilters` (type: `array`):

Any other filter of Booking.com's search, as the code a search link carries in "nflt", for example "di=8" (a district), "chaincode=1053" (a brand), "popular_activities=11" or "distance=1610". Turn on "includeFilterCounts" to get every code of a search with its count. Star codes ("class=") and guest score codes ("review_score=") go here only when "stars" or "minReviewScore" is left empty.

## `includeNearbyProperties` (type: `boolean`):

Booking.com adds properties from outside the destination when few match; they are left out free by default. Turn this on to keep them (flagged with "outsideDestination": true).

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

Order of the results (default: Booking.com's own top picks; map areas default to distance).

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

Most properties to deliver in the run, all searches and lookups together. Empty: no run cap (each search still stops at Booking.com's 1,000 results unless "maxItemsPerSearch" is above 1,000).

## `maxItemsPerSearch` (type: `integer`):

The most property rows one search delivers (default 1,000, the most Booking.com shows per search). Above 1,000 the Actor splits the search by property type and price to read past that limit.

## `includeDetails` (type: `boolean`):

Add every room and rate of the stay (price, taxes, meal plan, cancellation and prepayment terms, rooms left, room size, beds, photos), the description, facilities, house rules, check-in and check-out times, category scores, photos, surroundings and the host's business details. Billed as Property details per property read in full.

## `maxPropertiesWithDetails` (type: `integer`):

Read Property details for the first N properties of the run only (the rest are delivered without details and not charged for them). Empty: every property.

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

Add a day by day calendar from the run's day: whether a stay can start, Booking.com's date picker price per night and the minimum stay. Billed per calendar day delivered.

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

How many days of calendar (default 61).

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

Add each property's guest reviews as rows of their own: score, title, liked and disliked text, language, date, stay dates, nights, room, traveller type, reviewer first name and country, property reply and photos. Billed per review.

## `maxReviewsPerProperty` (type: `integer`):

The most reviews delivered per property (default 10).

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

Order of the reviews (default newest first).

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

Only reviews in these languages, as codes such as "en", "fr" or "pt".

## `reviewsTravellerType` (type: `string`):

Only reviews of this traveller type.

## `reviewsScoreBand` (type: `string`):

Only reviews in this score band.

## `reviewsSeason` (type: `string`):

Only reviews of stays in this season.

## `reviewsKeyword` (type: `string`):

Only reviews mentioning this word or phrase.

## `reviewsFrom` (type: `string`):

Only reviews posted on or after this date (YYYY-MM-DD). With newest first, the walk stops at the first older review.

## `reviewsTo` (type: `string`):

Only reviews posted on or before this date (YYYY-MM-DD).

## `includePersonalData` (type: `boolean`):

All public data is always delivered and this setting has no effect (kept so saved inputs keep working).

## `includeFilterCounts` (type: `boolean`):

Add to each search's free summary row every filter Booking.com offers there, with its code and the number of properties (market size by stars, type, price band, district, brand and more).

## `mapFile` (type: `boolean`):

Also save the delivered properties as MAP.kml in the run's key-value store, for Google Earth or My Maps.

## `mapColorBy` (type: `string`):

How the map file colours its pins (default guest score).

## `outputFields` (type: `array`):

Keep only these top level fields of each property row (the row's type, id, key, link and add-on fields always stay; with the map file on, the position, guest score and price stay too). Empty: every field.

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

Apify's datacenter proxy is used and included in the price; give your own proxy links only if you need them.

## Actor input object example

```json
{
  "search": [
    "Paris"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

## `report` (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 = {
    "search": [
        "Paris"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

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

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

```

## MCP server setup

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