How to use it: 3 steps
- Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
- Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example:
searchin What to collect. Each start is one run. - Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.
This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.
What it does
Booking.com Scraper takes a city, a Booking.com search link or a hotel link and returns hotels with stay prices, room offers, guest reviews and price calendars for your dates, so you can compare a market or watch price changes without manual copying. Add one city and run 10 hotels with no login or API key: this costs about $0.03 on the Free plan.
Good for
- You need hotel prices for exact dates and guests, for one city or many.
- You compare your hotel with others nearby, or follow prices every day.
- You read guest reviews in a spreadsheet or give them to an AI agent.
- Genius, member, mobile-only and other personal prices. The Actor does not log in.
- Flights, car rental and attractions.
- Hotel contact details and leads.
- Booking a room. The Actor only reads data.
Who uses it
Hotel owners
Compare your rates with hotels near you.
Travel analysts
Follow hotel prices in a city for chosen dates.
Review researchers
Read guest reviews in a spreadsheet, without author names.
Price
Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.
| What you pay for | Price | When |
|---|---|---|
| Search page or hotel check | $0.0035 (from $0.00245 on paid Apify plans) | One destination search page or one specific hotel/date/currency/language check, including no matches and unchanged prices. Charged before source work; invalid input is not charged. |
| Hotel result | $0.00225 (from $0.001575 on paid Apify plans) | One saved hotel result with the details and room rates requested in input. |
| Anonymous review | $0.0018 (from $0.00126 on paid Apify plans) | One anonymous guest review saved to the dataset. |
| Calendar day | $0.00045 (from $0.000315 on paid Apify plans) | One saved hotel/check-in date with price and availability. |
| Review page | $0.001 (from $0.0007 on paid Apify plans) | A source page of up to 25 reviews after a destination search, or a page after the first one for a direct hotel link. Includes filtered and final empty pages. |
| Calendar page | $0.001 (from $0.0007 on paid Apify plans) | A source batch of up to 31 check-in dates after a destination search, or a batch after the first one for a direct hotel link. Includes unchanged dates. |
Examples
- One result: about $0.0022.
- 1,000 results: about $2.25.
- Every day 100 results, for 30 days: about $6.75 a month.
Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 2,200 results.
Prices checked on 8 November 2026. See the current price on Apify.
Questions
Do I need a Booking.com account or API key?
No. The Actor reads public pages. You only need an Apify account.
Why is the price different from my browser?
Your browser can show Genius or member prices, another currency or other guests. Compare in a private window with the same dates.
Can I get hotel emails or phone numbers?
No. The Actor does not return contact details. Review rows have no author name.
Do reviews include guest names?
No. Rows have the review text, score, date, traveler type and room type, without the author's name, photo or profile.
How fresh is the data?
Each row is read during your run. fetchedAt shows the time. Rows are not reused from earlier runs.
Details
Step by step on Apify
- Open the input form. Keep
Pattayaor type your city indestination(box 1 in the picture). - Keep
maxItemsat 10 (box 2 in the picture). This is the number of hotels to save. - Open Dates and guests (box 3 in the picture) and set
checkInandcheckOut. If you leave both empty, the Actor checks one night, seven days from today. - Press Start. A run with these settings usually takes about two minutes.
- Open the Hotels and prices tab and check
name,priceandrating(box 5 in the picture).
Use cases
| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Compare prices in a city for one stay | destination, checkIn, checkOut | Hotel row | name, price, rating, stars | CSV or Excel, Google Sheets |
| Check rooms and terms at hotels you follow | startUrls with hotel links, includeRooms | Hotel row with roomRates | roomRates, freeCancellation, excludedCharges | API, your database |
| Read what guests say | mode: reviews, startUrls, reviewAfter | Review row | reviewDate, rating, positiveText, negativeText | AI agent, spreadsheet |
| Find cheap dates for a hotel | mode: calendar, calendarDays | Calendar row | checkIn, price, availability | Spreadsheet, chart |
| Get told when prices move | mode: monitor, stateName, an Apify schedule | Changed hotel row | changeType, previousPrice, priceChange | Slack or Notion summary |
Tips for better results
- Keep maxItems at 10 for a first run. It sets how many hotels are saved.
- Use monitor mode to get only hotels whose price changed since the last run.
- Turn details off for a fast price list. Many hotels with details need a longer timeout.
Limits and good to know
- Time: with details and rooms on, one hotel takes about 5 to 6 seconds in our tests, so 100 hotels take 7 to 11 minutes. Without details, 850 hotels took under one minute. A run that reaches its timeout stops with
DEADLINEand keeps saved rows. The default timeout is 3600 seconds: for more than about 550 hotels with details, raise it in Run options or turn details off - One hotel: up to 40 seconds and 2.5 MiB of responses per hotel. Over that, or with broken data, the hotel is skipped without a
hotelcharge. A run stops on the third skip; every 20 saved rows allow one more, but three in a row always stop it - Tested sizes: 850 hotels from one search, 800 reviews from one hotel, 365 calendar dates.
maxItemshas no fixed upper limit, but a larger run depends on what Booking.com shows - Search window: Booking.com shows about 1,000 results per search. The Actor splits a larger search by price range and removes repeated hotels. If a range cannot be split further, the run stops with a clear error
- Calendar: one night gives rounded labels (
priceIsRounded: true). UsecalendarNightsabove 1 for exact stay totals, ordateRangeswithincludeRoomsfor full offers - Monitor: because visitor prices can differ, a single
priceUporpriceDownis a signal to check, not proof of a new rate. Confirm it with the next run before you act.soldOutneeds a direct check. A hotel missing from a search is not marked sold out. History keeps up to 30,000 records perstateNameand drops the oldest and sold-out records first - Reviews: author name, photo and profile are not returned. Review text is cleaned of the shown name and contact details on a best-effort basis, so read it before you publish it
For developers
Sample result
One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.
{
"recordType": "hotel",
"status": "ok",
"hotelId": 27653,
"name": "Bella Villa Cabana",
"url": "https://www.booking.com/hotel/th/best-western-bella-villa-cabana.html",
"stars": 4,
"rating": 7.8,
"ratingLabel": "Good",
"reviewsCount": 1054,
"price": 62.18,
"pricePerNight": 62.18,
"priceBeforeDiscount": 100.29,
"excludedCharges": 3.93,
"priceWithCharges": 66.11,
"currency": "USD",
"availability": "available",
"address": "55/7 M.1Sukhumvit Rd. Naklua Banglamung, 20150 Naklua , Thailand",
"city": "Naklua",
"countryCode": "th",
"lat": 12.9901208145351,
"lng": 100.922231376171,
"distanceFromCenterMeters": null,
"propertyType": "HOTEL",
"checkInTime": "14:00",
"checkOutTime": "11:00",
"breakfast": "Breakfast included",
"freeCancellation": false,
"roomRates": [
{
"roomId": "2765301",
"name": "Deluxe Standard - No Pets",
"price": 62.18,
"currency": "USD",
"mealPlan": "BREAKFAST",
"priceBeforeDiscount": 100.29,
"priceInHotelCurrency": 2099.26,
"hotelCurrency": "THB",
"excludedCharges": 3.93
}
],
"checkIn": "2026-11-11",
"checkOut": "2026-11-12",
"nights": 1,
"adults": 2,
"rooms": 1,
"destination": "Pattaya",
"language": "en-gb",
"fetchedAt": "2026-11-04T11:22:25.032Z",
"changeType": null
}Use it from code
Actor ID: cliqtomedia/booking-scraper. You need your Apify API token from Apify Console → Settings → API & Integrations.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/booking-scraper").call(run_input={
"mode": "search",
"destination": "Pattaya"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~booking-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode": "search", "destination": "Pattaya"}'# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("cliqtomedia/booking-scraper")
result = tool.invoke({"run_input": {"mode": "search", "destination": "Pattaya"}})
print(result)The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.
Data fields (40)
| Field | Type | Meaning |
|---|---|---|
recordType | string | hotel, review or calendar. Use this column to distinguish rows. |
status | string | ok for a successfully collected record. |
name | string | Property name as published by Booking.com. |
url | string | Public Booking.com hotel page. |
currency | string | Three-letter currency for this row. |
language | string | Language of the description, or the original guest review language. |
fetchedAt | string | Time this record was collected, in ISO 8601 UTC. |
destination | string | Destination name or hotel link that produced this row. |
availability | string | available, soldOut or unknown. A missing search result alone is never treated as sold out. |
hotelId | integer | Stable Booking.com property number. |
stars | number | Property star rating; null for an unrated property. |
rating | number | Overall guest score, or the score for a review row, on a 0–10 scale. |
reviewsCount | number | Number of guest reviews reported by the property. |
price | number | Displayed total for the full stay. Calendar rows contain a rounded daily price label converted to a number. |
pricePerNight | number | Displayed stay total divided by the number of nights. |
priceBeforeDiscount | number | Stay total before the displayed discount, when Booking reports one. |
excludedCharges | number | Taxes or fees that Booking reports outside the displayed stay price. |
priceWithCharges | number | Displayed stay total plus excluded charges returned by Booking. |
lat | number | Property latitude. |
lng | number | Property longitude. |
propertyTypeId | number | Booking.com accommodation type number. |
nights | number | Number of nights in the stay. |
adults | number | Number of adults requested. |
rooms | number | Number of rooms requested. |
previousPrice | number | Price in the saved monitor baseline, or null on the first observation. |
priceChange | number | Current price minus the saved previous price, in this row’s currency. |
distanceFromCenterMeters | number | Distance to the city center in meters. Filled when the search reports it in English; null for other languages, for region searches such as Pattaya and when Booking gives no distance. |
distanceLabel | string | Distance text as Booking shows it in the requested language, for example 1.2 km from centre. |
minimumNights | number | Minimum stay length reported by the availability calendar. |
stayNights | number | Number of nights associated with an anonymous review. |
ratingLabel | string | Booking’s overall score label. |
address | string | Full public property address when available. |
city | string | Property city. |
countryCode | string | Two-letter property country code. |
description | string | Full public property description when details are on. |
propertyType | string | Accommodation type name reported by Booking. |
mainPhoto | string | Public URL of the main property photo. |
finePrint | string | Public property conditions and notices. |
checkInTime | string | Property’s check-in starting time. |
checkOutTime | string | Property’s latest check-out time. |
Input settings (25)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| What to collect | mode | string | "search" |
| City or destination | destination | string | "Pattaya" |
| More destinations | destinations | array | |
| Booking.com links | startUrls | array | |
| Hotel IDs | hotelIds | array | |
| Maximum hotels per search | maxItems | integer | 10 |
| Check-in date | checkIn | string | |
| Check-out date | checkOut | string | |
| Several date ranges | dateRanges | array | |
| Adults | adults | integer | 2 |
| Rooms | rooms | integer | 1 |
| Children’s ages | childrenAges | array | |
| Currency | currency | string | "USD" |
| Several currencies | currencies | array | |
| Language | language | string | "en-gb" |
| Several languages | languages | array | |
| Minimum stay price | minPrice | number | |
| Maximum stay price | maxPrice | number | |
| Minimum guest rating | minScore | number | |
| Star ratings | stars | array | |
| Property type | propertyType | string | "any" |
| Sort hotels by | sortBy | string | "distance_from_search" |
| Free cancellation only | freeCancellationOnly | boolean | false |
| Breakfast included only | breakfastIncluded | boolean | false |
| Hotel descriptions and facilities | includeDetails | boolean | true |




