Booking.com Hotel Price Monitor & Availability
Pricing
from $1.00 / 1,000 hotel dates
Booking.com Hotel Price Monitor & Availability
Nightly price and availability for every check-in date of a Booking.com hotel, up to a year ahead: cheapest rate, sold-out flag, rooms left, free cancellation deadline, tax-inclusion note. One row per hotel and date. Not affiliated with Booking.com.
Pricing
from $1.00 / 1,000 hotel dates
Rating
0.0
(0)
Developer
Aleksandr Kobtsev
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Track the nightly price and availability of any Booking.com hotel for every check-in date up to a year ahead. One row per hotel and date: the cheapest rate for the stay and per night, whether the date is sold out, how many rooms are left at that price, the free-cancellation deadline, the meal plan, and whether the price already includes local taxes.
You bring the hotel page URLs. No login, no Booking.com account, no partner API. Run it once, put it on a schedule, or call it from the API, and send the rows to Google Sheets, Slack, Make, Zapier or an MCP client.
Who is this Booking.com price monitor for?
| You are | What you run | What you get |
|---|---|---|
| A revenue manager watching a comp set | 10 hotel URLs, 90 dates | 900 rows: who is priced where, and who is full, for the next quarter |
| A short-let or small hotel owner | your own property, 180 dates, weekly | a rate calendar half a year out, refreshed every Monday |
| A deal hunter or travel planner | one hotel, 365 dates | the cheapest night in the year, and the sold-out weeks to avoid |
| Building a rate-shopping or BI product | any number of URLs through the API | a clean price series per hotel and date |
If you do not have the hotel links yet, the companion
Booking.com Scraper lists the hotels of a
city, region or airport with their prices, and the hotelUrl of each row goes straight into this
Actor.
If you need every rate a hotel offers on a date, with room types, cancellation and prepayment terms for each of them, use the companion Actor Booking.com Hotel Price Calendar Scraper. It reads the full room table and costs more per row, because it drives a browser. This Actor reads one price per date over plain HTTP, which is why it runs in 512 MB and finishes a year of dates in about six minutes.
If you want what guests wrote about a hotel, the companion Booking.com Reviews Scraper returns its reviews, one row per review. It takes the same hotel links, or the hotel numbers of this Actor.
What makes this different from other Booking.com scrapers?
- It monitors, it does not search. Most Booking.com Actors answer "which hotels are in this city". This one answers "what does this hotel cost on the 10th, the 11th, the 12th, and is it still open", for the hotels you name.
- It verifies before it bills. Every answer is checked against what you asked for: the property itself, matched on the URL you pasted and not on a similar name in another town; the check-in and check-out dates the answer echoes back; and the currency of the price. A date that fails any of those is rejected and never charged.
- It tells sold out from broken. A date with no rooms comes back with
soldOut: true, a real answer that people monitor availability for. A blocked request, a missing property or a malformed answer produces no row and no charge, and a hotel that cannot be read is named in theFAILED_HOTELSrecord so you can re-run exactly that. - It says whether taxes are in the price. Booking.com quotes with or without local tax
depending on where the request comes from. Every row carries
pricesIncludeTaxes, so a calendar built on Monday compares correctly with one built on Tuesday. - A run that collects nothing fails. It does not finish green with an empty dataset.
What data does it return?
One row per hotel and check-in date.
| Field | What it is |
|---|---|
| hotelUrl, hotelId, hotelName | The property, as Booking.com identifies it. hotelId is the stable join key. |
| checkIn, checkOut, nights | The stay this row priced. |
| adults, rooms, childrenAges | The occupancy it was priced for. Change it and the prices change. |
| currency | Confirmed against the answer, not just requested. |
| soldOut | true when the property has nothing bookable for that stay. A billed row. |
| totalPrice | The cheapest rate for the whole stay. null when sold out. |
| pricePerNight | totalPrice divided by nights. |
| priceBeforeDiscount | The crossed-out price, when Booking.com shows one. |
| pricesIncludeTaxes | true, false, or null when the answer carried no tax information. See below. |
| cheapestRoomId | Booking.com's id of the room behind the cheapest rate. |
| roomsLeft | "Only N rooms left at this price" as a number; null when there is no such message. |
| freeCancellationUntil | When the cheapest rate stops being refundable; null if it never was. |
| mealPlan | Meal plan on the cheapest rate, when Booking.com prints one. |
| scrapedAt | When it was collected, ISO-8601 UTC. |
{"hotelUrl": "https://www.booking.com/hotel/ge/radisson-blu-batumi.html","hotelId": "320991","hotelName": "Radisson Blu Hotel Batumi","checkIn": "2026-11-04","checkOut": "2026-11-05","nights": 1,"adults": 2,"rooms": 1,"childrenAges": [],"currency": "USD","soldOut": false,"totalPrice": 227.57,"pricePerNight": 227.57,"priceBeforeDiscount": null,"pricesIncludeTaxes": true,"cheapestRoomId": "32099112","roomsLeft": null,"freeCancellationUntil": null,"mealPlan": null,"scrapedAt": "2026-09-23T12:00:00.000Z"}
What to do with it. Put the run on a weekly or daily schedule, send the dataset to Sheets
or BigQuery, and key rows on hotelId plus checkIn. A change in pricePerNight is a rate
move; a change in soldOut is the market filling up; roomsLeft dropping is the last warning
before it does.
Do Booking.com prices include tax?
Booking.com decides whether to quote with or without local tax from the country it infers for
the request. From the default Apify datacenter addresses the quote is tax-exclusive and the row
says pricesIncludeTaxes: false; from most residential addresses it is tax-inclusive and the
row says true. Measured on one Georgian property, same date, minutes apart: 190 USD from a
datacenter address, 220 USD from a home address, the gap being local VAT.
Both are genuine prices. What breaks a calendar is mixing them without noticing, which is why
every row states the regime. Whatever address you run from, compare rows with the same value
of pricesIncludeTaxes. To get the tax-inclusive quote, run through your own proxies in the
country you want to buy from.
How much does it cost?
One billed row is one hotel on one check-in date. Thirty dates are thirty rows on every hotel, always, so the bill is predictable before you start.
| Event | Price | When |
|---|---|---|
| Hotel date | $0.0015, falling to $0.001 by plan | Per row that reaches the dataset |
| Actor start | $0.00005 | Once per run; at 512 MB it is a single start event |
| Result | $0.00001 | Per stored row, about one cent per thousand rows |
The hotel-date price steps down with your Apify plan: $0.0015 on the free plan and on Bronze, $0.00125 on Silver, and $0.001 on Gold and above.
What that means for real jobs, all three charges included:
| Job | Rows | Free plan | Gold and above |
|---|---|---|---|
| One hotel, a month ahead | 30 | $0.05 | $0.03 |
| One hotel, a quarter ahead | 90 | $0.14 | $0.09 |
| One hotel, a year ahead | 365 | $0.55 | $0.37 |
| Ten competitors, a quarter ahead | 900 | $1.36 | $0.91 |
| One property, 60-date window, refreshed daily for a month | 1,800 | $2.72 | $1.82 |
Sold-out dates are charged, because "no rooms on that date" is a real answer. Nothing else is: not a blocked request, not an answer for the wrong property, wrong dates or wrong currency, and not a malformed answer.
Set Maximum total charge on the run to cap spending. The Actor stops cleanly at the budget
and names the hotels it did not reach in the FAILED_HOTELS key-value store record.
How to monitor Booking.com hotel prices
- Open the hotel on Booking.com and copy the page URL. Anything like
https://www.booking.com/hotel/ge/radisson-blu-batumi.htmlworks. Dates, language and tracking parameters already in the link are ignored. - Paste one or more URLs into Hotel page URLs.
- Choose the first check-in date, how many dates to cover, nights per stay, guests and currency.
- Run it. Download the dataset as JSON, CSV or Excel, or read it through the API.
- For a price history, put the run on a schedule and keep every run's dataset.
| Field | Default | What it does |
|---|---|---|
hotelUrls | none | Booking.com hotel page links, one per line. A link carries no hotel number, so the hotel is looked up by the name in it; about two links in three are found. A link that is not found is listed in FAILED_HOTELS and not billed. |
hotelIds | none | Booking.com's own hotel numbers, such as 320991: the hotelId column of the Booking.com Scraper output. Exact, no lookup. Use it for the links that are not found. Can be combined with hotelUrls. |
startDate | tomorrow | First check-in date, YYYY-MM-DD (UTC). Today is allowed; a past date is moved to today. |
days | 90 | Number of consecutive check-in dates, per hotel. Each hotel and date pair is one billable row. Up to 365. |
nights | 1 | Length of stay for every check-in date. |
adults | 2 | Adult guests. Occupancy changes prices, so compare like for like. |
childrenAges | [] | Age of each child, e.g. [5, 9]. Booking.com prices children by age. |
rooms | 1 | Rooms to price. |
currency | USD | Verified in every answer. A wrong currency means the date is rejected and not charged. |
concurrency | 2 | Dates requested at the same time. |
proxy | Apify datacenter | Measured on Booking.com: 635 of 635 requests answered. Apify residential groups are refused before any row is charged. For a specific country, or a residential address, choose Custom proxies and supply your own. The country decides pricesIncludeTaxes. |
dryRun | false | Owner-only switch for the maintainer's own monitoring. Ignored for everyone else. |
How fast is it, and what does it not do?
Measured from the default Apify datacenter proxy: about one second per date, a year of dates for one hotel in six minutes, nine hotels over a month each in under five.
- One price per date: the cheapest rate Booking.com shows for your occupancy. For every rate with its room type and terms, use the companion Actor linked above.
- Prices are what Booking.com showed at scrape time. They move constantly; scrape on a schedule for a trend.
priceBeforeDiscount,roomsLeft,freeCancellationUntilandmealPlanarenullwhen Booking.com prints nothing for them.- Member-only Genius discounts need a logged-in session and are not included.
- It does not collect reviews, photos, guest names or any personal data.
FAQ
Can I monitor several hotels at once? Yes, one URL per line. Each hotel is handled in turn, from its own proxy address.
How far ahead can it price? Up to 365 check-in dates per hotel per run. Many hotels open
bookings less than a year ahead: past that point Booking.com has no rooms to show, and those
dates come back as soldOut: true, the same as a sold-out night. Measured on a Lisbon hotel in
October 2026: bookable until 31 March 2027, then 187 dates in a row with no rooms. A seasonal
resort's closed weeks look the same way.
Do I need a Booking.com account or an API key? No.
What if a hotel URL is dead? A property that cannot be found by its URL is skipped and
named in the FAILED_HOTELS record. Nothing is charged for it.
Why is the price different from the hotel page I see in my browser? Almost always the tax
regime: see the section above and the pricesIncludeTaxes field. Occupancy is the other
reason; two adults and a family with children are priced differently.
Is it legal to scrape Booking.com? This is an unofficial tool, not affiliated with, endorsed by or connected to Booking.com or Booking Holdings Inc. It reads publicly visible prices and collects no personal data. Booking.com's terms of service restrict automated access, and you are responsible for making sure your use complies with those terms and with the law in your jurisdiction. See Apify's stance on web scraping legality.
Found a problem?
Open an issue on the Issues tab with the hotel URL and the run ID. Reports get read.