Booking.com Hotel Scraper – Prices, Room Rates & Reviews avatar

Booking.com Hotel Scraper – Prices, Room Rates & Reviews

Pricing

from $2.54 / 1,000 search results

Go to Apify Store
Booking.com Hotel Scraper – Prices, Room Rates & Reviews

Booking.com Hotel Scraper – Prices, Room Rates & Reviews

Scrape Booking.com hotel prices, room rates and availability via the mobile API. Full per-room rate table with itemised taxes and fees, family pricing by child age, guest reviews and property details — one actor, not four. Search by destination, GPS radius or hotel id. No API key needed.

Pricing

from $2.54 / 1,000 search results

Rating

0.0

(0)

Developer

R.L.

R.L.

Maintained by Community

Actor stats

1

Bookmarked

486

Total users

213

Monthly active users

3.1 days

Issues response

7 days ago

Last modified

Categories

Features

Limited permissions

Share

Booking.com API Scraper – Hotel Prices, Rooms, Reviews & Availability

Scrape Booking.com at scale — hotels, live room prices, availability, full rate breakdowns, facilities, photos and guest reviews as clean, structured JSON. No login, no captchas, no browser automation. Give it a destination and dates and export to CSV, Excel, JSON or the API.

Whether you track competitor prices, build a travel app, feed a rate-shopping dashboard or do market research, this Booking.com data extractor turns the world's largest accommodation site into a structured feed.

Fast and reliable — calls Booking.com's own mobile app API (mobile-apps.booking.com) instead of rendering pages, so it needs no browser automation or login and is far faster and more stable than page-rendering scrapers. No partner contract needed — it does not call the partner-gated Demand API and needs no affiliate ID, API key or approval.

What you can extract

  • Hotel search results – every property for a city, region, free-text destination or GPS radius, with live total price, currency and booking links.
  • Live prices and itemised taxes – per-stay pricing with every tax and fee broken out (city tax, VAT, service charge, tourism fee, cleaning fee…), in your currency.
  • Family stays priced by child age – pass the ages and get the rates Booking would actually sell your party, family rooms surfacing and non-fitting rooms flagged.
  • Rooms and availability – every room type and bookable rate: occupancy, structured bed layout, bedrooms and bathrooms, size, board, cancellation policy, payment options, and how many rooms are left at each price.
  • Availability status – for a fixed list of hotels you always get a record, saying why there is no price: sold out, minimum stay not met (with the nights required), closed, or unknown id.
  • Guest reviews – paginated, with score, title, positive/negative text, date and reviewer country.
  • Property details – name, star rating, review score and count, coordinates, address, 100+ named facilities, family amenities, languages, house rules, photos.

Example use cases

  • Hotel price monitoring & rate shopping – track competitor and market prices over time for revenue management.
  • Family & group travel products – price parties with children correctly, and show only rooms that fit.
  • Travel & metasearch products – power a booking site, app or comparison tool with fresh inventory.
  • Market & investment research – analyze pricing, occupancy signals, ratings and amenities across a destination.
  • Review & reputation analysis – mine guest sentiment and review trends.
  • Lead lists & data enrichment – build accommodation datasets with geo and facilities context.

Why this scraper, not a flat-listing one

Most Booking.com scrapers return one row per hotel with a single total price. Enough to see who is cheapest today; not enough for revenue management, a family stay, or explaining a number to a client. This actor returns the layer underneath:

  • It tells you why a hotel has no price. Query a fixed list of ids and you always get a record back — sold out, minimum stay not met (with the nights required), closed, or unknown id — instead of the property vanishing.
  • It searches by GPS radius or bounding box, not just destination name.
  • It is one actor, not four. Search, details, rooms and reviews come from the same run, so you do not chain a listing scraper into a reviews scraper into a photos scraper.
  • There is no per-run start fee. That matters more than it looks on a schedule: a start fee is charged whether a run returns 2 rows or 2,000, so it falls hardest on exactly the small, frequent runs price monitoring is made of. Most alternatives charge one.

How to use it

No coding required. Set your search up in the visual input form, then run it on demand, schedule it, or call the API and connect Make, Zapier, n8n, Google Sheets and more. Results land in a dataset you can download as JSON, CSV, Excel or HTML.

Family stays with children

Child ages are required for correct family prices. Booking prices a stay by each child's age — free cots, kids-stay-free rules, extra beds — so 2 adults with children aged 2 and 9 pays differently from the same party aged 12 and 15, and differently again from 4 adults.

{ "adults": 2, "rooms": 1, "childrenAges": [5, 9] }

The ages go out on every request, rooms that cannot host the party are marked fitsParty: false, and each product echoes occupancy.requestedChildrenAges so you can confirm they reached Booking. The alternative spellings, the per-room allocation form and what happens when you omit the ages are in the input reference.

Ready-made examples (one click, no setup)

Nine published tasks sit on this Actor's Examples tab: rate-shopping a fixed compset room by room, city-wide price monitoring, sell-out tracking for compression dates, full rate tables with taxes, reviews with per-category subscores, cheapest well-rated properties, family pricing by child age, self-catering supply with bedroom counts, and a landmark radius search. Open one, press run, and it works with the input already filled in; running it copies it into your account, so you can change anything afterwards without touching the original. None pins a date — check-in defaults to 30 days ahead, so they return live availability rather than going stale.

Dates, absolute or relative. Every date input — checkin, checkout, attractionsStartDate, attractionsEndDate — takes either a chosen day (2026-12-10) or a relative value (30 days, 2 weeks, 1 month). Prefer the relative form in anything saved or scheduled: a fixed date is correct the day you set it and then drifts into the past, and Booking only quotes future stays, so a schedule built on one eventually rejects its own input. Both are resolved to a real date before any request goes out, and every row carries that date, not the words.

Recipes

Eight worked runs — family stays with child ages, price monitoring over a fixed list, cheapest well-rated hotels in a city, apartments only, reviews for competitive analysis, radius search around coordinates, full enrichment, and telling sold-out from minimum-stay — each with the exact input that produces it, are on recipes.

Input reference

Every input, with its type and default, is on the Input tab — it is generated from the schema, so it describes the deployed build. What a field description cannot carry is on the input reference: how the ten modes differ, which toggles add a charge event, where a run's limits come from, and what Deep search actually does.

The first decision is the mode, and it is also the one that sets the bill:

modewhat it doesbills
searchfind properties and their pricessearch-result
roomsroom options for ids you haveroom-details
ratesre-check named product idsrate-check or room-details
reviewsguest reviewsreview + review-scores
reviewScoresscore summary onlyreview-scores
surroundingsnearby placessurroundings
detailsstatic property contenthotel-details
attractionstickets, tours, activitiesattraction-row
attractionDetailsone attraction in fullattraction-detail
attractionAvailabilityan attraction's datesattraction-availability

On search and rooms, each include* toggle adds its own event — that is where a run's cost actually comes from. Charging happens on delivery, not on request: a surface that fails or returns nothing is free. Units, the toggles and the two events that are not priced yet are in what each mode bills; the figures are on the Pricing tab, which is generated and plan-tiered.

Upgrading: what changed for existing runs

Search-mode runs are unchanged. A saved task sending search, dates, guests and the include* toggles produces the same records, fields and charges as before — verified by diffing old and new builds on the same input, property by property.

Breaking changes, all of them. Each one removes or refuses something that was wrong rather than merely unhelpful, and each is loud instead of silent:

whatwhy
attractions: latitude / longitude renamed to cityLatitude / cityLongitudethey are the destination centroid, not the product: 21 products in three cities gave three pairs, one per city. A product's own are on an attractionDetails row
attractions: cancellationLabel removednull on 143 of 143 products; freeCancellation, stillRefundable and cancellationUntil fill every time
scrapedAt / scrapedAtUnix added (not a breaking change)ISO-8601 UTC to milliseconds, and epoch seconds, on every row: when that row's price was fetched, not when it was pushed. Booking's own date strings are not ISO — do not share a parser. RUN_SUMMARY.window bounds the run
extra_charges.conditional[] and conditionalTotal removedempty everywhere: 0 of 4,934 room-list lines, 0 of 405 search lines. A line's own inclusion still reads conditional, and such a line now groups with excluded, never unknown. depositTotal stays — a refundable deposit there would overstate the bill
bookerCountry removedread by nothing since the day it was added — never in src/, never on a request. The point of sale follows the proxy exit country, now reported per row as provenance.exitCountry

Older waves — the 1.0.94–1.0.141 changes, the two no-op flags that now work and are billed, the rejected-instead-of-defaulted location, and the retired country — are in the upgrade guide, with the reasoning for each.

Renames are aliased, not breaking: city and region still work beside cityId and regionId, searchMode defaults to auto, and an empty outputFields gives the full record.

Output reference

Every column, with its type and what it means, is on the Output tab — 120 of them, generated from the dataset schema, so it describes what the deployed build returns. The same tables by row kind, each with a real row and the nested objects member by member, are on keyspace.dev:

row kindmodescolumnsreference
Accommodationssearch, rooms, details, surroundings35property-rows
Reviews & scoresreviews, reviewScores12reviews
Watched ratesrates27rates
Attractionsattractions30attractions
Attraction detailsattractionDetails56attraction-details
Attraction availabilityattractionAvailability19attraction-availability

Numeric ids — accommodation type, room type, bed type, charge type, payment card — are tabled in the integer ID reference. Annotated screenshots joining each number on screen to the field behind it are on the screenshots page.

What is inside the amount the guest pays, what Booking adds on top, and what sits outside it entirely, is drawn in the price stack. Read that before reconciling a total against anything.

The five columns read wrong most often

Everything else is in the references above; these five cost money to get wrong.

  • Compare against price.total_with_charges, not price.total. total is the display price: right on a room-list rate, low wherever Booking excludes tax from it. One column is correct on both paths.
  • starRating does not say whether the stars are official. Booking awards some and lets others self-estimate; the surface returns symbol: "STARS" for both, so ranking by it mixes them.
  • amountDueNow is null, not 0, when a rate states no payment stage. Treating null as zero turns every such rate into a false "pays nothing now".
  • A meal price is in the property's own currency, not the row's. Read breakfastPrice with breakfastCurrency: a Cape Town property quotes 120 ZAR on a run priced in EUR.
  • Do not rebuild url — read it. Booking's slugs are not derivable from the name, and unavailable ones come back null rather than guessed.

Known limitations

What this surface cannot give you — each entry with the measurement that says so, and tagged by who could fix it — is on known limitations. The one worth knowing before you start: roomList returns the room types bookable for your dates, not the property's catalogue, and the shortfall is not detectable from the payload. So "this property has N room types" is not a claim this data supports.

Attractions: tickets, tours and activities

Booking sells more than places to stay. Three modes read its bookable-product catalogue — museum admissions, guided tours, day trips, transfers. A different vertical from the six property modes, sharing nothing with them but the location primitive: no stay window, no guests, no room blocks.

modegives you
attractionsthe catalogue for a place, with price, rating, duration and cancellation terms
attractionDetailsone product in full — the long description, what is included, where it starts
attractionAvailabilitywhich dates are bookable, and optionally the timeslots

How to point them at a destination, what each input does and how to read the availability status are in the input reference; the columns are on attractions, attraction details and attraction availability.

Frequently asked questions

Can I get Booking Genius / loyalty-tier prices?

No — and that is a proven absence, not a gap in this Actor. Genius prices need a member login, which this Actor deliberately never does. The evidence — genius_discount_percentage present and exactly 0 on 1,385 of 1,385 blocks, 0 of 180 search rows badged, and no request parameter that sets a level — is on known limitations, which collects everything this surface cannot give.

Is there a Booking.com API, and do I need partner approval to use it? Booking.com's official Demand API is partner-gated — contract and affiliate ID. This actor needs neither: it reads the public mobile app API (mobile-apps.booking.com) and returns structured JSON, so you can get hotel prices without an API key.

How do I scrape Booking.com hotel prices? Give it a destination and dates and it returns every property that can host the stay, with live total price, currency and booking link. Add includeRooms for the per-room rate table and includeExtraCharges for itemised taxes and fees.

How do I get room rates and availability for a specific hotel? Pass its numeric id in hotel_ids with your dates and set includeRooms. You get every bookable rate — occupancy, bed layout, board, cancellation policy, rooms left — and, where there is no price, an availability status saying why.

Can I search hotels near a set of coordinates? Yes. Set latitude, longitude and radius to search by GPS radius, or neLat/neLon/swLat/swLon for a bounding box — "hotels within 2 km of this venue" rather than "hotels in this city".

Which Booking.com scraper should I use for rate shopping or revenue management? One returning rates per room rather than one price per hotel, because a blended nightly total cannot be compared across boards, cancellation policies or occupancy. This actor returns the full per-room rate table with taxes itemised. See why this scraper.

Do I need a Booking.com account or API key? No. Just configure the input and run it.

Does it price children correctly? Yes — pass the ages in childrenAges (or guests.children) and every request carries them; see Children / family stays. Without ages Booking prices the party as adults only.

Can I get prices in my own currency and language? Yes — set currency and language.

How many reviews can I collect? Reviews are paginated, so you can pull well beyond the first page — set maxReviews per property.

Can I scrape a specific hotel? Yes — pass its numeric Booking id (not the URL slug or name) in hotel_ids. To find it, open the hotel's Booking.com page, View source, and search for hotelId. An unknown id yields availability.status: "not_found" rather than silently vanishing.

Can I just put a hotel's name in search instead of finding its id? Often, yes — the actor tries to resolve a full hotel name to the right property, with checks against confidently returning the wrong one. But matching is not guaranteed, and ambiguous names may fail with "Could not resolve destination". The numeric id in hotel_ids is the reliable way to target one hotel.

Why is a hotel missing from my search results? Booking's search only returns properties that can host the stay. To learn why one is missing (sold out, minimum stay, closed), query it through hotel_ids and read availability.

Does it return phone numbers or email addresses? No. Booking.com hides property contact details until after a booking, so they are not in public data.

What formats can I export? Results land in a dataset, downloadable as JSON, CSV, Excel or HTML, or available through the API and integrations.

Is this an official Booking.com product? Does it use the Demand API? No to both — it is an independent scraper reading the public mobile app API, and needs no partner approval.

This is one entry in a longer inventory: known limitations collects everything this surface cannot give, each with the measurement behind it and tagged by whether it is Booking's limit, ours, or a line we chose not to cross.

Did you find this useful?

Rate this actor on Apify! Your feedback helps other users find it and helps us keep improving it.

⌂ 换网址