BOOKING PRICE SCRAPER - by room
Pricing
from $5.00 / 1,000 results
BOOKING PRICE SCRAPER - by room
Track Booking.com prices by room type, per night, up to 365 days. Get rooms_left, rate options, meal plans, discounts, and sold-out detection. Clean output for revenue management and competitive analysis. CSV, JSON, HTML, Excel. Built by NoraView Intelligence.
Pricing
from $5.00 / 1,000 results
Rating
5.0
(1)
Developer
NoraView Intelligence
Maintained by CommunityActor stats
7
Bookmarked
119
Total users
23
Monthly active users
6.7 days
Issues response
a day ago
Last modified
Categories
Share
๐จ Booking.com Room-Level Price Scraper
Extract complete room-level pricing from any Booking.com hotel โ every room type, every rate option, every date โ up to 365 days ahead.
Unlike listing scrapers that return one price per hotel, this actor dives into each property page and extracts granular room-by-room data: prices, rate options, availability signals, meal plans, discounts, facilities, and sold-out detection.
One run = complete pricing visibility for your competitive set.
๐ก Paste hotel URLs, set your date range, hit Start. Results ready in JSON, CSV, or Excel.
๐ฏ Who is this for?
- Revenue managers monitoring competitor pricing daily
- Hotel operators tracking market positioning at the room-type level
- Travel tech companies feeding structured pricing data into dashboards or algorithms
- Market analysts studying seasonal trends and demand patterns
- Consultants building competitive intelligence reports for hospitality clients
๐ฅ Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
hotelUrls | array | โ | โ | Booking.com hotel URLs (up to 10 per run) |
daysAhead | integer | โ | 30 | Number of days to scrape (1โ365) |
startDate | string | โ | Today | Start date in YYYY-MM-DD format |
currency | string | โ | USD | Any Booking.com currency: USD, EUR, GBP, MAD, AED, JPYโฆ |
adults | integer | โ | 2 | Number of adult guests |
children | integer | โ | 0 | Number of children |
rooms | integer | โ | 1 | Number of rooms |
includeSoldOut | boolean | โ | true | Include sold-out dates in results |
includeWholesaleRates | boolean | โ | false | Capture partner/wholesale rates (bbasic), tagged separately as is_wholesale |
proxyCountries | array | โ | ["FR"] | Source markets to scrape from. The actor runs once per country; each result is tagged with proxy_country. Requires useApifyProxy: true |
delayBetweenRequests | integer | โ | 4 | Seconds between page loads (anti-blocking) |
useApifyProxy | boolean | โ | false | Use Apify Proxy for better success rates |
Example input
{"hotelUrls": ["https://www.booking.com/hotel/ma/savoy-le-grand.html","https://www.booking.com/hotel/ma/longue-vie-hotels.html"],"daysAhead": 30,"currency": "USD","adults": 2,"rooms": 1,"includeSoldOut": true,"useApifyProxy": true,"proxyCountries": ["FR", "US", "GB"]}
๐ก Tip: You only need the base hotel URL โ query parameters like ?checkin=... are automatically handled. Works with any Booking.com property worldwide.
๐ก Multi-country tip: Booking.com applies geo-pricing based on visitor location. Scraping from multiple proxyCountries (e.g. ["FR", "US", "GB"]) reveals how the same room is priced for different source markets. Keep currency fixed across countries so the difference you see is the geo-pricing cohort, not a currency conversion.
๐ค Output
Each result represents one room type for one date. A hotel with 8 room types scraped across 30 days produces ~240 results โ a complete pricing matrix.
Output fields
| Field | Type | Description |
|---|---|---|
hotel_url | string | Source URL |
hotel_name | string | Property name as shown on Booking.com |
scrape_timestamp | string | When this data was collected (UTC) |
proxy_country | string | Source market the result was scraped from (e.g. FR, US) |
check_in_date | string | Check-in date (YYYY-MM-DD) |
check_out_date | string | Check-out date (YYYY-MM-DD) |
room_id | integer | Booking.com internal room type ID |
room_name | string | Full room name (e.g., "Prestige Double Room with Pool View") |
room_name_clean | string | Room name with bed type suffix removed |
bed_type | string | Bed configuration (e.g., "1 extra-large double bed") |
max_guests | integer | Maximum occupancy for this room |
room_size_sqm | integer | Room size in mยฒ (null if not shown) |
room_view | string | View type (e.g., "Pool view", "Seating Area") |
has_private_bathroom | boolean | Whether the room has a private bathroom |
facilities | array | Full list of room facilities (30โ40+ items per room) |
room_amenities | array | Premium amenities only (balcony, minibar, spa bath, etc.) |
currency | string | Price currency |
price | number | Lowest available price for this room |
price_primary | number | Best price for 2-guest standard occupancy |
price_public | number | Non-Genius public price (for competitive benchmarking) |
original_price | number | Pre-discount price (null if no discount) |
discount_percent | integer | Discount percentage (null if no discount) |
rooms_left | integer | Booking.com availability signal (null = high availability) |
availability_status | string | available, low_availability, low_availability_urgent, or sold_out |
stock_confidence | string | exact, capped, or hidden โ see explanation below |
meal_plan | string | Meal plan description |
is_breakfast_included | boolean | Whether breakfast is included at no extra cost |
is_refundable | boolean | Whether free cancellation is offered |
book_now_pay_later | boolean | Whether deferred payment is available |
taxes_included | number | Taxes included in the displayed price |
taxes_excluded | number | Taxes added on top of the displayed price |
has_wholesale_rate | boolean | Whether any rate option for this room is a wholesale/partner rate (only relevant when includeWholesaleRates: true) |
rate_options | array | All pricing tiers for this room (see below) |
rate_options_count | integer | Number of rate options available |
Rate options structure
Each entry in rate_options contains:
| Field | Type | Description |
|---|---|---|
price | number | Price for this specific rate |
public_price | number | Non-Genius price (original price if Genius discount applied) |
max_guests | integer | Guest count this rate is designed for |
is_refundable | boolean | Free cancellation available |
is_genius | boolean | Whether this is a Genius-discounted rate |
is_wholesale | boolean | Whether this is a partner/wholesale (bbasic) rate. Always false unless includeWholesaleRates: true |
original_price | number | Pre-discount price (null if none) |
free_cancellation_until | string | Last date for free cancellation (YYYY-MM-DD) |
taxes_and_fees | number | Taxes shown in DOM |
meal_plan | string | Meal plan for this rate |
block_id | string | Booking.com internal block ID |
taxes_included | number | Taxes from Booking's JSON data (included in price) |
taxes_excluded | number | Taxes from Booking's JSON data (excluded from price) |
stay_prices | object | Price per number of nights (LOS pricing data) |
book_now_pay_later | boolean | Deferred payment available |
๐ก Note: Rate options only include rates that match your search parameters (e.g., searching for 2 adults filters out 1-person-only rates). Partner/wholesale rates (bbasic) are excluded by default โ enable includeWholesaleRates to capture them, tagged separately as is_wholesale so they never mix with retail rates.
Example output
{"hotel_url": "https://www.booking.com/hotel/ma/savoy-le-grand.html","hotel_name": "Savoy Le Grand Hotel Marrakech","scrape_timestamp": "2026-03-17T22:20:20Z","proxy_country": "FR","check_in_date": "2026-03-17","check_out_date": "2026-03-18","room_id": 160633804,"room_name": "Prestige Double Room with Pool View","room_name_clean": "Prestige Double Room with Pool View","bed_type": "1 extra-large double bed","max_guests": 1,"room_size_sqm": 43,"room_view": "Pool view","has_private_bathroom": true,"facilities": ["Room", "463 feetยฒ", "Balcony", "Pool view", "Air conditioning","Ensuite bathroom", "Flat-screen TV", "Soundproofing", "Terrace","Coffee machine", "Minibar", "Free WiFi", "..."],"room_amenities": ["balcony", "air conditioning", "soundproofing", "terrace", "minibar"],"currency": "USD","price": 186,"price_primary": 186,"price_public": 186,"original_price": 207,"discount_percent": 10,"rooms_left": null,"availability_status": "available","stock_confidence": "hidden","meal_plan": "breakfast","is_breakfast_included": true,"is_refundable": false,"book_now_pay_later": true,"taxes_included": null,"taxes_excluded": null,"has_wholesale_rate": false,"rate_options": [{"price": 186,"public_price": 186,"max_guests": 1,"is_refundable": false,"is_genius": false,"is_wholesale": false,"original_price": 207,"meal_plan": "breakfast","block_id": "160633804_419828305_1_1_0","taxes_excluded": null,"book_now_pay_later": true}],"rate_options_count": 1}
๐ Understanding key fields
price vs. price_primary vs. price_public
| Field | What it is | When to use |
|---|---|---|
price | Absolute cheapest option (may be 1-person or restricted) | Quick market scan |
price_primary | Best price for standard 2-guest occupancy | Revenue management benchmarking |
price_public | Non-Genius public rate (strips Genius discounts) | Competitor comparison โ most travelers don't have Genius |
๐ก For competitive analysis, use price_public. Genius discounts (10โ20%) make prices look artificially low. price_public gives you the rate that most travelers actually see.
proxy_country
Booking.com prices the same room differently depending on the visitor's location (geo-pricing). The proxy_country field tells you which source market each result was scraped from. Running multiple proxyCountries in one job lets you compare cohorts side by side โ e.g. how a French visitor, a US visitor, and a UK visitor each see the same property.
๐ก For clean cohort comparison, keep currency fixed across all countries. Otherwise you mix two variables: the geo-pricing cohort and the currency conversion.
availability_status
| Status | Meaning | Revenue insight |
|---|---|---|
available | Rooms widely available | Normal market conditions |
low_availability | Inventory signal from internal data | Demand is building |
low_availability_urgent | Booking.com shows a visible scarcity alert | High demand โ act on pricing |
sold_out | No rooms available for this date | Peak demand โ opportunity to optimize your rates |
stock_confidence
| Value | Source | Reliability |
|---|---|---|
exact | DOM scarcity badge visible on page | High โ Booking.com shows this to create urgency |
capped | rooms_left = 10 from internal JSON | Medium โ actual stock is โฅ 10 |
hidden | rooms_left = null โ no signal from either source | Low โ Booking.com not revealing stock level |
rooms_left
Booking.com reveals availability through two channels, both captured by this scraper:
| Source | How it works |
|---|---|
Internal JSON (b_nr_stays) | Booking's internal stock data embedded in page scripts. Always captured when available. |
| DOM scarcity badges | Visible alerts like "Only 3 left!" shown to shoppers. Triggers stock_confidence: "exact". |
| Value | Meaning |
|---|---|
1โ9 | Real scarcity signal |
10 | Booking.com display cap โ actual inventory is โฅ 10 |
null | No signal from either source โ high availability |
facilities vs. room_amenities
| Field | What it contains | Example |
|---|---|---|
facilities | Complete list โ every feature Booking.com shows for the room (30โ40+ items) | "463 feetยฒ", "Pool view", "Air conditioning", "Toilet paper", ... |
room_amenities | Premium features only โ the differentiators that affect pricing | "balcony", "minibar", "soundproofing", "spa bath" |
Use facilities for full room comparison. Use room_amenities for quick tier classification.
๐ก Tips for best results
- Start with 7โ30 days to validate your setup, then scale to 365
- Schedule daily runs with Apify Scheduler โ hotel prices change constantly
- Use Apify Proxy (
useApifyProxy: true) for better success rates on large runs - Monitor up to 10 hotels per run for optimal speed and reliability
- Track sold-out patterns over time to map demand cycles in your market
- Compare
rate_optionsto analyze refundable vs. non-refundable pricing strategies - Use
price_public(notprice) when comparing against your own rates โ strips Genius discounts - Use
facilitiesto match comparable room types across different hotels - Compare
proxyCountriesto see geo-pricing differences across your source markets โ keepcurrencyfixed for a clean comparison
๐ Integrations
| Integration | Use case |
|---|---|
| Apify Scheduler | Automate daily/weekly price monitoring |
| Webhooks | Get notified when a run completes |
| API | Pull data programmatically (see API tab) |
| Google Sheets | Direct export for quick analysis |
| n8n / Make / Zapier | No-code automation pipelines |
| JSON / CSV / Excel | Download in any format |
๐ Use cases
Daily competitor monitoring โ Track what your competitive set charges across every room type, every day. See exactly how competitors price their rooms, when they discount, and when they sell out.
Revenue management โ Feed room-level market data into pricing decisions. Compare your rates against competitors using matching rate options (same occupancy, same cancellation policy, same meal plan). Use price_public for fair Genius-free comparison.
Geo-pricing analysis โ Scrape the same properties from multiple proxyCountries to see how Booking.com prices rooms for visitors from different source markets โ useful when your guests come predominantly from specific countries.
Room-type matching โ Use facilities, room_size_sqm, and room_view to match comparable rooms across different hotels. A 43mยฒ Prestige room with pool view at Hotel A maps to a similar tier at Hotel B.
Seasonal trend analysis โ Scrape 365 days to visualize demand curves, identify shoulder seasons, and plan promotions around events and holidays.
Portfolio benchmarking โ Manage multiple properties? Compare each one against its local market at the room-type level.
Travel platform data feeds โ Power booking engines, metasearch tools, or dashboards with structured, validated pricing data.
โ FAQ
Does this work with any Booking.com property? Yes โ any hotel, resort, riad, apartment, or boutique property listed on Booking.com, in any country. Works with small riads (5 rooms) and large hotels (100+ rooms).
What currencies are supported? All currencies available on Booking.com: USD, EUR, GBP, MAD, AED, SAR, JPY, and 30+ more.
What does rooms_left: null mean?
Booking.com is not displaying a scarcity alert for this room โ it has comfortable availability. When inventory drops, Booking.com shows alerts like "Only 3 left!" and rooms_left captures that exact count.
What does rooms_left: 10 mean?
This is Booking.com's display cap. The actual inventory is 10 or more โ Booking.com doesn't show exact counts above this threshold.
Why are sold-out dates valuable? Sold-out dates reveal peak demand periods. If a competitor is fully booked, that's a high-demand window where you can optimize your own rates.
What's the difference between price, price_primary, and price_public?
price is the absolute cheapest rate. price_primary is the best rate matching standard 2-guest occupancy. price_public strips Genius discounts to show the rate most travelers actually see โ use this for competitive benchmarking.
What are Genius rates and why does price_public matter?
Booking.com Genius gives 10โ20% discounts to frequent bookers. price_public always shows the non-Genius price, giving you the rate that the majority of travelers see. This is critical for fair competitor comparison.
What are bbasic rates and can I include them?
Booking.com sometimes shows "Tarif Prestataire" (partner/wholesale rates) from third-party resellers. By default the scraper skips them, since they aren't representative of the hotel's own retail pricing. If you need them โ common in some Asian markets โ set includeWholesaleRates: true and they'll be captured and tagged with is_wholesale: true, kept separate from retail rates so the two never mix.
How does proxyCountries work?
The actor runs once per country in the list, routing through a residential proxy for that market, and tags every result with proxy_country. This reveals Booking.com's geo-pricing โ how the same room is priced for visitors from different countries. Requires useApifyProxy: true. Keep currency fixed across countries for a clean comparison.
How does the scraper handle large hotels with many room types? Hotels with 9+ room types use a different DOM structure. The scraper handles this automatically by grouping rate rows by room ID and matching them to room type cells.
How often should I run this? For active revenue management, daily runs are recommended. Prices and availability on Booking.com change frequently โ sometimes multiple times per day.
Can I scrape more than 10 hotels? For optimal reliability, each run handles up to 10 hotels. For larger sets, schedule multiple runs or use the Apify API to batch them.
๐ Changelog
v2.2.0 โ June 2026
- โ
Multi-country proxy โ
proxyCountriesfield scrapes from multiple source markets in one run; each result tagged withproxy_countryfor geo-pricing comparison - โ
Wholesale rates โ
includeWholesaleRatesflag captures partner/bbasicrates, tagged separately asis_wholesale(andhas_wholesale_rateat the room level), kept separate from retail - โ Resilient registry load โ room-registry navigation now retries with IP rotation, so a single dead proxy IP no longer blocks sold-out detection for the whole hotel
v2.1.1 โ March 2026
- โ
Fixed multi-room extraction โ removed name-based deduplication that caused rooms to be silently skipped;
roomIdis now the single source of truth for deduplication - โ
Robust fallback names โ rooms with missing DOM names now use
Room_{id}instead of colliding on"Unknown Room" - โ Cleaner bbasic handling โ partner rate rows correctly skipped at both cell and row level across all hotel sizes
- โ
stay_prices(LOS data) โ length-of-stay pricing matrix extracted from Booking's internal JSON (b_stay_prices) - โ
taxes_included/taxes_excludedโ tax breakdown extracted fromb_included_charges/b_excluded_charges - โ
book_now_pay_laterโ deferred payment flag extracted fromb_book_now_pay_later - โ
stock_confidenceโ distinguishesexact(DOM badge),capped(JSON โฅ 10), andhidden(no signal)
v2.1.0 โ March 2026
- โ Cell-based extraction โ handles hotels with 9+ room types in a single table
- โ Full facilities list โ 30โ40+ items per room (size, view, bathroom, amenities)
- โ
price_publicโ non-Genius public rate for fair competitor comparison - โ
room_size_sqmโ extracted from real room cell (not partner rate cell) - โ
room_viewโ extracted from facilities and room name - โ
has_private_bathroomโ boolean from room facilities - โ
room_amenitiesโ premium features for tier classification - โ
Genius detection โ
is_geniusflag per rate option withpublic_priceextraction
v2.0.3 โ March 2026
- โ Clean output schema โ reduced from 35+ fields to 22 focused fields
- โ
Accurate
max_guestsโ uses Booking.com'sdata-fltrsattribute - โ
fitfiltering โ rate options only include rates matching your search parameters - โ
Fixed
rooms_leftextraction โ expanded JSON parsing window - โ
Fixed
is_breakfast_includedโ correctly detects all Booking.com breakfast formats - โ
price_primaryโ new field for revenue management benchmarking
v2.0.0 โ February 2026
- โจ Room-by-room extraction with multiple rate options per room
- โจ
rooms_left+availability_statusavailability tracking - โจ Discount detection with original price and percentage
- โจ Meal plan and cancellation policy extraction
- โจ Sold-out detection across date ranges
v1.0.0 โ February 2026
- Initial release
๐ฌ Support & feature requests
Have a question, found a bug, or want a new feature? โ Open an issue on the Issues tab.
Want a custom solution for your revenue management needs? โ Reach out via Issues.
Built by NoraView Intelligence โ AI-powered revenue management for independent hotels.
Track Booking.com prices by room type, per night, up to 365 days ahead. Get rooms_left, rate options, meal plans, discounts, refundable pricing, sold-out detection, full facilities, room size, view, Genius rate detection, wholesale/partner rates, and multi-country geo-pricing. Clean structured output for revenue management and competitive analysis. CSV, JSON, HTML, Excel.