# Booking.com Hotel Details Scraper: Rooms & Prices (`myth84/booking-hotel-details-scraper`) Actor

Scrape Booking.com hotel details from hotel URLs: room types with amenities, facilities by group, photos, address, coordinates, review score, stars and the cheapest offer for your dates (total, taxes, free cancellation, breakfast). One flat row per hotel, no personal data.

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

## Pricing

from $1.69 / 1,000 hotel details

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 Hotel Details Scraper – rooms, facilities, photos and prices, no personal data, no reviews, no host details

Booking.com hotel details scraper: paste Booking.com hotel URLs and get each hotel's room types, facilities, photos, address, coordinates, review score and stars, with room prices for your dates (the cheapest available room: total, per night, taxes, free cancellation, breakfast), as a clean table or through an API — no login. Use it to enrich a list of hotels, benchmark competitors and track room prices with scheduled runs.

**No login, no cookies, no personal data:** nothing to sign in to, no cookies to paste, nothing about guests, reviewers or hosts in the output.

- **What you get:** one flat row per Booking.com hotel URL: description, facilities by group (free, paid, off-site), every room type with its amenities, up to 200 photos, address, coordinates, review score on 10, number of reviews, stars and the cheapest offer for your dates (total, taxes, free cancellation, breakfast). No personal data.
- **For whom:** revenue managers and hoteliers benchmarking competitors, travel agencies and comparison sites enriching their catalogues, analysts and AI agents through MCP.
- **How much:** from $2.50 per 1,000 hotels on the Free plan, lower on paid plans; Apify's free monthly credit of $5 covers about 1,999 hotels. A fixed price per hotel saved, and nothing else (see the Pricing tab); `maxResults` caps every run, unknown pages are not charged.

**Sample output**: one real Lisbon hotel for a 3-night stay, key columns only (the full row, with facilities, room types and photos, is under *Output example*):

```json
{
  "platformListingId": "10131840",
  "title": "MASA Hotel & Spa Campo Grande Collection",
  "checkIn": "2026-11-20",
  "currency": "EUR",
  "priceTotal": 289.81,
  "taxesAndFees": 41.39,
  "priceTotalAllIn": 331.2,
  "rating": 8.5,
  "reviewCount": 11778,
  "starRating": 4,
  "cancellationPolicy": "free_cancellation_until:2026-11-15",
  "highlights": [
    "Private bathroom in all rooms",
    "Languages spoken: en, es, pt",
    "Cheapest offer for your dates: Deluxe Double or Twin Room"
  ]
}
```

Give this Booking.com scraper a list of **hotel page URLs** and get **one flat row per hotel** with what the hotel page shows and search results do not: the full description, the complete list of facilities grouped by Booking.com's own groups (Bathroom, Internet, Parking, Room amenities…) with the payment notes Booking.com gives ("free", "paid: 2 EUR per hour", "off-site"), **every room type with its amenities**, the gallery photos, the short and full address with the district, the coordinates, the review score on 10 and the number of reviews, the official stars, accessibility, spoken languages and Booking.com's own summary of the property. For your dates and guests, the row also carries the **cheapest available offer**: total price of the stay, price per night, crossed-out price, taxes not included, free cancellation date, breakfast included and the room type it belongs to.

**No personal data, by design.** Nothing about guests, reviewers or hosts is collected: no names, no profile photos, no ids, no review texts. The output only contains facts about the property, the average review score and the number of reviews. The dataset is safe to store, share and feed to AI agents.

### What can you do with Booking.com hotel data?

- **Benchmark competing hotels**: room types, facilities (parking, pool, spa, airport shuttle, free or paid), stars, review score and the price of the same stay, side by side in a spreadsheet.
- **Track the cheapest offer** of a list of hotels for a date range: schedule the Actor (dates relative to the run date by default) and compare `priceTotalAllIn` (taxes included), `priceTotal`, `taxesAndFees` and `cancellationPolicy` from run to run.
- **Enrich a search export**: run the [Booking.com Scraper](https://apify.com/myth84/booking-hotels-scraper) for a destination, then this Actor on its `url` column for rooms, facilities and photos; both share the same first columns and join on `platformListingId`.
- **Build catalogues and AI datasets** with a stable, documented schema (`travel-listing/1.6`) shared by the travel studio (Airbnb, Booking.com and more).

### What data does Booking.com Hotel Details Scraper extract?

Every row has every column: a value Booking.com does not show is `null` (or `[]` / `{}` for lists and groups), so CSV and Excel exports keep the same columns from run to run. The first columns are those of the search scrapers of the travel studio (`travel-listing/1.5`, its price-monitoring columns included and always `null` here), then come the detail columns.

| Group | Columns |
|---|---|
| Identity | `schemaVersion`, `platform`, `platformListingId`, `url`, `title`, `propertyType`, `propertyTypeCode`, `roomType` |
| Location | `city`, `region`, `country`, `countryCode`, `latitude`, `longitude`, `isExactLocation`, `neighborhood`, `neighborhoodDescription`, `locationSummary` |
| Stay and offer | `checkIn`, `checkOut`, `nights`, `guests`, `currency`, `priceTotal`, `pricePerNight`, `priceBeforeDiscount`, `taxesAndFees`, `taxesIncluded`, `priceTotalAllIn`, `cancellationPolicy`, `isAvailable`, `badges` |
| Quality | `rating`, `ratingMax`, `reviewCount`, `starRating`, `highlights`, `listedBy`, `isNew` |
| Rooms and facilities | `sleepingArrangements`, `amenityGroups`, `amenities`, `accessibilityFeatures`, `safetyFeatures` |
| Description and photos | `description`, `imageUrls`, `imageCount` |
| Context | `viewCountryCode`, `scrapedAt` |
| Price monitoring (not offered by this Actor, always `null`) | `changeType`, `previousPrice`, `priceDelta`, `priceDeltaPercent` |
| Always empty for this Actor | `cleaningFee`, `serviceFee`, `bedrooms`, `beds`, `bathrooms`, `maxGuests`, `isSuperhost`, `instantBook`, `isGuestFavorite`, `unavailableAmenities`, `houseRules`, `checkInTime`, `checkOutTime`, `petsAllowed`, `smokingAllowed`, `eventsAllowed`, `quietHours`, `ratingAccuracy`, `ratingCheckIn`, `ratingCleanliness`, `ratingCommunication`, `ratingLocation`, `ratingValue`, `calendarStart`, `calendarEnd`, `calendarDays`, `availableDays`, `nextAvailableDate`, `minNights`, `availability`, `searchLocation`, `searchRank`, `searchPage` |

How the Booking.com page maps to the columns:

- `sleepingArrangements` holds **one line per room type**: the room name, then its amenities ("Deluxe Double or Twin Room — Safety deposit box, Air conditioning, Soundproofing…").
- `amenityGroups` holds the facilities by group, with "(free)", "(paid)", "(paid: 2 EUR per hour)" or "(off-site)" when Booking.com says so; `amenities` is the flat list of facility names.
- `neighborhood` is the short address ("Campo Grande 56, Alvalade, Lisbon"), `neighborhoodDescription` the full postal address, `region` the district ("Alvalade") and `locationSummary` Booking.com's generated summary of the property.
- `highlights` gathers what the page highlights: summaries of facility groups ("Wifi is available in all areas and is free of charge."), "Private bathroom in all rooms", "Work-friendly property", "Preferred Partner", "In the old town", "Languages spoken: en, es, pt", sustainability certifications and, with an offer, "Cheapest offer for your dates: <room type>".
- `badges` carries machine-readable flags: `meal_plan_included` (breakfast or another meal plan included in the price), `third_party_offer`, `chain:<id>`, the deal badges of the offer ("Limited-time Deal") and "Only X left" messages.
- `cancellationPolicy` is `free_cancellation_until:<YYYY-MM-DD>` when the cheapest offer can be cancelled for free, `null` otherwise. `isAvailable` is `true` when Booking.com returned an offer for your dates and guests, `false` when it returned none, `null` when the offer was not requested or could not be read.

**Which price to compare.** On Booking.com, `priceTotal` is the price of the stay **before** the taxes and charges Booking.com shows as not included, which are in `taxesAndFees`; `taxesIncluded` is then `false` (`true` when Booking.com shows an excluded amount of 0, `null` without an offer or when it shows no excluded amount). `priceTotalAllIn` is the total of the stay **with** them, `priceTotal` + `taxesAndFees` (€289.81 + €41.39 = €331.20 in the sample above), and `null` when the taxes are unknown, never estimated: it is the column to compare stays across platforms, filled with the same rule by every travel scraper of the studio.

### How to scrape Booking.com hotel details

1. **Paste hotel URLs** copied from your browser (`https://www.booking.com/hotel/pt/masa-campo-grande.html`, any Booking.com domain, with or without a language suffix or query parameters) or just `pt/masa-campo-grande`, one per line. Search result URLs are not accepted.
2. **Set your stay** (optional): check-in and check-out dates, adults, children with their ages, rooms. Without dates, the offer is for a stay starting 30 days from the run date, for 3 nights.
3. **Choose the currency and the language**, the number of photos per hotel, or untick **Include the cheapest offer** for descriptions, facilities and photos only.
4. **Run** and open the **Output** tab: the *Overview*, *Prices*, *Rooms and facilities* and *Photos and descriptions* views show the main columns; export everything as JSON, CSV, Excel or through the API.

### Input

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

The input of our validation run: two Lisbon properties and a page that does not exist (it yields no row and is not charged), offer in EUR for a stay starting 30 days after the run, texts in English (every other field keeps its default):

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html",
    "https://www.booking.com/hotel/pt/villa-baixa-lisbon-luxury-apartments.html",
    "https://www.booking.com/hotel/pt/this-hotel-does-not-exist-xyz.html"
  ],
  "adults": 2,
  "includeOffer": true,
  "currency": "EUR",
  "language": "en-us",
  "maxResults": 2
}
```

Every field, with its type and default:

| Field | Type | Default | Description |
|---|---|---|---|
| `hotelUrls` | string\[] | — | Booking.com hotel page URLs (any Booking.com domain) or `<country>/<name>`, 1 to 1,000. Duplicates are fetched once. Prefilled with three Lisbon hotels. |
| `checkIn` | string | — | Check-in date, YYYY-MM-DD. Empty: 30 days after the run date. |
| `checkOut` | string | — | Check-out date, YYYY-MM-DD, after check-in. Empty: 3 nights after check-in. |
| `adults` | integer | `2` | Number of adults (the offer depends on it). |
| `children` | integer | `0` | Number of children (0 to 17 years old). |
| `childrenAges` | integer\[] | `[]` | Age of each child; a child without an age counts as 8. |
| `rooms` | integer | `1` | Number of rooms (units) to book. |
| `includeOffer` | boolean | `true` | Also price the stay: cheapest available room, total, crossed-out price, taxes not included, free cancellation, breakfast (one extra request per hotel). |
| `maxPhotos` | integer | `45` | Gallery photos kept per hotel, 0 to 200. |
| `currency` | string | `"EUR"` | ISO 4217 code of the offer prices; paid facilities keep the hotel's own currency. |
| `language` | string | `"en-us"` | Booking.com language code of the texts: en-us, en-gb, fr, de, es, it, pt-pt… |
| `maxResults` | integer | `100` | Stop after this many hotels (1 to 1,000). You are never charged for more; a page Booking.com does not know gives no row. Prefilled with `50` in the form: the three prefilled hotel URLs make a quick first run, a pasted list is not cut short. |
| `proxyConfiguration` | object | `{"useApifyProxy":true}` | Apify datacenter proxies by default, included in the price; keep them, or bring your own proxy URLs. A proxy country is recorded in `viewCountryCode`. |
| `maxRequests` | integer | `2500` | Safety cap on requests in one run (one per hotel page and one per offer, each asked at most once more after an unusable or empty answer): enough for 1,000 hotels with their offer. |
| `delayMs` | integer | `500` | Pause after each hotel, in milliseconds (four hotels are processed at a time). |
| `debugStoreResponses` | boolean | `false` | Debugging only: store every API response in the key-value store. |

### Output example

One real row, produced by the Actor from a Lisbon hotel on Booking.com (English, EUR, 20–23 November 2026, 2 adults, 1 room). All columns are present, in this order, for every hotel; the response was shortened at capture time to 3 room types, 14 facilities and 4 photos (the full page has 8 room types, 117 facilities and 45 photos):

```json
{
  "schemaVersion": "travel-listing/1.6",
  "platform": "booking",
  "platformListingId": "10131840",
  "url": "https://www.booking.com/hotel/pt/masa-campo-grande.html?checkin=2026-11-20&checkout=2026-11-23&group_adults=2&group_children=0&no_rooms=1&selected_currency=EUR&lang=en-us",
  "title": "MASA Hotel & Spa Campo Grande Collection",
  "propertyType": "Hotel",
  "roomType": "hotel_room",
  "city": "Lisbon",
  "region": "Alvalade",
  "country": "Portugal",
  "countryCode": "PT",
  "latitude": 38.750851,
  "longitude": -9.148746,
  "checkIn": "2026-11-20",
  "checkOut": "2026-11-23",
  "nights": 3,
  "guests": 2,
  "currency": "EUR",
  "pricePerNight": 96.6,
  "priceTotal": 289.81,
  "priceBeforeDiscount": 362.26,
  "cleaningFee": null,
  "serviceFee": null,
  "taxesAndFees": 41.39,
  "taxesIncluded": false,
  "priceTotalAllIn": 331.2,
  "rating": 8.5,
  "ratingMax": 10,
  "reviewCount": 11778,
  "starRating": 4,
  "bedrooms": null,
  "beds": null,
  "bathrooms": null,
  "maxGuests": null,
  "amenities": [
    "Shared lounge/TV area",
    "Designated smoking area",
    "Air conditioning",
    "Smoke-free property",
    "Hypoallergenic room available",
    "Wake-up service",
    "Hardwood or parquet floors",
    "Heating",
    "Soundproofing",
    "Private entrance",
    "Soundproof rooms",
    "Elevator",
    "Facilities for disabled guests",
    "Airport shuttle",
    "Airport pickup",
    "Airport drop-off"
  ],
  "badges": [
    "meal_plan_included"
  ],
  "isSuperhost": null,
  "listedBy": "professional",
  "instantBook": null,
  "isNew": false,
  "isAvailable": true,
  "cancellationPolicy": "free_cancellation_until:2026-11-15",
  "imageUrls": [
    "https://cf.bstatic.com/xdata/images/hotel/max1024x768/535564893.jpg?k=e7a60ec8e804b0be59a40ec440854ad50d0cfa8dc2316bed0e97f443d03c8412&o=",
    "https://cf.bstatic.com/xdata/images/hotel/max1024x768/574394653.jpg?k=5d4fb4ae323cc249f2155cfde8bbdd3f230327c0ae92611f75332d5953ee18cb&o=",
    "https://cf.bstatic.com/xdata/images/hotel/max1024x768/547341750.jpg?k=63afa1207fa4126eccc1951aaecf8147775c0b2a4dde0156c5fa821066da340c&o=",
    "https://cf.bstatic.com/xdata/images/hotel/max1024x768/474094642.jpg?k=14ad041be0bdca251e6575751fe9a2afb008edc2433cdc08cf351cda83a52a55&o="
  ],
  "imageCount": 4,
  "searchLocation": null,
  "searchRank": null,
  "searchPage": null,
  "viewCountryCode": null,
  "scrapedAt": "2026-10-20T10:00:00.000Z",
  "changeType": null,
  "previousPrice": null,
  "priceDelta": null,
  "priceDeltaPercent": null,
  "description": "MASA Hotel & Spa Campo Grande Collection has a fitness center, shared lounge, a restaurant and bar in Lisbon. This 4-star hotel offers a business center and a concierge service. The property has a 24-hour front desk, airport transportation, room service and free WiFi throughout the property.\n\nThe hotel will provide guests with air-conditioned rooms with a desk, a coffee machine, a fridge, a minibar, a safety deposit box, a flat-screen TV and a private bathroom with a shower. MASA Hotel & Spa Campo Grande Collection provides some rooms with city views, and all rooms include an electric tea pot. All rooms feature a closet.\n\nA buffet, continental or halal breakfast is served at the property.\n\nLuz Football Stadium is 2.6 miles from the accommodation, while Dona Maria II National Theater is 3.1 miles from the property. Humberto Delgado Airport is 2.5 miles away.",
  "highlights": [
    "Private bathroom in all rooms",
    "Languages spoken: en, es, pt",
    "Cheapest offer for your dates: Deluxe Double or Twin Room"
  ],
  "propertyTypeCode": "HOTEL",
  "isGuestFavorite": null,
  "amenityGroups": {
    "Other": [
      "Shared lounge/TV area",
      "Designated smoking area",
      "Air conditioning (free)",
      "Smoke-free property",
      "Hypoallergenic room available",
      "Wake-up service",
      "Hardwood or parquet floors",
      "Heating",
      "Soundproofing",
      "Private entrance",
      "Soundproof rooms",
      "Elevator",
      "Facilities for disabled guests",
      "Airport shuttle (paid)",
      "Airport pickup (paid)",
      "Airport drop-off (paid)"
    ]
  },
  "unavailableAmenities": [],
  "houseRules": [],
  "checkInTime": null,
  "checkOutTime": null,
  "petsAllowed": null,
  "smokingAllowed": null,
  "eventsAllowed": null,
  "quietHours": null,
  "safetyFeatures": [],
  "sleepingArrangements": [
    "Standard Double or Twin Room — Safety deposit box, Air conditioning, Private entrance, Soundproofing, Hardwood or parquet floors, Wake-up service/Alarm clock",
    "Deluxe Double or Twin Room — Safety deposit box, Air conditioning, Private entrance, Soundproofing, Hardwood or parquet floors, Wake-up service/Alarm clock",
    "Superior Double or Twin Room — Safety deposit box, Air conditioning, Private entrance, Soundproofing, Hardwood or parquet floors, Wake-up service/Alarm clock"
  ],
  "accessibilityFeatures": [
    "Wheelchair accessible",
    "Accessible facilities"
  ],
  "ratingAccuracy": null,
  "ratingCheckIn": null,
  "ratingCleanliness": null,
  "ratingCommunication": null,
  "ratingLocation": null,
  "ratingValue": null,
  "neighborhood": "Campo Grande 56, Alvalade, Lisbon",
  "locationSummary": "The 4-star hotel features a child-friendly buffet, baby cot availability, and a family-oriented restaurant. Families appreciate the breakfast, property staff, and spacious rooms. Luz Football Stadium is 2.6 mi away.",
  "neighborhoodDescription": "Campo Grande 56, Alvalade, 1700-093 Lisbon, Portugal",
  "isExactLocation": true,
  "calendarStart": null,
  "calendarEnd": null,
  "calendarDays": null,
  "availableDays": null,
  "nextAvailableDate": null,
  "minNights": null,
  "availability": null
}
```

Here every facility of the shortened capture belongs to a group that the capture does not describe, hence the single "Other" group; on a full page the facilities are spread over Booking.com's groups ("Bathroom", "Internet", "Parking", "Room amenities"…). With `language` set to another language, the name, description, room types, facilities and deal badges come in that language; `propertyType` and the flags stay in English.

The **Output** tab offers four views of the same rows: **Overview** (type, stars, district, score, reviews, price, availability, link, photos), **Prices** (stay, total, per night, before discount, taxes, free cancellation, badges), **Rooms and facilities** (room types, facilities by group, accessibility, safety, highlights) and **Photos and descriptions** (description, summary, address, coordinates, photos).

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

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

| What you pay for | How it is counted | Price |
|---|---|---|
| `result` event: one hotel saved to your dataset | once per unique hotel of the run, capped by `maxResults`, offer included | Pricing tab, per plan tier |
| Unknown or removed hotel pages | no row, not charged | — |
| Run start | a symbolic amount, once per run | Pricing tab |
| Compute, proxies, storage and data transfer | included: no platform usage is passed on to you | — |

The cost of a run is known before you start: 1,000 hotels cost 1,000 times the `result` price of your tier, with or without the offer, whatever the number of requests. Four hotels are processed at a time, about two to four seconds each with the offer.

### What is not included

Booking.com shows more on its hotel pages than this Actor can read from its data source today. These are **not included in this version** and the matching columns stay empty:

- **The per-room rate table** (every room with every rate and condition for your dates): the row carries the cheapest available offer only, with the room type it belongs to in `highlights`.
- **House rules and check-in / check-out times** (`houseRules`, `checkInTime`, `checkOutTime`, `petsAllowed`, `smokingAllowed`): the facility groups that describe them, when present, appear in `highlights` and `amenityGroups`.
- **Category scores** (staff, cleanliness, location, value…): the overall review score on 10 and the number of reviews are included.
- **The availability calendar** (`calendar*`, `availability`): `isAvailable` answers for your dates.
- **Reviews and anything about hosts or guests**: never collected, by design.

They are on the roadmap; open an issue if one of them matters to you.

### Limits and behaviour worth knowing

- **One hotel per URL, unknown pages skipped.** A URL whose hotel does not exist on Booking.com (or was removed) yields no row, is not charged and is named in the run log. A run whose hotels all fail ends as failed with an explicit message, so that your schedules and integrations notice (no empty successes).
- **The offer is the cheapest available room for your occupancy.** It is the price Booking.com shows first for your dates and guests, for the whole stay; `taxesAndFees` holds the taxes and charges Booking.com announces as not included, and `priceTotalAllIn` the total with them. When Booking.com has nothing to offer for your dates and guests, `isAvailable` is `false` and the price columns are `null`. Booking.com sometimes answers the first price request for a hotel with an empty offer: the scraper asks once more before concluding.
- **Prices depend on the stay and the currency.** `currency` converts the offer; paid facilities ("paid: 2 EUR per hour") keep the hotel's own currency. Prices may also depend on the country the request comes from: select a proxy country to control it (recorded in `viewCountryCode`).
- **Texts are Booking.com's, localized.** Name, description, room types, facilities and summaries come in the requested `language`; `propertyType`, `propertyTypeCode`, `roomType` and the badges are language independent.
- **Photos.** `imageUrls` lists the gallery photos in 1024 × 768 size, at most `maxPhotos`; room photos are not in a column yet.
- **Reliability.** If a response is unusable, the scraper opens a new session and retries once, then gives up on that hotel and reports it in the log. If Booking.com changes its data format, the run fails with an explicit message instead of returning half-empty rows; the fix is shipped as a new build (see the Changelog).

### Integrations and API

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

### Use it from your AI assistant

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

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

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

```text
Use myth84/booking-hotel-details-scraper to get the room types, facilities and cheapest price of this Booking.com hotel for 2 adults, 3 nights starting 30 days from today, in EUR: https://www.booking.com/hotel/pt/masa-campo-grande.html. Input: {"hotelUrls": ["https://www.booking.com/hotel/pt/masa-campo-grande.html"], "adults": 2, "currency": "EUR", "maxPhotos": 5}. Show the room types, the main facilities, the total price, the taxes not included and whether it can be cancelled for free.
```

### For AI agents (MCP)

Through the [Apify MCP server](https://docs.apify.com/mcp) this Actor is a tool that answers questions such as *"which room types does this Booking.com hotel have, and what do they include?"*, *"does it have free parking, a pool or an airport shuttle?"* or *"what is the cheapest price for two adults from 20 to 23 November, and can it be cancelled for free?"*.

**Minimal input** (every other field keeps its default; give dates when the question is about a price):

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html"
  ],
  "checkIn": "2026-11-20",
  "checkOut": "2026-11-23",
  "maxPhotos": 5
}
```

- **Key output fields**: `platformListingId`, `title`, `url`, `propertyType`, `starRating`, `rating` (on 10), `reviewCount`, `sleepingArrangements` (room types), `amenityGroups`, `priceTotal`, `pricePerNight`, `taxesAndFees`, `currency`, `cancellationPolicy`, `isAvailable`, `badges`, `neighborhoodDescription` (address). Every column is always present, in a fixed order; `null` means Booking.com did not show the value. The full list is in *What data does Booking.com Hotel Details Scraper extract?* above.
- **Use it when** you already have Booking.com hotel URLs and need what the hotel page shows: rooms, facilities, photos, address, score, stars, and the cheapest offer for given dates. Pass `hotelUrls` (a few URLs), optionally `checkIn` / `checkOut`, `adults` and `currency`.
- **Do not use it for** searches by destination (use the Booking.com Scraper), the full rate table of every room, reviews, host or guest information, booking or anything behind a login: it does not collect personal data and only reads public hotel pages.
- **Cost per 1,000 results**: 1,000 `result` events, $2.50 per 1,000 on the Free plan and less on paid plans (Pricing tab); nothing else is charged, the offer is included.
- **Typical time**: two to four seconds per hotel with the offer, four hotels at a time: 10 hotels in about 15 seconds.

### Alternatives and switching

- **Official API.** Booking.com's APIs are made for its accommodation and affiliate partners and need an approved partner account; if you have one and need bookings or contracted rates, use it. This Actor reads what any visitor sees on Booking.com hotel pages (rooms, facilities, photos, review score, public prices for your dates) with no account, no keys and no approval.
- **Your own scraper.** Nothing to build or maintain: sessions, retries, the second price request and Booking.com page changes are handled for you. The columns stay the same from run to run, a run whose hotels all fail ends with an explicit message instead of succeeding empty, and a scheduled test run catches Booking.com changes early.
- **Another scraper from the Store.** What you can count on here: `maxResults` is a hard cap, the run stops at that number of hotels and you are never charged for more, and unknown hotel pages are not charged; `priceTotalAllIn` gives the price of the stay taxes included, to compare with the other platforms. The input names differ from one Actor to the next; the usual ones map to this Actor as follows:

| Usual input | Here | Note |
|---|---|---|
| `startUrls`, `urls`, `hotelUrl` | `hotelUrls` | Booking.com hotel page URLs, or `<country>/<name>` |
| `maxItems`, `limit` | `maxResults` | Hotels per run, never charged beyond |
| `checkin`, `checkout` | `checkIn`, `checkOut` | YYYY-MM-DD; left empty: 3 nights starting 30 days after the run |
| `adults`, `children`, `rooms` | `adults`, `children` + `childrenAges`, `rooms` | The offer depends on them |
| `scrapePrices`, `includePrices` | `includeOffer` | Cheapest available room for your dates |
| `maxImages` | `maxPhotos` | 0 to 200 gallery photos per hotel |
| `currency`, `language` | `currency`, `language` | ISO 4217 code, Booking.com language code |
| `proxy` | `proxyConfiguration` | Apify proxies, included in the price |

### FAQ

#### Does Booking.com Hotel Details Scraper collect personal data?

No. The scraper reads public hotel information and keeps nothing about guests, reviewers or hosts: no names, photos, profile ids, contact details or review texts. It outputs facts about the property, the average review score and the number of reviews. Every row goes through a privacy filter before it is saved, which also removes e-mail addresses from descriptions.

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

The Actor only reads information that Booking.com shows to any visitor without an account, and it stores no personal data. Scraping public data is generally lawful, but you are responsible for how you use the results and for complying with Booking.com's terms of service and the laws that apply to you (including copyright on descriptions and photos). Use the data for analysis, not to republish hotel pages.

#### Which price is in the row?

The cheapest available offer for your dates, guests and rooms, for the whole stay, as Booking.com shows it first: `priceTotal`, the average `pricePerNight`, the crossed-out `priceBeforeDiscount` when there is a discount, and `taxesAndFees` not included in the total; `priceTotalAllIn` is the total with them, the one to compare with other platforms. `cancellationPolicy` gives the free cancellation date, `badges` says when breakfast is included, and `highlights` names the room type of the offer. The full rate table of every room is not included in this version.

#### Why is isAvailable false or the price empty?

`false` means Booking.com had no offer for your dates and occupancy (sold out, minimum stay, or too many guests for one room: add rooms). `null` means the offer was not requested (`includeOffer` off) or could not be read; the run log says which. Every other column is filled either way.

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

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

#### Which languages and currencies are supported?

Any Booking.com language code (`en-us`, `en-gb`, `fr`, `de`, `es`, `it`, `pt-pt`, `nl`…) and any currency Booking.com offers (`EUR`, `USD`, `GBP`, `CHF`…). Texts come in the requested language; offer prices are converted into the requested currency.

#### Where do the hotel URLs come from?

From your browser, from the `url` column of the Booking.com Scraper (search by destination), or from any list of Booking.com hotel pages. Any URL of the form `https://www.booking.<tld>/hotel/<country>/<name>.html` works, with a language suffix (`.en-gb.html`) and query parameters; `<country>/<name>` works too.

#### How fresh is the data and how often should I run it?

Every run reads the live data. Descriptions, rooms and facilities change rarely; prices and availability change daily: schedule the Actor as often as your use case needs (without dates, every run prices a stay 30 days ahead) and compare runs by `platformListingId`.

#### How do I export or integrate the results?

From the run's Output tab (JSON, CSV, Excel, XML, RSS) or automatically: Apify API, webhooks, scheduled runs and integrations with Google Sheets, Make, Zapier, n8n, Slack and others. AI agents can call the Actor through the Apify MCP server.

#### Where do I get support?

Open an issue in the **Issues** tab of this Actor with your run id and input. Bugs and data-format changes are fixed as a priority; feature requests (rate table, house rules, category scores, other platforms of the travel studio) are welcome.

### More scrapers by Flatrow Data Studio

The travel scrapers of the studio share the same core columns: find hotels with a search, enrich them here, and compare stays from several platforms in one table on `priceTotalAllIn`, the total of the stay with taxes and fees, filled with the same rule by each scraper (`null` when a platform does not show the taxes):

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

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

### Legal note

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

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

# Changelog

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

# Actor input Schema

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

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

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

Check-in date, YYYY-MM-DD, e.g. <code>2026-12-01</code>, given with checkOut. Leave both dates empty to price a stay starting 30 days from today (UTC) for 3 nights, better for schedules: fixed dates expire.

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

Check-out date, YYYY-MM-DD, after checkIn, e.g. <code>2026-12-04</code>. Required when checkIn is set; with both dates empty, the stay ends 3 nights after the check-in in 30 days.

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

Number of adults, 1 to 30; the price of the offer depends on the number of guests. Default 2: the most searched occupancy.

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

Number of children (0 to 17 years old), 0 to 10; give their ages in childrenAges, Booking.com prices depend on them. Default 0: adults only.

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

Age of each child, one number from 0 to 17 per child, e.g. <code>\[5, 9]</code>; no more ages than children. Default empty: a child without a listed age counts as 8 years old.

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

Number of rooms (units) to book, 1 to 30; the offer is priced for this many rooms. Default 1: one room for all the guests.

## `includeOffer` (type: `boolean`):

Also price your stay, one more request per hotel (asked once more after an empty answer): total price of the cheapest available room for your dates and guests, crossed-out price, taxes not included, free cancellation date, breakfast and the room type it belongs to. Default on: every row carries the price of the stay. Untick it for descriptions, facilities and photos only (faster).

## `maxPhotos` (type: `integer`):

Maximum number of gallery photos (1024 × 768 URLs) kept per hotel, 0 to 200; 0 keeps none. Default 45: the number Booking.com shows on its hotel pages.

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

ISO 4217 code of the offer prices, e.g. <code>EUR</code>, <code>USD</code> or <code>GBP</code>: Booking.com converts every price of the offer into it; paid facilities keep the hotel's own currency. Pick one or type any code Booking.com accepts. Default EUR: the currency of our validation runs.

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

Booking.com language code of the texts (hotel name, description, room names, facilities, deal badges): two lowercase letters, optionally a region, e.g. <code>en-us</code>, <code>en-gb</code>, <code>fr</code>, <code>de</code>, <code>pt-pt</code>. Default en-us: English (US), the language of our validation runs.

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

Maximum number of hotels saved and charged, 1 to 1,000; useful to cap a long list of URLs. A page Booking.com does not know gives no row and is not charged. Default 100: about $0.25 on the Free plan. The form is prefilled with 50: the three prefilled hotel URLs make a quick first run, and a pasted list is not cut short.

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

Proxies of the requests. Default: Apify datacenter proxies, included in the price and enough for Booking.com hotel pages in our tests. A proxy country you select is recorded in viewCountryCode; you can also give your own proxy URLs.

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

Safety cap on requests for the whole run: one per hotel page and one per offer, each asked at most once more after an unusable or empty answer. Default 2500: enough for 1,000 hotels with their offer (2,000 requests) and some retries.

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

Pause after each hotel, in milliseconds, 0 to 30,000 (four hotels are processed at a time); 0 disables it. Default 500: half a second, a gentle pace with four hotels in parallel.

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

Debugging only: save every API response (hotel page and offer) in the run's key-value store. Default off: it uses storage.

## Actor input object example

```json
{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html",
    "https://www.booking.com/hotel/pt/villa-baixa-lisbon-luxury-apartments.html",
    "https://www.booking.com/hotel/pt/maxime.html"
  ],
  "adults": 2,
  "children": 0,
  "childrenAges": [],
  "rooms": 1,
  "includeOffer": true,
  "maxPhotos": 45,
  "currency": "EUR",
  "language": "en-us",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxRequests": 2500,
  "delayMs": 500,
  "debugStoreResponses": false
}
```

# Actor output Schema

## `listings` (type: `string`):

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

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

Requests made, bytes transferred, blocked responses, hotels pushed, offers found, empty and failed, second offer calls, unknown pages and the estimated platform cost of the run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "hotelUrls": [
        "https://www.booking.com/hotel/pt/masa-campo-grande.html",
        "https://www.booking.com/hotel/pt/villa-baixa-lisbon-luxury-apartments.html",
        "https://www.booking.com/hotel/pt/maxime.html"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("myth84/booking-hotel-details-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "hotelUrls": [
        "https://www.booking.com/hotel/pt/masa-campo-grande.html",
        "https://www.booking.com/hotel/pt/villa-baixa-lisbon-luxury-apartments.html",
        "https://www.booking.com/hotel/pt/maxime.html",
    ],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("myth84/booking-hotel-details-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "hotelUrls": [
    "https://www.booking.com/hotel/pt/masa-campo-grande.html",
    "https://www.booking.com/hotel/pt/villa-baixa-lisbon-luxury-apartments.html",
    "https://www.booking.com/hotel/pt/maxime.html"
  ],
  "maxResults": 50
}' |
apify call myth84/booking-hotel-details-scraper --silent --output-dataset

```

## MCP server setup

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