Booking.com Room Offers & Cancellation Policies
Under maintenancePricing
$0.50 / 1,000 row saveds
Booking.com Room Offers & Cancellation Policies
Under maintenanceGet every property's cheapest bookable offer for your exact dates and party: stay price, price per night, taxes, board, room setup — plus the cancellation terms. Free-cancellation deadline, hours of flexibility before check-in, refundable true/false, and market-wide refundability shares.
Pricing
$0.50 / 1,000 row saveds
Rating
0.0
(0)
Developer
Hamza
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
What a property will actually charge for your dates — and whether you can cancel it for free. Name the places you care about, set the stay and the party, and this actor returns one row per property: its cheapest bookable offer for exactly that stay, the price for the whole stay and per night, the taxes and charges that sit on top, the board included, the room's bed and bathroom count, and the cancellation terms — the free-cancellation deadline as a real timestamp, how many hours before check-in that deadline falls, and a plain true/false for whether the offer is refundable at all. Built for revenue managers watching a comp set's live rates, travel brands and booking sites tracking price and policy competitiveness, and analysts who need a dated, comparable snapshot of what a market is charging.
It is a cheapest-offer scanner, not a room-inventory dump. Booking.com shows one to two offers per property for any given stay, so that is what you get — read Limits below before you buy.
What you can do with it
- Watch a comp set's live rates for one specific stay. Every row is stamped with the check-in, check-out, nights, lead time and party it was priced for, so two runs are directly comparable and nothing has to be reconstructed later.
- Measure how flexible a market really is. Turn on the market summary and each destination gets a row with the share of properties offering free cancellation and the share needing no prepayment — for a live Austin weekend that was 587 of 646 properties refundable and 188 with no prepayment.
- Pull only the flexible inventory. Switch on "Free cancellation only" and effectively every row comes back with a real cancellation deadline, which is the fastest way to build a shortlist a corporate travel policy will accept.
- Compare the true cost, not the headline price. Where Booking.com publishes charges that sit outside the quoted price, you get them as their own column plus a tax-inclusive total, so a cheap headline that turns expensive at checkout is visible immediately.
- Build a price and policy series over time. Run it on a schedule against the same destinations, dates and currency and you have a dated history of what a market charged and how refundable it was, per property.
- Screen a whole market down to a shortlist. Filter by star rating, guest review band, board basis, no-prepayment, genuine discount depth, or any of Booking.com's own facets, and only the rows that survive are saved — so you are never billed for rows you would have thrown away.
What you get
Two kinds of row land in the same dataset, told apart by recordType.
An offer row — one per property, cheapest matching offer first:
{"recordType": "offer","hotelId": 1344239,"hotelName": "Austin Motor Inn","hotelUrl": "https://www.booking.com/hotel/us/austin-motor-inn.en-us.html","latitude": 30.30662,"longitude": -97.73915,"address": "5000 North Interregional Highway","city": "Austin","countryCode": "us","starRating": 2,"reviewScore": 6.4,"reviewsCount": 412,"accommodationTypeId": 205,"offerRank": 1,"roomId": "134423917","occupancy": 2,"mealPlanId": 0,"mealPlanType": null,"mealPlanText": null,"finalPrice": 87.98,"currency": "USD","originalPrice": 87.98,"discountAmount": null,"discountPercent": null,"pricePerNight": 43.99,"taxesAndCharges": 13.2,"totalWithTaxes": 101.18,"chargesNote": "+$13 taxes and charges","freeCancellationUntil": "2026-09-09T05:00:00Z","isRefundable": true,"hoursOfFreeCancellationBeforeCheckin": 19,"scarcityMessage": null,"scarcityTag": null,"roomName": "Double Room","bedrooms": 1,"beds": 1,"bathrooms": 1,"kitchens": 0,"livingRooms": 0,"variant": "base","checkIn": "2026-09-10","checkOut": "2026-09-12","nights": 2,"leadTimeDays": 42,"adults": 2,"rooms": 1,"children": 0,"destination": "Austin","destinationType": "CITY","scrapedAt": "2026-07-30T09:14:02.181Z","actorRunId": "y7Kq2mVbN4tRp8sD"}
And, while the market summary is left on, one row per destination:
{"recordType": "marketRefundability","destination": "Austin","destinationType": "CITY","checkIn": "2026-09-10","checkOut": "2026-09-12","nights": 2,"totalProperties": 646,"freeCancellationCount": 587,"freeCancellationSharePct": 90.87,"noPrepaymentCount": 188,"noPrepaymentSharePct": 29.1,"availableOnlyCount": 646,"currency": "USD","scrapedAt": "2026-07-30T09:14:02.181Z","actorRunId": "y7Kq2mVbN4tRp8sD"}
Input reference
Where to look
Offers only exist inside a market's live results, so start from a place rather than from a single property.
| Field | Type | Default | Description |
|---|---|---|---|
destinations | array of strings | ["Austin"] (max 100) | Where to look for offers, one entry per line: a city (Austin), a region or country (Tuscany, Portugal), a district, a landmark, an airport name, or a latitude,longitude pair such as 30.2672,-97.7431. An entry Booking.com cannot resolve is named in the log and fails only itself. |
destinationType | select | CITY | What kind of place the entries are: city, region or state, country, district or neighbourhood, airport, landmark, or coordinates. A latitude,longitude pair is always treated as coordinates whatever you pick. |
Stay and guests
Every price and every cancellation deadline belongs to one specific stay, so these settings change the whole output.
| Field | Type | Default | Description |
|---|---|---|---|
checkIn | date | (empty) | First night of the stay, as YYYY-MM-DD. Leave both dates blank and you get a rolling two-night stay 30 days from the run date, which keeps a scheduled run useful without anyone editing it. Booking.com shows no availability for dates in the past. |
checkOut | date | (empty) | Departure day, as YYYY-MM-DD. Must be at least one night after check-in; if it is not, two nights are used and the log says so. |
adults | integer | 2 (max 30) | Adults per room. Offers are priced for exactly the party you ask for, so changing this changes every price. |
rooms | integer | 1 (max 30) | How many rooms the party needs. |
children | integer | 0 (max 10) | Children in the party. Add their ages below — Booking.com prices children by age, and without ages the offers may not be the ones you would be quoted. |
childrenAges | array of strings | [] (max 10) | One age (0–17) per child, one per line. Filling this in also sets the number of children. |
Offer filters
Applied while the market is read, so the rows you are billed for are the rows you wanted.
| Field | Type | Default | Description |
|---|---|---|---|
refundableOnly | boolean | false | Keep only offers that can be cancelled free of charge up to a deadline. Turning this on lifts the share of rows carrying a cancellation deadline to effectively all of them. |
noPrepaymentOnly | boolean | false | Keep only offers you do not have to pay for up front. |
mealPlanFilter | select | any | Board basis: any, breakfast included, breakfast and dinner included, or kitchen facilities. The choice is matched against the labels the destination itself publishes; when a destination does not publish that option, the log says so and offers come back without the board filter rather than empty. |
minStars | integer | 0 (max 5) | Keep only properties with at least this official star rating. 0 keeps everything, including properties with no star rating at all. |
minReviewScore | select | any | Keep only properties whose guest review score is at least this good: any, 6+, 7+, 8+ or 9+. The bands are the ones Booking.com itself publishes for that destination. |
extraFilters | array of strings | [] (max 12) | Advanced. Any additional Booking.com filter ids, one per line, in the form group=value — for example hotelfacility=107 for a pool or ht_id=204 for hotels only. Malformed entries are dropped and named in the log. |
minDiscountPercent | integer | 0 (max 100) | Keep only offers whose price is genuinely below the property's own pre-discount price by at least this much. Most offers carry no discount at all, so anything above 0 is a strict filter. |
Coverage and extras
| Field | Type | Default | Description |
|---|---|---|---|
offerVariants | array of strings | [] (max 6) | The one honest way to see more than a property's single cheapest offer. Each entry is a Booking.com filter id — for example fc=2 for free cancellation or mealplan=1 for breakfast included — and the destination is read again under that one constraint, returning each property's best offer within that constraint. Rows are merged and identical offers removed, and every row records which variant produced it. Each entry roughly doubles the work of the run. An entry that repeats a filter you already switched on above would return the very same market a second time, so it is dropped and named in the log rather than saving — and charging you for — every offer twice. |
sortBy | select | price | Cheapest first, or Booking.com's own ranking. Cheapest first keeps a market comparable between runs and surfaces materially more refundable inventory; Booking.com's own ranking mixes in far more non-refundable offers. |
maxPropertiesPerDestination | integer | 500 (max 1000) | How many properties to read per destination, per variant. Booking.com itself stops showing more than about 1,000 properties for any single search, so that is the ceiling. |
emitMarketRefundabilityRow | boolean | true | Saves one extra row per destination with the share of properties offering free cancellation, the share needing no prepayment, and how many properties the destination held in total. |
Run settings
Sensible defaults — most runs never need to touch these.
| Field | Type | Default | Description |
|---|---|---|---|
maxRequests | integer | 800 (max 8000) | A hard ceiling on how much reading one run may do. The projected size of the job is printed in the log before anything starts, and the run finishes cleanly with whatever it collected once the ceiling is reached. |
| Destinations at a time | integer | 4 (max 8) | How many destinations are worked through in parallel. Higher finishes a long list sooner; 4 is a good balance. |
currency | string | USD | Three-letter code every price is returned in, for example USD, EUR or GBP. Amounts are taken exactly as Booking.com quotes them and nothing is ever converted, so keep this the same between runs or a price series cannot be compared. |
language | string | en-us | Booking.com language code for property names and labels, for example en-us, en-gb, de or fr. |
proxyCountry | string | (empty) | Country to appear to browse from, as a two-letter code such as us, gb or de. Booking.com tailors availability and promotions by country, so this can change which offers appear. |
Output fields
Offer rows (recordType: "offer")
| Field | Type | Description |
|---|---|---|
hotelId | integer | Booking.com's numeric id for the property. The stable key to join on across runs. |
hotelName | string | Property name as Booking.com publishes it. |
hotelUrl | string | Link to the property page, assembled from the property's own details. A convenience field — it opens for the great majority of properties but is not the link Booking.com published. |
latitude / longitude | number | Position of the property. |
address | string | Street address, where published. |
city | string | City the property sits in — often more precise than the destination you asked for. |
countryCode | string | Two-letter country code, lower-cased. |
starRating | number | Official star rating. Empty for properties that have none. |
reviewScore | number | Guest review score out of 10. Empty when Booking.com withholds it, usually because there are too few reviews. |
reviewsCount | integer | How many guest reviews the property has. |
accommodationTypeId | integer | Booking.com's own code for the kind of accommodation (hotel, motel, apartment, guest house and so on). |
offerRank | integer | 1 for the property's cheapest matching offer, 2 for the runner-up when a second one is shown. |
roomId | string | Identifier of the room being offered, as text so it joins cleanly against other datasets. |
occupancy | integer | How many guests the offer is priced for. |
mealPlanId | integer | Booking.com's board code for the offer; 0 means no board included. |
mealPlanType | string | Board type as Booking.com labels it, when it labels one. |
mealPlanText | string | Human-readable board description, for example "Breakfast included". |
finalPrice | number | What the offer costs for the whole stay, in currency. This is the number to compare. |
currency | string | Currency every amount on the row is quoted in. Never converted. |
originalPrice | number | The pre-discount price for the same stay. Equal to finalPrice whenever there is no discount, which is the common case. |
discountAmount | number | How much is off, and only when the pre-discount price is genuinely higher. Empty otherwise — a 0% discount is never reported as a finding. |
discountPercent | number | The same discount as a percentage, on the same terms. |
pricePerNight | number | finalPrice divided by the nights in the stay, for comparing stays of different lengths. |
taxesAndCharges | number | Charges Booking.com publishes as sitting outside the quoted price. A non-zero value means finalPrice does not include them. Booking.com publishes one such figure per property and it belongs to that property's cheapest offer, so it is reported on that row only — never copied onto a runner-up whose price is different. |
totalWithTaxes | number | finalPrice plus those charges. Empty when no charge figure is published for that offer, rather than silently repeating the offer price as if it were tax-inclusive or borrowing another offer's tax. |
chargesNote | string | Booking.com's own wording about taxes and charges for this property. |
freeCancellationUntil | string | The moment free cancellation expires, as a full timestamp. Empty means the offer is non-refundable — it is not a missing value. |
isRefundable | boolean | true when the offer has a free-cancellation deadline, false when it has none. |
hoursOfFreeCancellationBeforeCheckin | number | How many hours before the start of the check-in day the free-cancellation deadline falls — the number that tells you how flexible an offer actually is. Typically 19–43 hours. |
scarcityMessage | string | Booking.com's "only X left" style urgency note, when it shows one. A rare bonus signal, empty on almost every offer. |
scarcityTag | string | The tag behind that message, when there is one. |
roomName | string | Name of the room or unit being offered. |
bedrooms / beds / bathrooms / kitchens / livingRooms | integer | Configuration of the unit matched to your party. |
variant | string | base for the main pass, or the extra-pass filter id this row came from. |
checkIn / checkOut | string | The stay this price and this deadline belong to. |
nights | integer | Length of the stay. |
leadTimeDays | integer | Days between the run date and check-in — the axis to plot a price curve against. |
adults / rooms / children | integer | The party the offer was priced for. |
destination | string | The destination entry that produced this row. |
destinationType | string | The kind of place that entry was treated as. |
scrapedAt | string | When this row was collected. |
actorRunId | string | The run that produced this row. |
Market summary rows (recordType: "marketRefundability")
| Field | Type | Description |
|---|---|---|
destination / destinationType | string | The market this summary describes. |
checkIn / checkOut / nights | string, integer | The stay it was measured for. |
totalProperties | integer | How many properties Booking.com reported for that market and stay. A live snapshot — see Limits. |
freeCancellationCount | integer | Properties in that market offering free cancellation. |
freeCancellationSharePct | number | The same figure as a share of totalProperties. |
noPrepaymentCount | integer | Properties needing no payment up front. |
noPrepaymentSharePct | number | The same figure as a share of totalProperties. |
availableOnlyCount | integer | Properties Booking.com counts as actually available for the stay. |
currency | string | Currency the run was pinned to. |
scrapedAt | string | When the summary was taken. |
actorRunId | string | The run that produced this row. |
Pricing
Pay per event — you are billed for what you keep, not for how long a run takes.
| What triggers a charge | Price |
|---|---|
| Any row saved to the dataset — an offer row or a market summary row | $0.0005 each, i.e. $0.50 per 1,000 rows |
That is the whole price list. Pricing here is deliberately single-tier: offer rows arrive dozens to hundreds at a time, so no row costs meaningfully more to produce than any other and a second charge would be a markup with nothing behind it. Rows a filter removes — the wrong board, too few stars, a discount below your floor — are never saved and therefore never billed, and neither are repeats of an offer you already have from an earlier variant.
Worked example: 5,000 offers is about $2.50. A single 500-property market with the summary row on is roughly $0.25; a 20-city sweep at 500 properties each, about $5.
Limits and what this actor cannot do
- This is the cheapest matching offer per property, not a full room list.
Booking.com's market results carry one to two offers for a property on your
dates, and nothing it publishes lists a property's whole inventory, so no actor
can honestly give you every room and rate for a hotel.
offerVariantsis the real workaround: each extra pass returns each property's best offer within one constraint you choose, which widens coverage without pretending to be complete. - Offers match the occupancy you asked for. Two adults and one room returns what two adults in one room would be quoted — not the property's cheapest room in the abstract. Change the party and every price changes.
- A blank free-cancellation date means non-refundable. That is the verified meaning, not a gap. Booking.com also publishes an unlabelled policy code alongside each offer, but its values have no published meaning, so this actor does not ship it dressed up as a policy name. Whether a free-cancellation deadline exists is the honest refundability signal, and it is the one you get.
- Which offers you see depends on the ordering. Cheapest first surfaces materially more refundable inventory than Booking.com's own ranking does. Both are truthful views of the same market; neither is the complete one.
- Booking.com shows at most about 1,000 properties per destination search. A market bigger than that cannot be enumerated in one destination entry — split it into districts, coordinates or neighbouring places to see further.
- Booking.com's own property total moves between identical searches. The same
Austin query returned 632, 646 and 647 within minutes, so
totalPropertiesand the market shares are a snapshot, not an audited figure. - A property with no availability for your dates is absent entirely. It has no offer to report, so there is no row. A named single hotel can therefore only be priced when it actually turns up in its market's results for your stay.
- Discounts are rare and are only reported when real. On live samples the
pre-discount price equalled the price being charged on every offer, so a
discount floor above
0is a genuinely strict filter that can empty a market. - Scarcity badges appear rarely. Treat them as a bonus signal, never as a guarantee that a room is about to sell out.
- Tax-inclusive totals depend on what Booking.com publishes. Where no charge figure is published, the tax-inclusive total is left empty rather than assuming the quoted price already includes tax.
- Prices are never converted. Every amount is quoted exactly as Booking.com gave it in the currency you pinned; a market that quotes in something else is reported as it came, not silently converted.
- Speed depends on the size of the job and on Booking.com's own response times. No fixed completion time is promised for any run size.
- Booking.com's terms prohibit automated access. You are responsible for using this data lawfully and in line with the source site's terms.
FAQ
Do I need a Booking.com account? No. None at all.
Does it need a login, a password or any personal details? No. There is nothing to sign in to and nothing to configure — pick your destinations and dates and run it.
Can I get every room and rate a hotel offers?
No, and no tool reading Booking.com's public pages honestly can. A market's
results carry one to two offers per property, so what you get is the cheapest
offer that matches your party, with its cancellation terms. If you need more
breadth per property, add entries to offerVariants: each one re-reads the
market under a single constraint — free cancellation, no prepayment, breakfast
included — and returns each property's best offer under it.
Can I price one specific hotel?
Only through its market. Search a hotel by itself and Booking.com returns the
right property with no rates attached at all, which is why this actor works from
places rather than from single properties. Run its city with a tight filter — its
star band, or a review-score floor — and pick it out of the results by
hotelId.
Can I schedule it?
Yes, and it is built for it. Leave both dates blank and every run scans a rolling
two-night stay 30 days out, so a daily schedule gives you a clean lead-time price
curve with no edits. Keep the currency, the party and the destinations fixed
between runs, then join on hotelId plus checkIn to see what moved.
Is the data complete? For the stay you asked about, within two honest bounds: a destination shows at most about 1,000 properties, and each property contributes its cheapest matching offer rather than its full room list. Everything inside those bounds is Booking.com's own live data for your exact dates, party and currency — nothing is estimated, interpolated or converted.
Why did a destination come back with no offers? Either nothing in it is bookable for those dates and that party, or your filters were strict enough to empty it — a board basis the market does not publish, a review-score band it does not offer, or a discount floor no offer meets. The log names which of those happened for every destination.