# Booking.com Rates Scraper (`parsebird/booking-rates-scraper`) Actor

Scrape Booking.com hotel rates by date, length of stay and occupancy: price, taxes, discounts, cancellation terms, meal plan, sold-out status and competitor rates. Export JSON, CSV, Excel or use the API.

- **URL**: https://apify.com/parsebird/booking-rates-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.19 / 1,000 rates

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

**Booking.com Rates Scraper** builds a hotel rate calendar from [Booking.com](https://www.booking.com): one row for every property, check-in date, length of stay and occupancy you choose, with price, taxes, discount, cancellation terms, meal plan and sold-out status.

<table><tr>
<td style="border-left:4px solid #003580;padding:12px 16px;font-weight:600">
Give it hotel names, Booking.com URLs or property IDs and a date range, and get a time-stamped rate grid across lengths of stay, occupancies and 51 currencies, with optional rates for up to 100 other properties priced for the same stay.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
Apify Actor: parsebird/booking-rates-scraper. Scrapes hotel rates from Booking.com as one row per property, check-in date, length of stay and occupancy, without login. Call via ApifyClient: client.actor("parsebird/booking-rates-scraper").call(run_input={"hotels": ["The Savoy, London", "https://www.booking.com/hotel/gb/claridge-s.en-gb.html"], "checkinFrom": "2026-12-01", "checkinTo": "2026-12-30", "losNights": ["1", "2"], "occupancy": ["2"], "currency": "GBP", "includeCompetitors": false, "maxItems": 400}). Inputs: hotels (array of strings, required; hotel names, Booking.com URLs or numeric property IDs), checkinFrom (string YYYY-MM-DD, default tomorrow), checkinTo (string YYYY-MM-DD, default 14 check-in dates), losNights (array of strings, 1 to 30 nights, default ["1","2"]), occupancy (array of strings, 1 to 8 adults, default ["2"]), currency (string, three-letter code, default USD), includeCompetitors (boolean, default false), maxItems (integer, default 100). Output fields: hotelId, hotelName, hotelUrl, slug, stars, reviewScore, reviewsCount, checkin, checkout, nights, adults, rooms, soldOut, currency, totalPrice, pricePerNight, priceBeforeDiscount, taxesAndCharges, roomName, bedrooms, beds, mealPlan, breakfastIncluded, freeCancellation, freeCancellationUntil, noPrepayment, geniusRateAvailable, address, district, distanceFromCentre, city, countryCode, latitude, longitude, isCompetitor, comparedToHotelId, comparedToHotelName, scrapedAt. Read results with client.dataset(run["defaultDatasetId"]).iterate_items(). API reference: https://apify.com/parsebird/booking-rates-scraper/api. Get a token: https://console.apify.com/settings/integrations.
```

### What is Booking.com Rates Scraper?

**Booking.com Rates Scraper** is a Booking.com hotel price tracker that works as a **Booking.com API alternative**. Booking.com shows you one price for one stay at a time. This Actor turns that into a table, so you can see how a hotel's rate moves across dates, lengths of stay and occupancies, and how it compares with the properties around it.

To try it, click **Start** with the prefilled input. It prices The Savoy in London for the next 14 check-in dates, at 1 and 2 nights for 2 adults, and returns 28 rows in seconds. Download the results as **JSON, CSV or Excel**, or read them with the [Apify API](https://docs.apify.com/api/v2).

### What can Booking.com Rates Scraper do?

- 🗓️ **Build a rate calendar** for any check-in range, up to about 500 days ahead.
- 🏨 **Accept hotels your way**: names like `The Savoy, London`, Booking.com property URLs, or numeric property IDs, all in one list.
- 🛏️ **Compare stay patterns** with up to 14 lengths of stay and 8 occupancies in a single run.
- 💱 **Price in 51 currencies**, including USD, EUR, GBP, JPY and AED.
- 🚫 **Flag sold-out dates** as rows with `soldOut: true` and empty prices, so gaps in availability stay visible.
- 📊 **Add competitor rates** for up to 100 other properties from Booking.com's search results for the same stay.
- 🧾 **Report the outcome** in the run's status, such as `Saved 28 rate rows. 8 sold out.`, and mark a run as failed when nothing could be loaded.

Because it runs on Apify, you also get:

- [Scheduling](https://docs.apify.com/platform/schedules) for daily or weekly price snapshots
- [API access](https://docs.apify.com/api/v2) with [Python](https://docs.apify.com/api/client/python) and [JavaScript](https://docs.apify.com/api/client/js) clients
- [Integrations](https://docs.apify.com/platform/integrations) with Make, Zapier, Google Sheets, Slack and webhooks
- Export to JSON, CSV, Excel, XML and HTML

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

One row per property × check-in date × length of stay × occupancy.

| Field | Description |
|-------|-------------|
| `hotelId`, `hotelName`, `hotelUrl`, `slug` | Property identity and link |
| `checkin`, `checkout`, `nights`, `adults`, `rooms` | The stay this rate belongs to. `rooms` can be above 1 when Booking.com splits a large party across rooms |
| `soldOut` | `true` when the property has no availability for this stay. Prices and room details are then `null` |
| `totalPrice`, `pricePerNight`, `currency` | The price Booking.com shows in search results for the whole stay, and that price divided by the nights |
| `priceBeforeDiscount` | The struck-through price when the property runs a deal |
| `taxesAndCharges` | The extra Booking.com lists as not included in `totalPrice`. `null` when it shows none separately |
| `roomName`, `bedrooms`, `beds` | The unit the rate was matched to, where Booking.com labels it |
| `mealPlan`, `breakfastIncluded` | What the rate includes |
| `freeCancellation`, `freeCancellationUntil`, `noPrepayment` | Booking conditions attached to the rate |
| `geniusRateAvailable` | Whether Booking.com marks a Genius loyalty rate on the listing |
| `stars`, `reviewScore`, `reviewsCount` | Property quality signals. `null` when the property has none |
| `address`, `district`, `distanceFromCentre`, `city`, `countryCode`, `latitude`, `longitude` | Location |
| `isCompetitor`, `comparedToHotelId`, `comparedToHotelName` | `false` for your properties. On competitor rows, the property they were priced alongside |
| `scrapedAt` | When the rate was captured, the key for your time series |

### How to scrape Booking.com rates

1. Open [Booking.com Rates Scraper](https://apify.com/parsebird/booking-rates-scraper) and click **Try for free**.
2. In **Properties**, add hotel names, Booking.com URLs or property IDs, one per line. URLs and IDs identify a property exactly.
3. Set **First check-in date** and **Last check-in date**, or leave them empty for the next 14 dates.
4. Choose your **Lengths of stay** and **Occupancy**.
5. Pick a **Currency** and set **Maximum rate rows**.
6. Click **Start** and wait for the run to finish.
7. Download the dataset as JSON, CSV or Excel, or connect it to your tools with the [API](https://apify.com/parsebird/booking-rates-scraper/api).

To build a price history, save the input as a [task](https://docs.apify.com/platform/actors/running/tasks) and [schedule](https://docs.apify.com/platform/schedules) it to run daily. Each run's `scrapedAt` separates your snapshots.

### Input parameters

Only `hotels` is required.

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `hotels` | array of strings | **Yes** | — | Hotel names, Booking.com property URLs or numeric property IDs |
| `checkinFrom` | string | No | Tomorrow | First check-in date, `YYYY-MM-DD` |
| `checkinTo` | string | No | 14 dates from the start | Last check-in date, `YYYY-MM-DD`. Dates more than about 500 days ahead are dropped |
| `losNights` | array of strings | No | `["1", "2"]` | Nights per stay, from 1 to 30 |
| `occupancy` | array of strings | No | `["2"]` | Adult counts, from 1 to 8 |
| `currency` | string | No | `USD` | Three-letter currency code for all rates |
| `includeCompetitors` | boolean | No | `false` | Also save up to 100 other properties for the same stay, billed separately |
| `maxItems` | integer | No | `100` | Stop after this many rate rows for your properties. Competitor rows are not counted |

Example: a 90-day rate calendar for two London hotels at two lengths of stay.

```json
{
    "hotels": ["The Savoy, London", "https://www.booking.com/hotel/gb/claridge-s.en-gb.html"],
    "checkinFrom": "2026-12-01",
    "checkinTo": "2027-02-28",
    "losNights": ["1", "2"],
    "occupancy": ["2"],
    "currency": "GBP",
    "includeCompetitors": false,
    "maxItems": 400
}
```

Rate rows are properties × dates × lengths of stay × occupancies. Ten hotels over 90 dates with 3 lengths of stay and 2 occupancies is 5,400 rows, so use `maxItems` to cap a run. The earliest dates are priced first, for all your properties together, so a low cap still covers every hotel.

### Output example

Real rows from test runs: a rate row with taxes listed separately, and a competitor row with a discount.

```json
[
    {
        "hotelId": 38056,
        "hotelName": "Claridge's, Maybourne",
        "hotelUrl": "https://www.booking.com/hotel/gb/claridge-s.en-gb.html",
        "slug": "claridge-s",
        "stars": 5,
        "reviewScore": 9.2,
        "reviewsCount": 504,
        "checkin": "2026-11-18",
        "checkout": "2026-11-19",
        "nights": 1,
        "adults": 2,
        "rooms": 1,
        "soldOut": false,
        "currency": "USD",
        "totalPrice": 3006.22,
        "pricePerNight": 3006.22,
        "priceBeforeDiscount": null,
        "taxesAndCharges": 601.24,
        "roomName": "Claridge’s Studio",
        "bedrooms": null,
        "beds": 1,
        "mealPlan": null,
        "breakfastIncluded": false,
        "freeCancellation": true,
        "freeCancellationUntil": "2026-11-16T00:00:00Z",
        "noPrepayment": true,
        "geniusRateAvailable": false,
        "address": "41 - 43 Brook Street",
        "district": "Westminster Borough, London",
        "distanceFromCentre": "0.9 miles from centre",
        "city": "London",
        "countryCode": "gb",
        "latitude": 51.5126887354378,
        "longitude": -0.147789716720581,
        "isCompetitor": false,
        "comparedToHotelId": null,
        "comparedToHotelName": null,
        "scrapedAt": "2026-11-08T07:20:23.588Z"
    },
    {
        "hotelId": 220590,
        "hotelName": "The Royal Horseguards Hotel, London",
        "stars": 4,
        "reviewScore": 8.6,
        "reviewsCount": 4531,
        "checkin": "2026-12-08",
        "checkout": "2026-12-09",
        "nights": 1,
        "adults": 2,
        "soldOut": false,
        "currency": "EUR",
        "totalPrice": 532.95,
        "pricePerNight": 532.95,
        "priceBeforeDiscount": 592.17,
        "isCompetitor": true,
        "comparedToHotelId": 280149,
        "comparedToHotelName": "The Savoy"
    }
]
```

The second row is shortened here. Competitor rows carry the same fields as your own rows. Download the full dataset as **JSON, CSV, Excel, XML or HTML** from the run's Storage tab.

### Use the Booking.com Rates Scraper API

Python, with the [Apify API client](https://docs.apify.com/api/client/python):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("parsebird/booking-rates-scraper").call(run_input={
    "hotels": ["The Savoy, London"],
    "losNights": ["1", "2"],
    "occupancy": ["2"],
    "currency": "GBP",
    "maxItems": 50,
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["hotelName"], row["checkin"], row["nights"], row["totalPrice"], row["soldOut"])
```

JavaScript, with the [Apify API client](https://docs.apify.com/api/client/js):

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });

const run = await client.actor('parsebird/booking-rates-scraper').call({
    hotels: ['The Savoy, London'],
    losNights: ['1', '2'],
    occupancy: ['2'],
    currency: 'GBP',
    maxItems: 50,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((row) => console.log(row.hotelName, row.checkin, row.nights, row.totalPrice, row.soldOut));
```

### Use cases

- **Revenue management:** see your own rate calendar the way guests see it, across stay lengths.
- **Competitive rate shopping:** compare your property with others in the same destination for identical stays.
- **Rate parity checks:** compare Booking.com prices with your direct or other channel prices.
- **Occupancy pricing analysis:** find out how much a rate changes from 1 to 2 or more adults.
- **Market research:** record prices and sold-out dates around holidays and events.
- **Travel apps:** feed hotel prices into a dashboard, an alert or a price comparison tool.

### How it works

1. The Actor turns each name or URL into a Booking.com property ID. The log shows which property each name matched.
2. It builds the stay matrix from your dates, lengths of stay and occupancies, starting with the earliest dates.
3. It reads the rate Booking.com shows in search results for each stay, up to eight stays at a time.
4. It saves one row per stay, plus competitor rows if you turned them on.
5. It finishes with a status summary. If the run nears its timeout, it stops about 30 seconds early, keeps everything collected so far, and its status says how many stays were not reached.

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

Booking.com Rates Scraper uses pay-per-event pricing, and the price depends on your Apify plan.

| Event | What it covers | Free | Bronze | Silver | Gold |
|-------|----------------|------|--------|--------|------|
| `apify-actor-start` | One charge when a run starts | $0.005 | $0.005 | $0.005 | $0.005 |
| `rate-scraped` | Each rate row for your properties, including sold-out rows | $0.00149 | $0.00139 | $0.00129 | $0.00119 |
| `competitor-rate-scraped` | Each competitor row | $0.00149 | $0.00139 | $0.00129 | $0.00119 |
| **Per 1,000 rows** | | **$1.49** | **$1.39** | **$1.29** | **$1.19** |

For example, the prefilled run of 28 rows costs about $0.05 on the Free plan: $0.005 to start plus 28 rows at $0.00149. A 90-day calendar for two hotels at 2 lengths of stay (360 rows) costs about $0.54. Compute and proxy costs are included in the event price. With competitor rates on, each stay can add up to 100 more rows, so a run with many stays grows quickly.

### FAQ

**Which price is `totalPrice`?**
It's the price Booking.com shows for that stay in its search results. `taxesAndCharges` is the extra Booking.com lists as not included. Booking.com can show prices with taxes included or excluded depending on the visitor's location, so this split can differ from what you see in your own browser.

**Can I use hotel names?**
Yes. Names use Booking.com's own suggestions and take the first hotel it offers. Include the city, then check `hotelName` in your results or the run log, which also lists other close matches. When you need one exact property, use its Booking.com URL or numeric ID.

**Why is a date sold out when I know the hotel has rooms?**
`soldOut: true` means Booking.com showed no availability for that exact stay and occupancy. A different length of stay can still be available, because some hotels set minimum stays.

**How far ahead can I check rates?**
About 500 days. Booking.com stopped returning results after that when we tested in November 2026, and hotels often load their rates for far fewer days, so distant dates can come back sold out.

**How many competitors are returned?**
Up to 100 per stay. In our tests, each stay returned between 84 and 99 unique other properties. They come from Booking.com's own search results for the stay, in Booking.com's order, so they're usually in the same city and aren't sorted by distance. Each row includes coordinates if you want to filter by distance yourself.

**Why did my run stop early?**
A run stops at `maxItems`, at your spending limit, or about 30 seconds before its timeout. Large matrices need a longer timeout, and the status message says how many stays weren't reached. In our tests, 900 rows took about two minutes.

**How much memory should I use?**
Use the default of 512 MB. Runs need at least 256 MB and stop with a clear message below that.

**Can I schedule recurring runs?**
Yes. Use [Apify Schedules](https://docs.apify.com/platform/schedules) to run daily or at any interval, and connect results to your tools with [integrations](https://docs.apify.com/platform/integrations) or the [API](https://apify.com/parsebird/booking-rates-scraper/api).

**Something isn't working. What should I do?**
Open the Actor's **Issues** tab and include your run link. We read every report.

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

This Actor collects publicly available hotel listing data such as prices, availability and property details, and it doesn't log in or access any account. You're responsible for how you use the data, including compliance with Booking.com's terms and the laws that apply to you. See Apify's guide on [whether web scraping is legal](https://blog.apify.com/is-web-scraping-legal/), and consult a lawyer if you're unsure. This Actor is not affiliated with or endorsed by Booking.com.

### Other travel scrapers

- [Hotels.com Scraper](https://apify.com/parsebird/hotels-com-scraper)
- [Airbnb Scraper & API](https://apify.com/parsebird/airbnb-scraper)
- [Expedia Reviews Scraper](https://apify.com/parsebird/expedia-reviews-scraper)
- [HolidayCheck.de Hotels Scraper](https://apify.com/parsebird/holidaycheck-hotels-scraper)

# Changelog

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

# Actor input Schema

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

Add hotel names, Booking.com property URLs or numeric property IDs, one per line. For names, include the city, such as The Savoy, London. The run log shows which property each name matched.

## `checkinFrom` (type: `string`):

Pick the first check-in date in the range. Leave empty to start tomorrow.

## `checkinTo` (type: `string`):

Pick the last check-in date in the range. Leave empty for 14 check-in dates. Dates more than about 500 days ahead are dropped because Booking.com stops returning them.

## `losNights` (type: `array`):

Choose the stay lengths to price. Each check-in date is priced once per length.

## `occupancy` (type: `array`):

Choose the adult counts to price. Each date and length of stay is priced once per occupancy.

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

Choose the currency for all rates.

## `includeCompetitors` (type: `boolean`):

Turn on to also save up to 100 other properties from Booking.com's search results for the same stay. Competitor rows are billed separately and don't count toward Maximum rate rows.

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

Set how many rate rows to save for your properties. Competitor rows are not counted here.

## Actor input object example

```json
{
  "hotels": [
    "The Savoy, London"
  ],
  "losNights": [
    "1",
    "2"
  ],
  "occupancy": [
    "2"
  ],
  "currency": "USD",
  "includeCompetitors": false,
  "maxItems": 100
}
```

# Actor output Schema

## `dataset` (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 = {
    "hotels": [
        "The Savoy, London"
    ],
    "losNights": [
        "1",
        "2"
    ],
    "occupancy": [
        "2"
    ],
    "currency": "USD",
    "includeCompetitors": false,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/booking-rates-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 = {
    "hotels": ["The Savoy, London"],
    "losNights": [
        "1",
        "2",
    ],
    "occupancy": ["2"],
    "currency": "USD",
    "includeCompetitors": False,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/booking-rates-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 '{
  "hotels": [
    "The Savoy, London"
  ],
  "losNights": [
    "1",
    "2"
  ],
  "occupancy": [
    "2"
  ],
  "currency": "USD",
  "includeCompetitors": false,
  "maxItems": 100
}' |
apify call parsebird/booking-rates-scraper --silent --output-dataset

```

## MCP server setup

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