# Booking.com Room Rates Scraper (`boncross/booking-room-rates`) Actor

Scrape every room Booking.com is selling for a hotel and your dates. Just add hotel links and get room name, size, beds, board, price for the stay, price per night, cancellation terms and payment policy. Export to CSV, JSON or Excel, or schedule it.

- **URL**: https://apify.com/boncross/booking-room-rates.md
- **Developed by:** [BonCross API](https://apify.com/boncross) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 hotel-priceds

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 Room Rates Scraper

### What is Booking.com Room Rates Scraper?

A Booking.com hotel page leads with one "from" price. Booking.com Room Rates Scraper gets you everything behind it: each room the hotel is selling for your dates and each rate plan on that room, one row per bookable rate, with the board, the cancellation terms, the payment policy and what tax is or isn't in the price. Paste hotel links, set the dates, and that's the run.

What you get that a headline price can't tell you:

- The full grid. On the properties we measured that was 8 to 34 rates per hotel-stay, and The Savoy returned 61 for the night in the example further down.
- A price you can add up. Each rate says whether tax is included, with the amount inside the price and the amount payable on top.
- Like-for-like comparisons. Booking sells some rooms to fewer guests for less, and those rates are marked. 21 of The Savoy's 61 rows were that kind. Unmarked, they'd look like cheaper rooms.
- An answer for each hotel you asked about. A sold-out stay is one row saying sold out. A stay your filters emptied is one row saying how many rates there were. A hotel that couldn't be reached is one free error row.
- A price per hotel-stay, not per row: $3.50 per 1,000 priced hotel-stays on the Free plan and $2.60 on Business, however many rates the hotel has.

**BonCross Verified** means we tested this actor against the live site before release and kept the record:

- 28 of 28 live checks on its inputs and filters passed on 8 October 2026
- 9 hotels run on 7 October 2026 on one weekend: 103 rates, 2 sold-out answers
- A stay your filters empty gets one row saying how many rates were found

People use it for rate-parity checks against their own channel, competitor rate shopping across a set of hotels and dates, watching how a rival's rate plans and cancellation terms move, and feeding travel products that need bookable room-level prices.

### What data is on each rate row?

| | Field | Notes |
|---|---|---|
| 🏨 | `id`, `hotelId`, `hotelName`, `url`, `input` | the rate, the property, a link back to it and the hotel as you supplied it |
| 📅 | `checkIn`, `checkOut`, `nights` | the stay the rate was priced for |
| 🛏 | `roomId`, `roomName`, `roomDescription`, `roomSizeSqm` | as the site lists them |
| | `bathroomCount`, `isSmoking` | where the site gives them |
| | `bedConfiguration`, `maxOccupancy`, `maxAdults` | beds and how many the room sleeps |
| 🍳 | `board`, `mealPlan`, `isBreakfastIncluded` | room only, breakfast, half board and so on; `mealPlan` is the site's code |
| 💷 | `priceTotal`, `pricePerNight`, `currency` | the stay total and the nightly equivalent |
| | `priceBeforeDiscount`, `priceTotalText` | the struck-through price, where there is one |
| | `isRefundable`, `cancellation`, `cancellationDetail` | free cancellation and its deadline |
| 💳 | `isPrepaymentRequired`, `prepayment` | pay ahead or pay at the property |
| 👥 | `isAlternativeOccupancy`, `occupancyIndex` | marks a rate sold to fewer guests; the index is a variant number, not a guest count |
| | `blockId` | the site's own identifier for the rate |
| 📷 | `photos` | room photos |
| 🧾 | `pricesIncludeTax` | true where the price includes every tax and charge Booking puts a figure on, false where some are payable on top |
| | `taxesAndChargesIncluded`, `taxesAndChargesExcluded` | the taxes and charges inside the price and on top of it, for the stay, in the row's currency |
| | `chargesNote` | the site's note about charges not in the price |
| | `scrapedAt` | when the row was collected |

### How to scrape Booking.com room rates

1. [Create a free Apify account](https://console.apify.com/sign-up) and open [Booking.com Room Rates Scraper](https://apify.com/boncross/booking-room-rates).
2. Add your hotels: paste Booking.com hotel links, their slugs, or hotel IDs. If you have many, use Start URLs with a file or a Google Sheet.
3. Set your check-in and check-out dates and the adults and children in the room. Prices are for one room.
4. Filter to refundable rates or rates with breakfast if you want to, and cap the rows per hotel or for the whole run.
5. Click Start, then download the rates as CSV, Excel or JSON.

A link is looked up as that exact hotel page. If Booking has no such page you get an error row, never another hotel's rates.

### ⬇️ Input

Hotels and two dates are all it needs.

There are three caps, and they count different things. "Max rows per hotel" keeps the cheapest that many rates for each hotel-stay. "Max hotel-stays" stops the run after that many stays (a stay is one hotel for your dates, with all its rates). "Max rows in total" stops after that many rows, and the last stay is cut to fit, keeping its cheapest rates. All three default to 0, which means no limit.

| Input | Type | Notes |
|---|---|---|
| `hotels` | array | Hotel links, `country/slug` (`us/bellagio`), slugs or IDs |
| `startUrls` | array | The same hotels as links, a file, or a Google Sheet |
| `checkIn`, `checkOut` | string | `YYYY-MM-DD`. Check-out must be after check-in |
| `adults`, `childrenAges` | number, array | Who the room is for. Booking lists the same rooms and prices for any party, so these decide which rooms are big enough. Prices are for one room |
| `hideRoomsTooSmall` | boolean | Leave out rooms that cannot sleep your party. On by default |
| `maxRowsPerHotel` | number | Keep the cheapest this many rates per hotel-stay. `0` keeps every one |
| `maxItems` | number | Stop after this many hotel-stays (one hotel for your dates, all its rates). `0` (default) means no limit |
| `maxRows` | number | Stop after this many rows; the last stay is cut to fit, keeping its cheapest rates. `0` (default) means no limit |
| `onlyRefundable` | boolean | Keep only rates with free cancellation |
| `onlyBreakfastIncluded` | boolean | Keep only rates whose board includes breakfast |
| `includeAlternativeOccupancy` | boolean | Keep reduced-occupancy rates. On by default, and marked |
| `sessions` | number | Passes per hotel, 1 to 5 (default 2). See the FAQ |
| `currency`, `language` | string | Currency code (default `USD`) and Booking language code (default `en-gb`) |
| `maxConcurrency`, `delayMs` | number | Parallel requests, 1 to 32 (default 32), and an optional pause before each call in ms (default 0). Neither changes the rows |

**One hotel, one night, two adults and a child, in pounds**

```json
{
  "hotels": ["https://www.booking.com/hotel/gb/the-savoy.html"],
  "checkIn": "2026-11-02",
  "checkOut": "2026-11-03",
  "adults": 2,
  "childrenAges": ["5"],
  "currency": "GBP",
  "onlyRefundable": false,
  "maxItems": 0
}
```

**Refundable breakfast rates for several hotels, the five cheapest each, capped at 200 rows**

```json
{
  "hotels": ["us/bellagio", "https://www.booking.com/hotel/sg/marina-bay-sands.html"],
  "checkIn": "2026-11-02",
  "checkOut": "2026-11-04",
  "onlyRefundable": true,
  "onlyBreakfastIncluded": true,
  "maxRowsPerHotel": 5,
  "maxRows": 200
}
```

When we ran that second example on 7 October 2026, Marina Bay Sands returned its five cheapest refundable breakfast rates and Bellagio returned one row saying 26 rates were found and none passed the filters. That row is shown in the Output section.

#### For developers

- `maxItems` counts hotel-stays and `maxRows` counts rows. The run stops at whichever is reached first. A sold-out row or a "none passed the filters" row counts as one stay and one row.
- `sessions` is the number of passes per hotel. Booking shows reduced-occupancy rates to some visitors and not others: 1 pass may miss them, 2 catches them about 9 times in 10, and 3 about 97 times in 100. Each pass is one extra request.
- `childrenAges` takes one entry per child, their age at check-in (0 to 17). Children count towards the room's capacity.
- `maxConcurrency` (default 32, 1 to 32) is how many requests run at once. Several hotels are priced together. Lower it to 1 and hotels are priced one at a time. Row order doesn't change.
- `delayMs` (default 0) adds a wait before each call, capped at 2000 ms.
- If several inputs name the same hotel and three of its stays fail in a row, its remaining stays aren't asked for and each gets a free error row saying so.
- A run that the platform moves or restarts part-way picks up where it stopped. Hotels already in the dataset aren't priced, delivered or billed twice. We tested it by restarting a 500-hotel run part-way, and no row appeared twice.

### ⬆️ Output

One row per rate, cheapest first within each hotel-stay. This is the cheapest rate from the first example above, run on 7 October 2026 (one of the room's photos is kept here).

```json
{
  "id": "280149-2026-11-02-2026-11-03-28014903_88652304_2_2_0",
  "hotelId": 280149,
  "hotelName": "The Savoy",
  "checkIn": "2026-11-02",
  "checkOut": "2026-11-03",
  "nights": 1,
  "blockId": "28014903_88652304_2_2_0",
  "roomId": 28014903,
  "roomName": "Deluxe Room with 2 Twin Beds",
  "roomDescription": "Savoy Deluxe Rooms offer more space and are decorated in either Edwardian\nor Art Deco style, overlooking the courtyard or the city. Famous for their giant showerheads, the well-appointed marble bathrooms are finished with large chrome fittings and Miller Harris amenities. Many bathrooms have separate\nwalk-in showers.",
  "roomSizeSqm": 35,
  "bedConfiguration": "1 x single bed",
  "maxOccupancy": 3,
  "maxAdults": 3,
  "isSmoking": false,
  "bathroomCount": null,
  "mealPlan": "BREAKFAST_EXCLUDED",
  "board": "Room only",
  "isBreakfastIncluded": false,
  "occupancyIndex": 2,
  "currency": "GBP",
  "priceTotal": 807.5,
  "priceTotalText": "£807.50",
  "pricePerNight": 807.5,
  "priceBeforeDiscount": null,
  "chargesNote": null,
  "pricesIncludeTax": false,
  "taxesAndChargesIncluded": 0,
  "taxesAndChargesExcluded": 161.5,
  "isRefundable": false,
  "cancellation": "Non-refundable",
  "cancellationDetail": "Please note, if cancelled, modified or in case of no-show, the total price of the reservation will be charged.",
  "isPrepaymentRequired": true,
  "prepayment": "Pay the property before arrival",
  "photos": [
    "https://cf.bstatic.com/xdata/images/hotel/max1024x768/920380812.jpg?k=86f9425b053c7a71fce9ecef34311fa02a4bf93368d5f319a1794323ea7a847a&o="
  ],
  "url": "https://www.booking.com/hotel/gb/the-savoy.html",
  "scrapedAt": "2026-10-07T20:35:50.725Z",
  "isAlternativeOccupancy": false,
  "input": "https://www.booking.com/hotel/gb/the-savoy.html"
}
```

`id` joins the hotel, the stay and Booking's own `blockId`, which makes a rate row unique across a run and joinable. `input` echoes the hotel exactly as you supplied it. `priceBeforeDiscount` is filled only where the rate is discounted, and is null otherwise.

#### Reading the price

Prices are quoted as Booking.com shows them to a visitor in the United States, on every row and every run. Repeated checks of the same hotel are always on the same basis. On that basis some rates have every tax inside the price and others quote the price before taxes and list them separately, and each row tells you which. `pricesIncludeTax` is false where a tax or charge with a figure is payable on top, and `taxesAndChargesExcluded` is that figure. `priceTotal + taxesAndChargesExcluded` is then the full price: £807.50 + £161.50 = £969 for the room above. Prices are reported exactly as Booking returned them and are never converted from one basis to the other. A charge Booking can't put a figure on, such as a city tax that "may apply", doesn't count against `pricesIncludeTax`, and `chargesNote` mentions it.

#### Rows that aren't rates

A hotel-stay whose rates your filters all remove returns one row saying so, with `rateCount: 0`, `ratesFound` (how many rates the site had) and the reason in `error`:

```json
{
  "id": "186104-2026-11-02-2026-11-04-nomatch",
  "hotelId": 186104,
  "hotelName": "Bellagio",
  "input": "us/bellagio",
  "checkIn": "2026-11-02",
  "checkOut": "2026-11-04",
  "nights": 2,
  "isSoldOut": false,
  "rateCount": 0,
  "ratesFound": 26,
  "url": "https://www.booking.com/hotel/us/bellagio.html",
  "error": "26 rate(s) found, none passed the filters set on this run",
  "scrapedAt": "2026-10-07T20:36:02.311Z"
}
```

A sold-out stay returns one row marked `isSoldOut: true`. A hotel that couldn't be reached returns an error row, which is never charged.

### How many rates per hotel, and how fast?

You get every rate the site is selling for the stay. On the properties measured that is **8 to 34 rows per hotel-stay**, depending on how many room types the hotel has and how many boards and rate plans it sells each under. A large hotel can go well past that, as The Savoy's 61 shows.

| Run | Rows | Time |
|---|---|---|
| One hotel, one night, 8 cheapest rates | 8 | 2 to 6 s |
| 14 hotels, two nights | 111 | 5 to 11 s |
| 500 hotels, two nights | about 8,300 | 42 to 50 s |

Whole runs on Apify, start-up included, measured on 2 October 2026. Booking.com's answer time varies through the day, which is the spread. A hotel-stay is a single lookup with no pages to work through, and a longer list adds little time: the 500-hotel run worked out at about 600 hotel-stays a minute, which fits several thousand hotels into the default one-hour run limit.

### How much does it cost?

| Event | Free plan | Starter | Scale | Business |
|---|---|---|---|---|
| `actor-start`, per run | $0.001 | $0.001 | $0.001 | $0.001 |
| `hotel-resolved`, per hotel link, slug or id resolved to a property | $0.0005 | $0.0005 | $0.0005 | $0.0005 |
| `hotel-checked`, per hotel-stay the site answered, whether or not it had rooms | $0.0005 | $0.0005 | $0.0005 | $0.0005 |
| `hotel-priced`, per hotel-stay whose rates came back and rows were written | $0.003 | $0.0027 | $0.0024 | $0.0021 |

Enterprise plans pay the Business price.

**$3.50 per 1,000 priced hotel-stays** on the Free plan, $2.60 on Business, plus $0.0005 per hotel to look it up. You pay the same for a hotel with 8 rates as for one with 61. Proxy usage and platform usage are included.

- Ten hotels for one stay: $0.001 + 10 × $0.0005 + 10 × ($0.0005 + $0.003) = **$0.041** ($0.032 on Business).
- A daily monitor of 20 hotels for a month: 30 × ($0.001 + 20 × $0.0005 + 20 × $0.0035) = **$2.43** for the month ($1.89 on Business).

What you don't pay the per-stay rate for:

- A sold-out stay, or one whose rates your filters all remove, pays the small `hotel-checked` fee only.
- A hotel-stay the site never answered is charged nothing.
- Error rows are never charged.

Apify's Free plan gives you $5 of credits a month, which is about 120 runs of ten hotels each: roughly 1,200 priced hotel-stays with all their rates.

### Limitations

- Room rates are per hotel-stay. To compare dates, run the same hotel across several date pairs.
- Reduced-occupancy rates are shown to some visitors and not others. The actor takes more than one pass to catch them (see the FAQ).
- `occupancyIndex` is an opaque variant index, not a number of guests, and it's named that way to stop the column being misread. Use `isAlternativeOccupancy` to tell a reduced-occupancy rate from the full-occupancy one, and `maxOccupancy` for how many the room sleeps.
- There's no guest count per rate. Booking doesn't publish one on this data. A reduced-occupancy rate is identified as such but not labelled with how many guests it covers.
- The party doesn't change Booking's prices here. 2 adults, 4 adults and 2 adults with 2 children returned the same rooms at the same prices. Your party is used to leave out rooms too small for it.
- Prices are for one room. Booking's room list is priced per room and the number of rooms is chosen on the page, which is why there's no rooms input.
- You get prices in the currency and language you ask for. A hotel's own currency may differ.

### FAQ

#### Why do some runs return a few more rows than others?

Booking shows reduced-occupancy rates, the same room sold to fewer guests for less, to some visitors and not to others. The actor makes more than one pass to catch them either way. One pass is the fastest and the most likely to miss them. More passes raise the odds, but on some runs the site shows none of them to any pass, and a re-run can return a few more rows.

#### What does `isAlternativeOccupancy` mean?

It marks a rate that covers fewer guests than the room's full occupancy, which is why it's cheaper than an otherwise identical rate. Those rows are kept and marked. Nothing is lost, and you can't accidentally pair a one-breakfast rate with a two-breakfast one in a like-for-like comparison. If you only want the full-occupancy rate for each room and board, turn off "Include reduced-occupancy rates".

#### A hotel came back as one row with an error about filters. What happened?

The hotel had rates, and none survived the filters you set. `ratesFound` tells you how many there were. The usual causes are "Only refundable rates" with "Only rates including breakfast" on a hotel that sells no such combination, or a party too big for any room while "Hide rooms too small for your party" is on. Loosen one and run it again.

#### Why is a hotel returning one row saying sold out?

The site had nothing available for those dates. That's an answer a rate monitor wants, so you get it as a row.

#### Does the number of adults change the price?

Not here. Booking lists the same rooms at the same prices whatever the party, and the adults and children you enter decide which rooms are big enough to keep.

#### Can I search a city instead of listing hotels?

Run [Booking.com Hotel Search Scraper](https://apify.com/boncross/booking-hotel-search) for the destination and dates, then feed the hotels it returns into this actor.

#### Do I need proxies or a Booking.com account?

No to both. Rates are read as a logged-out visitor sees them, with no login of yours involved, and the proxy usage is part of the price you already pay.

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

Room prices are public: anyone can see them without signing in, and that's all this actor reads. Collecting public data like this is generally lawful in the UK, EU and US. How you use the prices, and whether that fits Booking.com's terms, is for you to check.

### Running it as a rate monitor

A daily rate check is the usual setup. Create an Apify Schedule with your hotel list and dates, and each run writes a fresh grid you can diff against the last. A webhook can fire when a run finishes, and the rows can go on to Google Sheets, Airtable or Slack through Apify's integrations.

From code, start a run and wait for the dataset in one call:

```
POST https://api.apify.com/v2/acts/boncross~booking-room-rates/run-sync-get-dataset-items
```

Through the Apify MCP server at `mcp.apify.com`, an AI agent can call `booking-room-rates` with a hotel and dates and get the rate rows back.

### More from BonCross

- [Booking.com Hotel Details Scraper](https://apify.com/boncross/booking-hotel-details): The full Booking.com record for a property.
- [Booking.com Hotel Search Scraper](https://apify.com/boncross/booking-hotel-search): Every hotel Booking.com is selling for a destination and your dates.
- [Booking.com Reviews Scraper](https://apify.com/boncross/booking-reviews): Every Booking.com guest review for any hotel.
- [Expedia Hotel Details Scraper](https://apify.com/boncross/expedia-hotel-details): The full property record from Expedia and Hotels.com.
- [Expedia Hotel Search Scraper](https://apify.com/boncross/expedia-hotel-search): Every hotel Expedia and Hotels.com list for a destination and your dates.
- [Expedia Room Rates Scraper](https://apify.com/boncross/expedia-room-rates): Every room Expedia and Hotels.com are selling for a hotel and your dates.

### Your feedback

Seen a rate on Booking.com that isn't in your rows, or a price that doesn't add up? Open an issue on the Issues tab with the hotel and dates. We check it against the site and reply there.

# Changelog

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

# Actor input Schema

## `hotels` (type: `array`):

Booking.com hotel links, "country/slug" (us/bellagio), a bare slug or a hotel ID. A link is looked up as that exact page; a bare slug is confirmed against Booking before it is priced.

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

The same hotels as links, or a file or Google Sheet holding many of them.

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

Arrival date, YYYY-MM-DD. Leave both dates empty to price one night 30 days from today.

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

Departure date, YYYY-MM-DD. Must be after check-in.

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

Adults in the room. Booking lists the same rooms and prices for any party, so this and Children's ages decide which rooms are big enough (see Hide rooms too small). Prices are for one room.

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

One entry per child, their age at check-in (0-17). Children count towards the room's capacity. Leave empty for adults only.

## `maxRowsPerHotel` (type: `integer`):

Keep the cheapest this many rate rows per hotel-stay. 0 keeps every one.

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

Stop after this many hotel-stays, across every hotel. A stay is one hotel for your dates, with all its rates. 0 means no limit.

## `maxRows` (type: `integer`):

Stop after this many rows across the run. The last hotel-stay is cut to fit, keeping its cheapest rates. 0 means no limit.

## `hideRoomsTooSmall` (type: `boolean`):

Booking lists every room whatever the party, so a search for 4 adults also returns rooms that sleep 2. On by default, rooms that cannot sleep your adults and children are left out. Turn off to get every room.

## `onlyRefundable` (type: `boolean`):

Keep only rates with free cancellation.

## `onlyBreakfastIncluded` (type: `boolean`):

Keep only rates whose board includes breakfast.

## `includeAlternativeOccupancy` (type: `boolean`):

Booking sometimes sells the same room to fewer guests for less. These rows are marked with isAlternativeOccupancy so they cannot be mistaken for a cheaper version of the full-occupancy rate. Turn off to keep only the full-occupancy rate for each room and board.

## `sessions` (type: `integer`):

Booking shows reduced-occupancy rates to some visitors and not others. Each extra pass raises the chance of catching them: 1 pass may miss them, 2 catches them about 9 times in 10, 3 about 97 times in 100. Costs one extra request per pass.

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

Three-letter code, e.g. USD or GBP. Default USD. Left empty, Booking picks a currency from the visitor's location, which can change between runs.

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

Booking language code, e.g. en-gb, en-us, de, fr, ja.

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

Optional pause before each call, in milliseconds. 0 (the default) runs as fast as the parallel limit allows. Values above 2000 are treated as 2000.

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

How many requests run at once across the whole run. The default is the fastest level measured clean; lower it only if a run reports refusals or errors.

## Actor input object example

```json
{
  "hotels": [
    "us/bellagio"
  ],
  "startUrls": [],
  "checkIn": "2026-11-02",
  "checkOut": "2026-11-03",
  "adults": 2,
  "childrenAges": [],
  "maxRowsPerHotel": 0,
  "maxItems": 0,
  "maxRows": 0,
  "hideRoomsTooSmall": true,
  "onlyRefundable": false,
  "onlyBreakfastIncluded": false,
  "includeAlternativeOccupancy": true,
  "sessions": 2,
  "currency": "USD",
  "language": "en-gb",
  "delayMs": 0,
  "maxConcurrency": 32
}
```

# Actor output Schema

## `dataset` (type: `string`):

Booking.com room rates: every row the run returned.

## `stats` (type: `string`):

Counts for the run: what was resolved, fetched, filtered and returned.

# 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 = {
    "hotels": [
        "https://www.booking.com/hotel/gb/the-savoy.html"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("boncross/booking-room-rates").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 = { "hotels": ["https://www.booking.com/hotel/gb/the-savoy.html"] }

# Run the Actor and wait for it to finish
run = client.actor("boncross/booking-room-rates").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 '{
  "hotels": [
    "https://www.booking.com/hotel/gb/the-savoy.html"
  ]
}' |
apify call boncross/booking-room-rates --silent --output-dataset

```

## MCP server setup

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

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/ZYOvVTDYgNW3Fl33w/builds/IyxC4Smozof3UbrVD/openapi.json
