# Booking.com Price Scraper (`rainminer/booking-price-scraper`) Actor

Extract live public Booking.com hotel prices with explicit currency, occupancy/dates context, and taxes/fees breakdown when Booking shows them. Supports destination search, filters, and fast single-hotel lookups. No login required.

- **URL**: https://apify.com/rainminer/booking-price-scraper.md
- **Developed by:** [rainminer](https://apify.com/rainminer) (community)
- **Categories:** Travel, Other
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.37 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does Booking.com Price Scraper do?

**Booking.com Price Scraper** extracts **live public hotel prices** from [Booking.com](https://www.booking.com/) with explicit **currency**, requested **dates/occupancy** context, and **taxes/fees breakdown** when Booking exposes them on the property page. Use a destination search, a Booking search URL (filters preserved), or a single hotel URL for a low-latency lookup — no login or user cookies required.

### What can this Actor do?

- Scrape **destination search results** and optional **hotel detail** enrichment
- Capture **explicit currency** and displayed stay prices (no invented / guessed amounts)
- Extract **room-level offers** with public **VAT / city tax / charges** lines when present
- Capture **minimum nights / min stay** (and maximum nights when Booking shows them) for the stay’s check-in
- Apply common **search filters** (stars, minimum review score, sort, currency, language)
- Flag **priceComplete** and **taxesFeesComplete** so incomplete public data is never silently filled
- Run on the **Apify platform** with scheduling, monitoring, dataset export, and API access

### Why scrape Booking.com prices?

- **Price monitoring** — Track live public rates for competitors or portfolio hotels
- **Travel intelligence** — Compare destinations with consistent occupancy and currency
- **Tax transparency** — Keep excluded/included fee lines when Booking shows them
- **Apify platform** — Schedule runs and export JSON, CSV, Excel, or webhooks

### What data can you extract?

| Field                                           | Description                                                                    |
| ----------------------------------------------- | ------------------------------------------------------------------------------ |
| name                                            | Hotel name                                                                     |
| url                                             | Canonical public hotel URL with stay params                                    |
| imageUrl / image                                | Primary hotel image (`image` aliases `imageUrl` for drop-in pipelines)         |
| imageUrls / images                              | Image gallery when available                                                   |
| currency                                        | Parsed display currency (for example EUR, USD)                                 |
| priceAmount / price                             | Stay price amount (`price` aliases `priceAmount` for drop-in pipelines)        |
| pricePerNightAmount                             | Per-night amount when Booking shows it                                         |
| totalWithTaxesFeesAmount                        | Total including publicly shown taxes/fees when available                       |
| taxesAndFees                                    | Line items (VAT, city tax, etc.) with included/excluded flags                  |
| roomOffers                                      | Room/block-level public offers for the stay                                    |
| minimumNights                                   | Min stay / minimum nights for the check-in when Booking exposes it             |
| maximumNights                                   | Maximum nights when Booking exposes it (often null)                            |
| reviewScore / rating                            | Public review score (`rating` alias)                                           |
| reviewCount / reviews                           | Public review count (`reviews` alias)                                          |
| reviewScoreWord / ratingLabel                   | Score label such as "Excellent"                                                |
| stars / type / description / location           | Stars, property type, description, `{ lat, lng }` when public                  |
| address / addressDetails / city / countryCode   | Address string plus structured details                                         |
| checkIn / checkOut / checkInDate / checkOutDate | Requested stay dates (ISO). Policy times are in `checkInTime` / `checkOutTime` |
| adults / children / childrenAges / rooms        | Requested stay context (`rooms` = occupancy count)                             |
| breakfast                                       | Meal plan / breakfast hint when Booking exposes it                             |
| priceComplete                                   | True only when amount + currency were explicitly present                       |
| taxesFeesComplete                               | True only when a public taxes/fees breakdown (or total with fees) was present  |
| completenessNotes                               | Human-readable gaps — never silent empty success                               |
| guessedPrice                                    | Always `false` — this Actor does not invent prices                             |

### How to scrape Booking.com hotel prices

1. Open the Actor in Apify Console.
2. Enter a **destination** (for example `Amsterdam`) and/or **Start URLs** (search or hotel pages).
3. Set **check-in / check-out** (or leave blank for dynamic ~30/32-day defaults), guests, **childrenAges** when traveling with children, rooms, and preferred **currency**.
4. Keep **Enrich hotel details** enabled for taxes/fees fidelity (disable for faster search-card-only runs).
5. Set **Max hotels per start URL** (default 5) and run.
6. Download results from the dataset tab.

### Supported URL patterns

- Search results: `https://www.booking.com/searchresults*.html?...`
- Hotel detail: `https://www.booking.com/hotel/{country}/{hotel-slug}.html`

Dates and occupancy on the URL are overwritten by the Actor input stay context so runs stay reproducible.

### Input

This Actor keeps a **price-fidelity wedge**: dynamic default dates, required child ages, honest completeness flags, and no guessed prices.

| Field                                | Notes                                                                                  |
| ------------------------------------ | -------------------------------------------------------------------------------------- |
| search                               | Destination text                                                                       |
| startUrls                            | Optional Booking search/hotel URLs (public pages only; no account shared lists)        |
| checkIn / checkOut                   | `YYYY-MM-DD`; leave empty for dynamic ~30/32 days ahead                                |
| flexWindow                           | Optional stay flexibility (`0`/`1`/`2`/`3`/`7`) for search/destination                 |
| adults / rooms                       | Occupancy context                                                                      |
| childrenAges                         | Ages 0–17 per child (required for accurate child pricing; sets `age=` on Booking URLs) |
| children                             | Optional; must match `childrenAges.length` when both are set                           |
| currency / language                  | Display preferences (expanded enums)                                                   |
| propertyType                         | Booking property-type filter (`Hotels`, `Apartments`, …)                               |
| minMaxPrice                          | Per-night range such as `100-150` or `100+`                                            |
| starsCountFilter / minScore / sortBy | Search filters (includes `unrated` stars)                                              |
| enrichHotelDetails                   | Room + taxes/fees enrichment (default `true`)                                          |
| extractAdditionalHotelData           | Alias of `enrichHotelDetails`; used only when that field is omitted                    |
| maxItems                             | Per start URL / destination                                                            |
| proxyConfiguration                   | Default off; enable residential if your IP is blocked                                  |

### Output example

```json
{
  "name": "citizenM Amsterdam South",
  "url": "https://www.booking.com/hotel/nl/citizenm-amsterdam-city.en-gb.html?checkin=2026-09-07&checkout=2026-09-09&group_adults=2&no_rooms=1&selected_currency=EUR",
  "imageUrl": "https://cf.bstatic.com/xdata/images/hotel/max500/772469520.jpg",
  "image": "https://cf.bstatic.com/xdata/images/hotel/max500/772469520.jpg",
  "currency": "EUR",
  "priceAmount": 296,
  "price": 296,
  "pricePerNightAmount": 148,
  "totalWithTaxesFeesAmount": 395,
  "taxesAndFees": [
    {
      "label": "21 % VAT",
      "amount": 62.16,
      "included": false,
      "type": "percentage__excluded"
    },
    {
      "label": "12.50 % City tax",
      "amount": 37.0,
      "included": false,
      "type": "percentage__excluded"
    }
  ],
  "rating": 8.6,
  "reviews": 2450,
  "ratingLabel": "Excellent",
  "stars": 4,
  "type": "hotel",
  "location": { "lat": "52.3676", "lng": "4.9041" },
  "checkIn": "2026-09-07",
  "checkOut": "2026-09-09",
  "checkInDate": "2026-09-07",
  "checkOutDate": "2026-09-09",
  "adults": 2,
  "children": 0,
  "childrenAges": [],
  "rooms": 1,
  "minimumNights": 1,
  "maximumNights": null,
  "priceComplete": true,
  "taxesFeesComplete": true,
  "guessedPrice": false,
  "priceSource": "hotel_rooms",
  "completenessNotes": [
    "Price taken from public hotel room offers for the requested stay context."
  ]
}
```

### Pricing

This Actor can be monetized on Apify with pay-per-event pricing after publication. Platform compute and proxy usage are billed separately by Apify.

### FAQ

#### Why is maximumNights often null?

Booking commonly publishes a **minimum** stay for a check-in date, but does not always publish a matching **maximum** nights limit on the public hotel page. When it is missing, the field is `null` — this Actor does not invent limits.

#### Does this Actor log in to Booking.com?

No. It only reads **public** search and hotel pages. It does not accept Booking usernames, passwords, or user session cookies.

#### Why are taxes/fees sometimes missing?

Booking often shows a clean search-card price and only exposes the full charges breakdown on the hotel page. Enable **Enrich hotel details**. If enrichment fails after retries, the Actor keeps an honest search-card fallback with `taxesFeesComplete=false` instead of silently dropping the row. If Booking still does not publish a breakdown for that stay, completeness flags and notes explain the gap — prices are never guessed.

#### Do I need child ages?

Yes whenever `children > 0`. Booking prices depend on each child's age. Provide `childrenAges` (for example `[5, 8]`); the Actor sends Booking `age=` / `req_age=` parameters. Runs with children but no ages fail validation instead of returning inaccurate prices.

#### What happens if the run finds nothing?

If every requested search/hotel fails or is blocked and **no rows are pushed**, the Actor exits with code `1`. Empty successful runs are not allowed.

#### Can I scrape a single hotel quickly?

Yes. Pass a hotel URL in **Start URLs**. The Actor skips destination search and loads that property with your dates/occupancy.

#### Do I need a proxy?

Many environments clear Booking’s AWS WAF browser challenge without a proxy. If runs are blocked in your region or on datacenter IPs, enable Apify **residential** proxies in the input.

### Related scrapers

Looking for other travel sources? See rainminer hotel Actors such as eDreams Hotels Scraper, Despegar Hotels Scraper, and hotel.de Scraper on Apify Store.

### Image Credit

Image credit: [Booking.com](https://www.booking.com/)

# Actor input Schema

## `search` (type: `string`):

Destination name when not using Start URLs (for example Amsterdam, Paris, New York).

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

Booking.com searchresults or hotel detail URLs. Search URL filters are kept unless overridden by scraper inputs. Hotel URLs are scraped as single-property lookups. Shared Booking account list URLs are not supported (public data only).

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

Maximum hotels to save per start URL / destination search.

## `enrichHotelDetails` (type: `boolean`):

Open each hotel page to extract room-level prices and public taxes/fees breakdown. Recommended for price fidelity. Disable for faster search-card-only runs.

## `extractAdditionalHotelData` (type: `boolean`):

Alias of enrichHotelDetails. Used only when enrichHotelDetails is omitted. Enables hotel-page enrichment (room offers + taxes/fees). Does not scrape account-only data.

## `propertyType` (type: `string`):

Filter search results by Booking property type (applied via public search filters).

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

Booking search sort order.

## `minScore` (type: `string`):

Minimum review score filter in "8.4" format. Empty means no filter. Searching below 5 may be inefficient (not natively supported by Booking).

## `starsCountFilter` (type: `string`):

Only scrape places with the selected stars count. Includes Booking's unrated option.

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

Currency Booking should display (selected\_currency).

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

Language to be set on the website (locale path segment).

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

Check-in date (YYYY-MM-DD, UTC). Leave empty to default to 30 days from today.

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

Check-out date (YYYY-MM-DD, UTC). Leave empty to default to 32 days from today.

## `flexWindow` (type: `string`):

Number of days to flex around check-in/out for search-style URLs and destination search. Ignored for direct hotel URLs.

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

Number of rooms.

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

Number of adult guests.

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

Optional child count. When set above 0 it must match childrenAges length. Prefer childrenAges alone — Booking prices depend on each child's age.

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

Ages (0–17) for each child. Required for accurate child pricing. Children count is derived from this list when provided. Example: \[5, 8].

## `minMaxPrice` (type: `string`):

Minimum and maximum price per night, e.g. '100-150' or '100+'. Wide-open '0-999999' is treated as no filter.

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

Proxy settings. Public Booking pages often work without a proxy after the AWS WAF browser challenge; enable residential proxies if your environment is blocked.

## Actor input object example

```json
{
  "search": "Amsterdam",
  "startUrls": [
    {
      "url": "https://www.booking.com/searchresults.en-gb.html?ss=Amsterdam&ssne=Amsterdam&ssne_untouched=Amsterdam&dest_id=-2140479&dest_type=city&group_adults=2&no_rooms=1&group_children=0"
    }
  ],
  "maxItems": 5,
  "enrichHotelDetails": true,
  "extractAdditionalHotelData": false,
  "propertyType": "none",
  "sortBy": "popularity",
  "starsCountFilter": "any",
  "currency": "EUR",
  "language": "en-gb",
  "rooms": 1,
  "adults": 2,
  "children": 0,
  "childrenAges": [],
  "minMaxPrice": "0-999999",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "search": "Amsterdam",
    "startUrls": [
        {
            "url": "https://www.booking.com/searchresults.en-gb.html?ss=Amsterdam&ssne=Amsterdam&ssne_untouched=Amsterdam&dest_id=-2140479&dest_type=city&group_adults=2&no_rooms=1&group_children=0"
        }
    ],
    "maxItems": 5,
    "starsCountFilter": "any",
    "currency": "EUR",
    "language": "en-gb",
    "minMaxPrice": "0-999999",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

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

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = {
    "search": "Amsterdam",
    "startUrls": [{ "url": "https://www.booking.com/searchresults.en-gb.html?ss=Amsterdam&ssne=Amsterdam&ssne_untouched=Amsterdam&dest_id=-2140479&dest_type=city&group_adults=2&no_rooms=1&group_children=0" }],
    "maxItems": 5,
    "starsCountFilter": "any",
    "currency": "EUR",
    "language": "en-gb",
    "minMaxPrice": "0-999999",
    "proxyConfiguration": { "useApifyProxy": False },
}

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

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

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

```

## CLI example

```bash
echo '{
  "search": "Amsterdam",
  "startUrls": [
    {
      "url": "https://www.booking.com/searchresults.en-gb.html?ss=Amsterdam&ssne=Amsterdam&ssne_untouched=Amsterdam&dest_id=-2140479&dest_type=city&group_adults=2&no_rooms=1&group_children=0"
    }
  ],
  "maxItems": 5,
  "starsCountFilter": "any",
  "currency": "EUR",
  "language": "en-gb",
  "minMaxPrice": "0-999999",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call rainminer/booking-price-scraper --silent --output-dataset

```

## MCP server setup

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