Booking.com Hotel Prices API: Search, Rooms and Reviews
The Booking.com API returns hotel prices, rooms and reviews as JSON through eleven endpoints, each costing 1 credit per successful call. Use GET /v1/booking/prices to price a destination for your dates, rooms for one hotel's room options, and reviews for guest feedback. A price check across 1,000 hotels costs between 40 and 2,000 credits, depending on the endpoints you pick.
Which Booking.com endpoint does which job?
The eleven endpoints fall into four jobs: finding hotels (destinations, search, search-by-url), pricing them (prices, bulk-prices), describing one property (hotel, rooms, facilities, photos) and judging quality (reviews, review-scores). All return JSON with named fields, and each costs 1 credit on success.
| Job | Endpoint | Method | Use it to |
|---|---|---|---|
| Find | /v1/booking/destinations |
GET | Turn a place name (q) into a destination to search |
| Find | /v1/booking/search |
GET | List hotels for a place, optionally with dates |
| Find | /v1/booking/search-by-url |
GET | Run a Booking.com search results URL you already have |
| Price | /v1/booking/prices |
GET | Get hotel names, prices and review scores for dates |
| Price | /v1/booking/bulk-prices |
POST | Send a list of searches in one request |
| Describe | /v1/booking/hotel |
GET | Read one property's details |
| Describe | /v1/booking/rooms |
GET | See one property's rooms for your dates |
| Describe | /v1/booking/facilities |
GET | List one property's facilities |
| Describe | /v1/booking/photos |
GET | Get one property's photos |
| Judge | /v1/booking/reviews |
GET | Page through guest reviews, sorted |
| Judge | /v1/booking/review-scores |
GET | Read the score breakdown for one property |
A typical flow starts with destinations or search to find hotels, then calls the per-hotel endpoints on the ones you care about. The per-endpoint pages, such as Prices, Hotel and Reviews, have a playground where you can run each one with your key.
How do you search hotels for a place and dates?
Call GET /v1/booking/search with ss (the place) and, for dated results, checkin and checkout. Only ss is required. Add group_adults, group_children and no_rooms to describe the party, and dest_id with dest_type to remove any ambiguity about which place you mean.
curl "https://api.perceptlayer.com/v1/booking/search?ss=Paris&checkin=2026-06-01&checkout=2026-06-04&group_adults=2&dest_id=-1456928&dest_type=city" \
-H "X-API-Key: $API_KEY"
Don't know the dest_id? Call destinations with q set to the place name first. dest_type accepts one of city, region, district, hotel, landmark or airport. If you already have a Booking.com results page open in a browser, search-by-url takes that url and nothing else.
Keys go in the X-API-Key header; see authentication for the query-parameter alternative.
How do you get hotel prices for your dates?
GET /v1/booking/prices returns a list of hotels with a price for your stay. It requires ss, checkin and checkout, which makes it the right call when the question is "what does this stay cost", not "which hotels exist". Here is a recorded request for three nights in Paris for two adults.
curl "https://api.perceptlayer.com/v1/booking/prices?ss=Paris&checkin=2026-11-20&checkout=2026-11-23&group_adults=2&dest_id=-1456928&dest_type=city" \
-H "X-API-Key: $API_KEY"
An excerpt of the real response, recorded on 2026-10-23:
{
"success": true,
"data": {
"title": "Booking.com: hotels in Paris",
"prices": [
{
"name": "Royal Saint Michel",
"url": "https://www.booking.com/hotel/fr/royal-saint-michel.html",
"price": "$351.05",
"review_score": "8.8",
"location": "3 Boulevard Saint Michel, Paris",
"image": "https://cf.bstatic.com/xdata/images/hotel/square240/560523800.jpg?…"
},
…
],
"total_prices": 25,
"parsed": true
},
"meta": {
"duration_ms": 1423.85,
"scraped_at": "2026-10-23T19:48:12+00:00",
"cached": false,
…
}
}
These are the parameters for prices; search takes the same ones, except that its dates are optional.
| Parameter | Type | Required | Notes |
|---|---|---|---|
ss |
string | yes | The place, up to 200 characters |
checkin |
string | yes | Check-in date |
checkout |
string | yes | Check-out date |
group_adults |
integer | no | Adults in the party |
group_children |
integer | no | Children in the party |
no_rooms |
integer | no | Number of rooms |
dest_id |
integer | no | Destination ID, from destinations |
dest_type |
string | no | city, region, district, hotel, landmark or airport |
lang |
string | no | Up to 10 characters |
currency |
string | no | Up to 3 characters |
prices documents no page, limit or offset parameter, so one call returns one result list. Two details matter for pipelines. price and review_score are strings, so parse them before you compare. The price is a formatted amount, here in dollars; pass currency (up to three characters, an ISO 4217 code) and lang to control the format. And meta.scraped_at tells you when the data was read: values are returned as found at the time of the call.
How do you get rooms and room-level prices?
GET /v1/booking/rooms takes a hotel and, optionally, your stay details, and returns that property's rooms. Identify the hotel with its Booking.com url, or with country (two characters) and slug. Add checkin, checkout, group_adults, group_children, no_rooms, lang and currency to price the rooms for your dates.
curl "https://api.perceptlayer.com/v1/booking/rooms?country=fr&slug=royal-saint-michel&checkin=2026-11-20&checkout=2026-11-23&group_adults=2" \
-H "X-API-Key: $API_KEY"
The country and slug come straight from a hotel URL: in https://www.booking.com/hotel/fr/royal-saint-michel.html, they are fr and royal-saint-michel. That means the url field in each prices result feeds the per-hotel endpoints directly. We haven't recorded a rooms response for this article, so the field list lives on the endpoint page and in the playground rather than here.
facilities and photos take the same parameters as rooms, and hotel takes only the identifiers.
How do you pull reviews and review scores?
Use GET /v1/booking/reviews for the text of guest reviews and GET /v1/booking/review-scores for the score breakdown. Both identify the hotel with url, or country plus slug. Reviews add page, limit and sort, where sort is one of recent_desc, recent_asc, score_desc or score_asc.
curl "https://api.perceptlayer.com/v1/booking/reviews?country=fr&slug=royal-saint-michel&sort=recent_desc&page=1" \
-H "X-API-Key: $API_KEY"
Sorting by recent_desc suits monitoring: you see new reviews first and can stop paging once you reach one you've stored. Sorting by score_asc surfaces complaints. Each page is one call and one credit, so the cost of reading a hotel's whole review history is the number of pages you fetch.
Reviews are guest-written text. If you store them, keep to the source's terms and don't contact the authors.
What does a price check across 1,000 hotels cost?
It costs between 40 and 2,000 credits, depending on how you build it. Every call is 1 credit, so the arithmetic is call counting. The sample above returned 25 hotels in a single prices call, and the number returned varies by search. Because prices has no paging parameter, you can't page one search up to 1,000 hotels. The first row below assumes 40 separate searches (different districts or dates, say), each returning 25 distinct hotels, so treat it as a best case.
| Approach | Calls | Credits |
|---|---|---|
prices, 40 separate searches at 25 hotels each (as in the recorded sample) |
1,000 ÷ 25 = 40 | 40 × 1 = 40 |
rooms once per hotel, for room-level prices |
1,000 | 1,000 × 1 = 1,000 |
rooms plus reviews page 1 per hotel |
2,000 | 2,000 × 1 = 2,000 |
The 1,000 credits of the second row equal the free tier: 1,000 credits every month after verifying an email address, no card. Repeat that check daily for 30 days and you need 30,000 credits, so look at the pricing page for what packs cost. Packs start at 10,000 credits, last 12 months, and carry no subscription.
bulk-prices takes a list of searches in a single POST. Its endpoint listing shows 1 credit per call. Because we haven't recorded a batch here, send a small list first and read X-Credits-Used on the response before you size a job. Every successful response also carries X-Credits-Remaining, which is how a scheduled job can stop itself before the balance runs out. The credits guide covers both headers.
How long does 1,000 calls take?
Rate limits are per account, counted per minute. A free account gets 1 request a second, so 1,000 sequential calls take about 17 minutes. A paying account runs at least 5 requests a second (300 a minute), so the same job finishes in under 4 minutes. A 429 response carries a Retry-After header with the seconds to wait; see rate limits.
A script that calls rooms for a list of hotels
This Python script calls rooms for each hotel URL in a list, waits and retries the same hotel on a 429, stops on any other error, and prints the credits the API reports. It doesn't parse the room data, because we haven't recorded a rooms response; add that once you've seen one in the playground.
import os
import time
import requests
API = "https://api.perceptlayer.com/v1/booking/rooms"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}
hotel_urls = [
"https://www.booking.com/hotel/fr/royal-saint-michel.html",
# …your other hotel URLs
]
def fetch(url, attempts=5):
for _ in range(attempts):
r = requests.get(
API,
headers=HEADERS,
params={"url": url, "checkin": "2026-11-20", "checkout": "2026-11-23", "group_adults": 2},
timeout=60,
)
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", "1")))
continue
r.raise_for_status()
return r
raise RuntimeError(f"still rate limited after {attempts} attempts: {url}")
for url in hotel_urls:
r = fetch(url)
print(url, "credits used:", r.headers["X-Credits-Used"], "remaining:", r.headers["X-Credits-Remaining"])
A rate-limited 429 isn't billed, so retrying it is safe. A timed-out request is different: it may have succeeded and been billed, because requests have no idempotency key, so don't blindly retry timeouts on a large job. Error codes such as invalid_parameters (422) and insufficient_credits (402) are listed in errors.
When should you use the official Booking.com API instead?
If you're an approved Booking.com partner, the company's own developer portal is worth checking first: it lists the Demand API, Connectivity APIs, Metasearch Connect API and Data Portability API, and may fit a production affiliate or connectivity product better than collected data. Check the portal for what access each one requires.
This API suits the cases where you need hotel prices, rooms and reviews as JSON today, in the same account and format as the rest of the travel APIs. Data is collected from publicly available sources and returned as found at the time of the call, so it isn't a booking channel and shouldn't be shown as a guaranteed, bookable rate.
Comparing sources for the same stay is a common next step. The Google Hotels API guide covers a second set of prices, and the AI travel planning agent shows how to expose both to an agent over MCP.
Get a free API key at signup, open the Booking.com API page and run the Prices call in the playground with your own dates.
APIs in this post
Frequently asked questions
How much does a Booking.com API call cost?
Every Booking.com endpoint here costs 1 credit on a successful call. Failed calls cost nothing and return X-Credits-Used: 0. New accounts get 1,000 free credits each month after verifying an email, with no credit card, so a 1,000-call job fits the free tier exactly.
Can I check prices for many destinations in one request?
Yes. POST /v1/booking/bulk-prices accepts a list of searches, and the endpoint is listed at 1 credit per call. Test it with a few searches and read the X-Credits-Used header on the response before you scale it. For a single destination, one prices call is simpler.
What is the difference between search and prices?
search requires only ss and lists hotels, with dates optional. prices requires ss, checkin and checkout, and is built to return a price for each hotel along with its review score. Use search to discover hotels and prices when the stay dates are known.
How do I identify a hotel for the rooms and reviews endpoints?
Pass the hotel's Booking.com page as url, or pass country (two characters) and slug. Both come from the hotel's URL, such as /hotel/fr/royal-saint-michel.html. The url field returned by prices gives you these values for every hotel in a result set.
How fast can I call the API?
Limits are per account and counted per minute. Free accounts get 1 request a second (60 a minute); paying accounts run at the rate of the credits they're using and at least 5 a second (300 a minute). A 429 response includes a Retry-After header with the wait in seconds.