# Booking.com Scraper: Hotel Prices, Ratings, Deals & Alerts (`euroscrape/booking-prices`) Actor

Booking.com scraper & hotel price API: hotels of any city for your dates with price per night, review score and count, stars, free cancellation, breakfast, distance to centre, deals. Price calendars over many dates, cheapest and best-value hotel per city, price-drop alerts.

- **URL**: https://apify.com/euroscrape/booking-prices.md
- **Developed by:** [EuroScrape](https://apify.com/euroscrape) (community)
- **Categories:** Travel, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 hotel price delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Booking.com Scraper: Hotel Prices, Ratings, Deals & Alerts

**Every hotel of a city for your dates, as rows: price per night and total, guest score and number of reviews, stars, free cancellation, breakfast, distance to the centre, deals.** Give it one or several cities and a check-in date, or thirty check-in dates for a price calendar, and get back what Booking.com shows a traveller, in the currency you choose, with a free summary per destination: median price, cheapest hotel, best value, price drops since yesterday.

![Hotel prices, ratings and review counts for a city and dates](https://api.apify.com/v2/key-value-stores/whPh2zNCcrRkrWi0g/records/demo-booking-prices.png?signature=xe557d3isYOmsvgfSSfN)

- 🏨 **Any destination**: cities, districts, lakes or landmarks, as typed on Booking.com, in 40+ languages.
- 📅 **Price calendars**: the same search for 7, 30 or 90 check-in dates in a row, or the same weekday every week.
- 🧾 **Rate conditions**: free cancellation, breakfast included, rooms left at this price, taxes included or not, the room offered.
- 📊 **Free summary per destination and date**: median, lowest and highest price per night, median score, share of free cancellation, median price by stars, cheapest and best-value hotel.
- 🔔 **Price-drop alerts**: name a monitor and schedule the Actor; each run compares with the previous one and sends drops to Telegram, Discord, Slack or a webhook.

### ✨ Why this Actor

| | |
|---|---|
| 💶 **Prices as numbers** | Per night and for the stay, before and after a shown discount, with the currency and whether taxes are included. |
| 🎯 **Filters that match the site** | Review score, stars, property type, free cancellation, breakfast, price range: the same filters as Booking.com, applied by the site, so the counts are the site's counts. |
| 🧭 **Best value, not just cheapest** | The summary names the cheapest hotel and the best-value one (score 8 or more, at least 50 reviews, lowest price). |
| 🔁 **Monitoring built in** | A monitor name turns any search into a daily watch: `changeType`, previous price and change in % on every row. |
| 💸 **Pay per hotel** | $0.002 per hotel and stay delivered. Summaries and the first baseline of a monitor are free. |

### 🎯 Use cases

- **Travellers and travel agents**: the cheapest week to go, the hotels under a budget with free cancellation, an alert when a price drops.
- **Hotels and revenue managers**: the competitive set of a city for the next 30 days, median price by stars, who discounts and by how much.
- **Rental investors and analysts**: median prices and occupancy signals (rooms left) for a district, dates and seasons.
- **Media and research**: price levels of European cities for the same dates, in one currency.

### 🚀 Examples

**Lisbon, two nights in two weeks, 50 hotels, prices in euros:**

```json
{
  "locations": ["Lisbon"],
  "nights": 2,
  "maxHotelsPerLocation": 50
}
```

**Price calendar: Paris, every day of November, 4-star hotels rated 8 or more, free cancellation:**

```json
{
  "locations": ["Paris"],
  "checkInDate": "2026-11-01",
  "numberOfDates": 30,
  "nights": 1,
  "hotelClasses": [4],
  "minReviewScore": 8,
  "freeCancellation": true,
  "sortBy": "price_asc",
  "maxHotelsPerLocation": 25
}
```

**Daily watch of three cities with price-drop alerts on Telegram:**

```json
{
  "locations": ["Barcelona", "Porto", "Seville"],
  "checkInDate": "2026-12-05",
  "nights": 3,
  "monitorName": "december-weekend",
  "onlyChanges": true,
  "alertOnPriceDropPct": 15,
  "telegramBotToken": "123456:ABC…",
  "telegramChatId": "987654321"
}
```

### 📦 Output

One row per hotel and stay (`type: "hotel"`) and one free `destinationSummary` row per location and date. Two ready-made views, **Hotels** and **Destination summary**; exports to JSON, CSV or Excel.

A hotel (real data, Lisbon, two nights):

```json
{
  "type": "hotel",
  "location": "Lisbon", "checkIn": "2026-11-10", "checkOut": "2026-11-12", "nights": 2, "adults": 2,
  "position": 1,
  "name": "Charming Suites Chiado",
  "url": "https://www.booking.com/hotel/pt/charming-suites-chiado.en-gb.html",
  "countryCode": "PT", "area": "Santa Maria Maior, Lisbon", "distanceFromCentreKm": 0.35,
  "stars": null, "reviewScore": 7.5, "reviewLabel": "Good", "reviewCount": 137, "guestFavourite": true,
  "dealBadge": "Limited-time Deal",
  "priceTotal": 156, "pricePerNight": 78, "originalPriceTotal": 216, "discountPct": 28, "currency": "EUR", "taxesIncluded": true,
  "roomName": "Double Room with Private Bathroom", "freeCancellation": true, "breakfastIncluded": false, "unitsLeftAtThisPrice": 1,
  "imageUrl": "https://cf.bstatic.com/xdata/images/hotel/max500/…",
  "changeType": null
}
```

The destination summary:

```json
{
  "type": "destinationSummary",
  "location": "Lisbon", "checkIn": "2026-11-10", "checkOut": "2026-11-12", "nights": 2, "currency": "EUR",
  "status": "ok", "propertiesOnSite": 2632, "hotelsCollected": 50, "hotelsDelivered": 50,
  "medianPricePerNight": 121.5, "minPricePerNight": 39, "maxPricePerNight": 412,
  "medianReviewScore": 8.6, "shareFreeCancellationPct": 64, "shareBreakfastIncludedPct": 18,
  "byStars": [ { "stars": 3, "hotels": 9, "medianPricePerNight": 92 }, { "stars": 4, "hotels": 21, "medianPricePerNight": 138 }, { "stars": 5, "hotels": 4, "medianPricePerNight": 290 } ],
  "cheapest": { "name": "…", "pricePerNight": 39, "reviewScore": 7.9, "url": "…" },
  "bestValue": { "name": "…", "pricePerNight": 84, "reviewScore": 8.8, "reviewCount": 2271, "url": "…" },
  "priceDrops": 0
}
```

### 🧮 How the numbers are computed

- **Prices** are read as Booking.com shows them to a visitor for your dates, guests and rooms, in the currency you choose (`selected_currency`), with Booking's own discount when there is one. `pricePerNight` is the stay price divided by the nights.
- **Summary** medians use every hotel collected for that location and date (set `maxHotelsPerLocation` to 100 or more for a market view, and leave `sortBy` on Booking's default rather than `price_asc`, which would bias the medians).
- **Best value**: among hotels with a score of 8 or more and at least 50 reviews, the lowest price per night.
- **Monitoring** compares the price per night of each hotel with the previous run of the same monitor name, location, check-in date and stay length.

### 💰 Pricing

| Event | Price |
|---|---|
| Hotel price delivered (one hotel, one stay) | **$2 / 1,000** |
| Run start | $0.003 |
| Destination summaries, monitor baseline | free |

A city for 30 check-in dates with 25 hotels each costs about $1.50. Apify subscribers pay less: −10% (Starter), −20% (Scale), −30% (Business). Set a **maximum cost per run** in the run options and the Actor stops cleanly when it is reached.

### ❓ FAQ

**Is the price the final price?** It is the price Booking.com shows in the results for your search, taxes included when Booking says so (`taxesIncluded`). Some destinations add city taxes at the property; Booking shows that on the hotel page, not in the results.

**Why fewer hotels than `propertiesOnSite`?** `maxHotelsPerLocation` caps what is collected (25 per page, up to 1,000); the site's total is kept in the summary.

**What does `status: "blocked"` mean?** Booking.com sometimes answers a bot challenge instead of results. The Actor retries through other IPs, then residential ones; if every attempt is challenged, the search is reported as blocked and nothing is charged for it. Run again later or with a residential proxy group.

**Can I watch one hotel rather than a city?** Search its district with `maxHotelsPerLocation` large enough and filter the dataset on `hotelSlug`; a hotel-page mode is on the roadmap.

**Is this personal data?** No: hotels are businesses, and nothing about guests or reviewers is collected.

### 🔌 API, AI agents and integrations

- **API**: one call runs the Actor and returns the results, `POST https://api.apify.com/v2/acts/euroscrape~booking-prices/run-sync-get-dataset-items` (see the API tab for Python, JavaScript and cURL).
- **AI agents (MCP)**: add `https://mcp.apify.com?tools=euroscrape/booking-prices` to Claude, Cursor, VS Code or any MCP client, and the Actor becomes a tool your agent can call.
- **No-code automation**: start runs and pass the results on with Apify's integrations for n8n, Make and Zapier, or with a webhook when a run ends.
- **Exports**: every result set downloads as JSON, CSV, Excel or XML, and can be sent to Google Sheets.

### ⭐ Your feedback

Found a bug or missing a field? Open an issue on the Actor's Issues tab. A short review on the Apify Store helps other users find this Actor.

### 🔗 More from EuroScrape

- [Google Hotels Scraper (Google Travel): Prices on Booking Sites](https://apify.com/euroscrape/google-hotels-prices): hotel prices for any destination and dates with the price on every booking site, rate parity and price calendars.
- [Google Flights Scraper: Cheapest Dates, Prices & Price History](https://apify.com/euroscrape/google-flights-prices): flight prices for any route and dates, cheapest day to fly and price-drop alerts.
- [Ryanair Low Fare Finder: Cheapest Days, Anywhere & Alerts](https://apify.com/euroscrape/ryanair-low-fares): the cheapest day of the month on a route, every destination under a price cap.
- [AutoScout24 Scraper: Used Cars in 8 Countries, Deals & Alerts](https://apify.com/euroscrape/autoscout24-scraper): used cars across eight countries with the market price of similar cars.
- [App Store Reviews Scraper + Google Play Reviews (All Countries)](https://apify.com/euroscrape/app-reviews): newest reviews of any app in 58 countries, with a summary per country and version.

# Actor input Schema

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

Cities, areas or landmarks as you would type them on Booking.com: "Lisbon", "Paris 11e", "Lake Como", "Barcelona Eixample".

## `checkInDate` (type: `string`):

First check-in date (YYYY-MM-DD). Default: in 14 days.

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

Length of stay.

## `numberOfDates` (type: `integer`):

Check prices for several check-in dates in a row, e.g. 30 = every day of the next month (a price calendar).

## `daysBetweenDates` (type: `integer`):

1 = every day, 7 = the same weekday every week.

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

Number of adult guests.

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

One age per child, e.g. \[4, 9].

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

Number of rooms.

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

ISO code of the currency of all prices (EUR, USD, GBP…).

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

Booking.com language code for names and labels: en-gb, en-us, fr, de, es, it, nl, pt-pt…

## `maxHotelsPerLocation` (type: `integer`):

Booking shows 25 per page; up to 1,000.

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

Order of Booking's results, which decides which hotels are collected when the cap is reached.

## `minReviewScore` (type: `integer`):

6, 7, 8 or 9 (Booking's filter steps).

## `hotelClasses` (type: `array`):

Keep only these star ratings, e.g. \[4, 5].

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

Leave empty for all.

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

Keep only rates with free cancellation.

## `breakfastIncluded` (type: `boolean`):

Keep only rates with breakfast included.

## `minPricePerNight` (type: `integer`):

In the chosen currency.

## `maxPricePerNight` (type: `integer`):

In the chosen currency.

## `includeSummary` (type: `boolean`):

One free row per location and date: median, lowest and highest price per night, median review score, share of free cancellation and breakfast, median price by stars, cheapest and best-value hotel.

## `monitorName` (type: `string`):

Name this search and schedule the Actor (e.g. daily): each hotel row then carries the price change since the previous run, and price drops trigger the alerts below. The first run saves the baseline.

## `onlyChanges` (type: `boolean`):

Skip unchanged prices and price increases (cheaper runs).

## `alertOnPriceDropPct` (type: `integer`):

Monitoring: send an alert when a price per night drops by this percentage or more.

## `telegramBotToken` (type: `string`):

Alerts on Telegram: create a bot with @BotFather and paste its token.

## `telegramChatId` (type: `string`):

Your chat ID (send a message to your bot, then open api.telegram.org/bot<token>/getUpdates).

## `discordWebhookUrl` (type: `string`):

Alerts in a Discord channel: Channel settings → Integrations → Webhooks.

## `slackWebhookUrl` (type: `string`):

Alerts in Slack: create an Incoming Webhook for your channel.

## `webhookUrl` (type: `string`):

Receives one POST per run with all price drops (Make, Zapier, n8n…).

## `maxNotifications` (type: `integer`):

Maximum number of alert messages per run.

## `useBrowser` (type: `boolean`):

Booking.com answers plain HTTP requests with a bot challenge; a headless browser passes it. Turn off only to try the cheaper HTTP mode.

## `proxy` (type: `object`):

Apify Proxy is recommended: datacenter IPs first, residential only when Booking challenges the request.

## Actor input object example

```json
{
  "locations": [
    "Lisbon"
  ],
  "nights": 1,
  "numberOfDates": 1,
  "daysBetweenDates": 1,
  "adults": 2,
  "childrenAges": [],
  "rooms": 1,
  "currency": "EUR",
  "language": "en-gb",
  "maxHotelsPerLocation": 25,
  "sortBy": "relevance",
  "hotelClasses": [],
  "propertyTypes": [],
  "freeCancellation": false,
  "breakfastIncluded": false,
  "includeSummary": true,
  "onlyChanges": false,
  "alertOnPriceDropPct": 10,
  "maxNotifications": 30,
  "useBrowser": true,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per hotel and stay with price per night, score, stars and rate conditions.

## `summary` (type: `string`):

Median, lowest and highest price per night, cheapest and best-value hotel per location and date.

## `runSummary` (type: `string`):

Counters for this run (output, blocked searches, proxy tiers).

# 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 = {
    "locations": [
        "Lisbon"
    ],
    "maxHotelsPerLocation": 25,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("euroscrape/booking-prices").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 = {
    "locations": ["Lisbon"],
    "maxHotelsPerLocation": 25,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("euroscrape/booking-prices").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 '{
  "locations": [
    "Lisbon"
  ],
  "maxHotelsPerLocation": 25,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call euroscrape/booking-prices --silent --output-dataset

```

## MCP server setup

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

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/hfCj20MhGTA1GgbxU/builds/85KonImtL6i4i8Wvd/openapi.json
