Booking COM: the complete guide to every endpoint
This is the one document that explains every endpoint of the API: what it is for, what to send, where each value comes from, and what you get back. Read it top to bottom to learn the whole API, or jump to an endpoint from the contents.
How to read this guide
- Base URL:
https://booking-com30.p.rapidapi.com/api/v1. Every request carries two headers:X-RapidAPI-Key: YOUR_KEYandX-RapidAPI-Host: booking-com30.p.rapidapi.com. - Every response is HTTP 200 with
status(true or false),messageanddata. A wrong parameter givesValidation failedwith anerrorslist, and uses no quota. - Values are passed on. A destination token, a hotel id, an offer token or a search key always comes from an earlier response. The "Where the inputs come from" line of each endpoint says which one.
- Parameter tables say whether a value is required and what is allowed. Where a value is a fixed list, the list is given.
- Each endpoint has the same parts: What it does, Where the inputs come from, Request, then its parameters and rules, What you get back and Fields.
Contents
Hotels and stays
- Stays Autocomplete
- Stays Suggestions (popular destinations)
- Stays Map Markers
- Stays Page Metadata
- Stays Search
- Stays Map
- Stays Search Filters (dynamic, live counts)
- Stays Search Sort Options (dynamic)
- Stays Property Details (the stay detail page)
- Stays Description
- Stays Description Sections
- Stays Highlights (feature badges only)
- Stays Badges
- Stays House Rules
- Stays Important Info
- Stays Policies
- Stays Rooms (room list)
- Stays Room Types (available and sold out)
- Stays Facilities
- Stays Property Facilities
- Stays Food and Drink
- Stays Photos
- Stays Photo List
- Stays Review Photos
- Stays Review Scores
- Stays Review Score Comparison
- Stays Featured Reviews
- Stays Review Filters
- Stays Reviews
- Stays Questions
- Stays Surroundings
- Stays Things To Do
Shared lookups
- Common Languages (shared by every module)
- Common Currencies (shared by every module)
- Common Exchange Rates (shared by every module)
Attractions and things to do
- Attractions Autocomplete
- Attractions Destinations
- Attractions Suggestions
- Attractions Search
- Attractions Search Filters
- Attraction Product
- Attraction Comparison
- Attraction Review Snippets
- Attraction Reviews
- Attraction Availability Calendar
- Attraction Availability
- Attraction Live Availability
- Attraction Legal Consent
Flights
- Flights Autocomplete
- Flights Fly Anytime ("I'm flexible")
- Flights Search
- Flights Details
- Flights Fare Quote
- Flights Fare Quote Extras
- Flights Seat Map
Car rental
- Cars Countries
- Cars Autocomplete
- Cars Search
- Cars Vehicle
- Cars Supplier
- Cars Supplier Reviews
- Cars Supplier Location
- Cars Terms
- Cars Price Summary
Taxi and airport transfers
- Taxi Autocomplete
- Taxi Airports
- Taxi Flights
- Taxi Search
- Taxi Supplier
- Taxi Public Transport
- Taxi Uber Rates
Hotels and stays
1. Stays Autocomplete
What it does. Destination suggestions for a search box: type "Mum", get cities, airports, landmarks and hotels.
Where the inputs come from. Nothing from an earlier call: this is where a hotel journey starts. query is the text your user typed.
Request
GET /api/v1/stays/autocomplete?query=Mum
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Part | Detail |
|---|---|
| Auth | API key in X-RapidAPI-Key (create one with POST /api-keys using the JWT from login). Needs an active subscription and counts against the monthly quota. |
query |
Required, string, 1–200 characters, trimmed (one character is enough: M and 長 both return results). Longer text is accepted but finds nothing. |
| Language | No language parameter. Results come back in the language the search text is written in: send query in Hindi, Arabic or Chinese and the destinations come back in that language (e.g. मुंबई). Per the product owner; not verified live. |
What you get back
Always HTTP 200. status says whether it worked.
{
"status": true,
"message": "Destinations found",
"data": {
"Booking.com": { "serverVersion": 180, "clientVersion": 180, "mfeId": "b-accommodation-disambiguation-saba-mfe/autocomplete" },
"suggestions": [ { ...see fields below... } ]
}
}
| Case | status |
message |
data |
|---|---|---|---|
| At least one destination | true |
Destinations found |
provider + suggestions |
| Booking.com answered, nothing matched | false |
No destinations found |
provider + suggestions: [] |
| Booking.com unavailable or sent an unreadable reply | false |
Stays provider is unreachable / …returned HTTP <n> / …returned an invalid response |
none |
query missing or too short |
false |
Validation failed (+ errors[]) |
none |
| No / bad API key, no subscription, quota hit | false |
the auth/quota message | none |
Suggestion fields
| Field | Type | Meaning |
|---|---|---|
id |
number | Booking.com location ID. Can be negative (e.g. -2092174 for Mumbai city). Use with type; the same ID can exist under different types. |
type |
string | city, airport, landmark, hotel, district, region, latlong (a map point such as a street or venue, e.g. "孟买海滨大道"). More types may appear. destinationType is deliberately not restricted to this list, since it's just whatever this field returns, not something we maintain a closed catalog of. |
destination |
string | One token combining id and type (or, for latlong, the coordinates) — copy this straight into /stays/search's, /stays/search-filters's or /stays/search-sort-options's own destination parameter (and into /stays/things-to-do, which accepts only city: and latlong: tokens) instead of reading id/type separately. Format "<type>:<id>", e.g. "city:-2092174"; for type: "latlong", "latlong:<latitude>,<longitude>" — its id alone does not work as a search destination, only coordinates do, which is exactly why this field uses them instead. |
name |
string | Display title, e.g. Mumbai, Chhatrapati Shivaji International Airport Mumbai. |
subtitle |
string | Where it is, e.g. Maharashtra (Mumbai Region ), India. Note Booking.com's stray space before ). |
labels[] |
{type, name} |
Breadcrumb: city → region → country. |
countryCode |
string | Lower-case ISO code, in. |
coordinates |
{latitude, longitude} |
Decimal degrees. |
hotelsCount |
number | Properties available there (city 1975, airport 137, hotel 1). |
imageUrl |
string | null | Booking.com's own image URL, usually small (square60 / square150). |
images |
object | null | thumbnail (square150), medium (square550), large (max1024x768). Built from imageUrl by swapping the size segment; the ?k= signature must stay. Airports use a fixed static icon, so all three are identical. null when there is no image. |
searchContext |
{searchText, index} |
Echo of the search text and Booking.com's ranking position (0 = best). |
providerMetadata |
object | autocompleteSource (brick), roundTripVariable (opaque token, probably needed to continue a search on Booking.com), metaMatches[]. |
Suggestions are de-duplicated by id + type (Booking.com repeats the first result in a "return button" action).
Example suggestion (city)
{
"id": -2092174,
"type": "city",
"name": "Mumbai",
"subtitle": "Maharashtra (Mumbai Region ), India",
"labels": [
{ "type": "city", "name": "Mumbai" },
{ "type": "region", "name": "Maharashtra (Mumbai Region )" },
{ "type": "country", "name": "India" }
],
"countryCode": "in",
"coordinates": { "latitude": 18.9689769744873, "longitude": 72.8189697265625 },
"hotelsCount": 1975,
"imageUrl": ".../city/square150/1000023.jpg?k=…&o=",
"images": {
"thumbnail": ".../city/square150/1000023.jpg?k=…&o=",
"medium": ".../city/square550/1000023.jpg?k=…&o=",
"large": ".../city/max1024x768/1000023.jpg?k=…&o="
},
"searchContext": { "searchText": "Mum", "index": 0 },
"providerMetadata": { "autocompleteSource": "brick", "roundTripVariable": "GhBk…==", "metaMatches": [] }
}
Sample result for query=Mum (5 items, in order): Mumbai (city), Chhatrapati Shivaji International Airport Mumbai (airport), Mumbai Central (landmark), The Taj Mahal Palace, Mumbai (hotel), Navi Mumbai (city).
2. Stays Suggestions (popular destinations)
What it does. Themed lists of popular destinations for a home-page / empty search box: "Hill stations and mountains", "Goa and Kerala beaches", "Swiss Alps and lakes", and so on. Complements autocomplete, which needs typed text. This is also a valid source of a search destination, exactly like autocomplete — every destination card here carries its own destination token (see the Fields table below), copyable straight into /stays/search, /stays/search-filters or /stays/search-sort-options. A layman user can tap any popular-destination card shown here, with no typing, and go straight to search.
Where the inputs come from. Nothing from an earlier call. It needs no destination: it returns popular destinations to show before the user types anything. Only languageCode is optional.
Request
GET /api/v1/stays/suggestions?limit=6
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Part | Detail |
|---|---|
| Auth | API key in X-RapidAPI-Key; needs an active subscription; counts against the monthly quota (same chain as autocomplete). |
limit |
Optional integer 1–10, default 6: destinations per cluster. Booking.com maximum is 10 (see below). |
languageCode |
Optional language code from GET /common/languages, default en-us (e.g. hi). Names and cluster titles come back in that language. |
What you get back
{
"status": true,
"message": "Suggestions found",
"data": {
"clusterCount": 10,
"destinationCount": 60,
"clusters": [
{
"index": 0,
"name": "Heritage cuisine trails",
"count": 6,
"destinations": [
{
"id": -2106102,
"type": "city",
"destination": "city:-2106102",
"name": "New Delhi",
"subtitle": null,
"labels": [],
"countryCode": "in",
"countryName": "India",
"coordinates": null,
"hotelsCount": null,
"imageUrl": "https://r-xx.bstatic.com/xdata/images/city/square150/990313.jpg?k=…&o=",
"images": {
"thumbnail": "https://r-xx.bstatic.com/xdata/images/city/square150/990313.jpg?k=…&o=",
"medium": "https://r-xx.bstatic.com/xdata/images/city/square550/990313.jpg?k=…&o=",
"large": "https://r-xx.bstatic.com/xdata/images/city/max1024x768/990313.jpg?k=…&o="
},
"themeId": null,
"image": { "id": 990313, "genericUrl": "/xdata/images/city/<SIZE>/990313.jpg?k=…&o=", "extras": null },
"extras": null
}
],
"extras": null
}
],
"Booking.com": { "durationMs": 72, "startTime": 1792308704766, "endTime": 1792308704838, "extraExtensions": null, "extraOutput": null }
}
}
...
| Case | status |
message |
|---|---|---|
| At least one destination | true |
Suggestions found |
| Booking.com answered with nothing | false |
No suggestions found |
service errors in the reply |
false |
Stays suggestions provider error: <message> |
| Booking.com unavailable | false |
Stays suggestions provider is unreachable / …returned HTTP <n> |
Bad limit |
false |
Validation failed (+ errors[]) |
| Auth / quota problems | false |
the auth/quota message |
Fields
| Field | Meaning |
|---|---|
clusterCount, destinationCount |
Totals across the response. |
clusters[].name |
Theme title from Booking.com (destinationsClusterName). The ten seen: Heritage cuisine trails, Cultural cities and arts, Cities and cafes, Hill stations and mountains, Temple towns and wellness, Asian markets and islands, Goa and Kerala beaches, European capitals and heritage, Swiss Alps and lakes, North American shopping. These are personalised/rotating, so expect them to change. |
clusters[].index, count |
Position in the response and number of destinations. |
destinations[].id |
locationId; can be negative (-2106102) or positive (900048213). Same id space as autocomplete. |
destinations[].type |
locationType; only city seen. |
destinations[].destination |
Same token format as autocomplete's destination — copy this straight into /stays/search's, /stays/search-filters's or /stays/search-sort-options's own destination parameter. Format "<type>:<id>", e.g. "city:-2106102". This endpoint has never been seen to return type:"latlong", so there's no coordinate form here — if it ever does, id alone would not work as a search destination (same caveat as autocomplete). |
destinations[].name, countryCode, countryName |
e.g. New Delhi, in, India. Names keep Booking.com's diacritics (Chandīgarh, Rāmeswaram). |
destinations[].themeId |
Always null so far. Kept in case Booking.com fills it. |
imageUrl, images |
Same as autocomplete: imageUrl is the small (square150) full URL; images has thumbnail (square150), medium (square550) and large (max1024x768). Built from Booking.com's path by filling in the size and the image host STAYS_SUGGESTIONS.imageBaseUrl. Both are null if the card has no image. |
image |
Booking.com's own image record: id and genericUrl (size-template path with <SIZE>, no host). Kept so no data is lost. |
subtitle, labels, coordinates, hotelsCount |
Not sent by this Booking.com: always null / [] / null / null. Present only so the keys match autocomplete. |
extras |
Anything Booking.com sends that we do not map (on destination, image and cluster) so no data is silently lost; null when nothing extra. |
provider.* |
Booking.com's own timing for the query (latency_insights), plus extraExtensions / extraOutput for unmapped fields. |
Left out on purpose: service's __typename tags (DestinationCard, MainImage, Recommendations, DestinationMultiCardsOutput, RecommendationPlatformQueries), which only name internal types. Order is preserved, nothing is de-duplicated, and a destination appearing in two clusters appears twice.
Same destination keys as autocomplete
A destination here has the same keys as an autocomplete suggestion (id, type, name, subtitle, labels, countryCode, coordinates, hotelsCount, imageUrl, images), so one client model reads both. Fields a Booking.com does not send are null ([] for labels). Differences: suggestions add countryName, themeId, image and extras; autocomplete adds searchContext and providerMetadata and has no countryName. The list wrapper differs: autocomplete is a flat suggestions[], suggestions is clusters[].destinations[].
3. Stays Map Markers
What it does. The map pins that are not properties: the cities, districts, landmarks, airports, beaches and ski resorts inside a map area, each with its name, coordinates and, where there is one, the destination token that you can pass straight to a search.
Where the inputs come from. Part 1 (Find where to search) in the journey overview, next to GET /stays/map: ask for the properties and for these pins with the same map corners.
Request
GET /api/v1/stays/map-markers?northEast=40.92,-73.70&southWest=40.55,-74.30&types=airports,landmarks&limit=5
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
northEast, southWest |
yes | The two corners of the map area as latitude,longitude; northEast has the larger latitude and longitude. |
types |
no, default all six | Comma-separated: cities, districts, landmarks, airports, beaches, ski. |
limit |
no, default 20 | Markers per type, 1 to 100. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the names. |
What you get back
{
"status": true,
"message": "Map markers found",
"data": {
"boundingBox": { "northEast": { "latitude": 40.92, "longitude": -73.7 }, "southWest": { "latitude": 40.55, "longitude": -74.3 } },
"markerCount": 7,
"markers": {
"airports": [ { "id": 39, "destination": "airport:39", "name": "LaGuardia Airport", "latitude": 40.7742, "longitude": -73.8719, "photoUrls": [], "cityName": "New York", "countryName": "United States", "iata": "LGA" } ],
"landmarks": [ { "id": 11045, "destination": "landmark:11045", "name": "Empire State Building", "latitude": 40.74843, "longitude": -73.98567, "photoUrls": ["https://r-xx.bstatic.com/xdata/images/landmark/270x200/278346.jpg?k=…"] } ]
}
}
}
| Case | status |
message |
|---|---|---|
| At least one marker | true |
Map markers found |
| Nothing in the area | false |
No map markers found in this area |
| Booking.com down / HTTP error | false |
Stays map markers provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
markers.<type>[] |
One list per requested type. Every pin has id, destination (city:20088325, district:, landmark:, airport:; null for beaches and ski resorts), name, latitude, longitude and photoUrls. |
| airports | Also iata (LGA), cityName, countryName. |
| districts | Also ufi (the city id), isCityCenter and polygon[] (latitude, longitude: the outline of the district). |
| beaches | Also review (count, score, text) and details[] (Golden sand). |
| ski resorts | Also trailsCoverageText, liftsCountText and lifts[] (id, location, capacity, translation); the lifts were empty on the resorts tested. |
4. Stays Page Metadata
What it does. The public booking.com page of any destination and its SEO text: the link, the title, a short description, the keywords and a 200 px image. It works for every kind of destination GET /stays/autocomplete returns: hotel, city, district, airport, landmark, region and country.
Where the inputs come from. Take a destination token from GET /stays/autocomplete (or hotel:<id> for a property found in /stays/search). See the journey overview.
Request
GET /api/v1/stays/page-metadata?destination=city:20088325&languageCode=en-gb
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
destination |
yes | <type>:<id> copied from a /stays/autocomplete suggestion's destination field: hotel:, city:, district:, airport:, landmark:, region:, country:. Not latlong:. |
languageCode |
no, default en-us |
A code from /common/languages. Decides the language of the texts and of the link. |
What you get back
{
"status": true,
"message": "Page metadata found",
"data": {
"title": "3239 hotels in New York, USA. Book your hotel now! - Booking.com",
"description": "Great savings on hotels in New York, USA online. Good availability and great rates. Read hotel reviews and choose the best hotel deal for your stay.",
"url": "https://www.booking.com/city/us/new-york.en-gb.html",
"keywords": ["3 star hotel", "4 star hotel", "..."],
"imageUrl": "https://cf.bstatic.com/xdata/images/city/square200/....jpg?k=...&o=",
"extras": null
}
}
| Case | status |
message |
|---|---|---|
| The destination has a page | true |
Page metadata found |
| Unknown id, or an id of another type | false |
No page metadata found for this destination |
| Booking.com down / HTTP error | false |
Stays page metadata provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
url |
The public booking.com page, in the language chosen. |
title |
The page title used for search engines. |
description |
A short teaser (cut at about 140 characters). |
keywords[] |
The page keywords (a hotel: about 14; a city: hundreds). |
imageUrl |
A 200 px image of the destination. |
5. Stays Search
What it does. Find stays (hotels, apartments, hostels, ...) for a destination and dates, 20 results per page, with readable details: price, taxes, discount, review, distance from the centre, perks, deal badges, images.
Where the inputs come from. Part 2 of the journey overview (the search list); Part 1 gets you a destination, the same list on a map is GET /stays/map. Next step after this call: pick a property from data.properties[] and pass its id as hotelId to the Part 3 endpoints: the whole page in one call (property-details), or by topic - about it (description, description-sections, highlights, badges, house-rules, important-info, policies), rooms and prices (rooms, room-types), facilities and food (facilities, property-facilities, food-and-drink), photos (photos, photo-list, review-photos), reviews and questions (review-scores, review-score-comparison, featured-reviews, review-filters, reviews, questions) and around the property (surroundings, things-to-do). See the journey overview for the whole flow.
Request
GET /api/v1/stays/search?destination=city:-2092174&checkin=2026-12-01&checkout=2026-12-02&adults=2&rooms=1¤cyCode=INR&languageCode=en-us&page=1
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
Auth, subscription and monthly quota work as for the other stays endpoints (one search = one request).
| Parameter | Required | Rule (all measured live) |
|---|---|---|
destination |
yes | One token, copied straight from a destination suggestion's own destination field — no need to read id and type separately. Two endpoints hand you one of these: GET /stays/autocomplete (typed search text) and GET /stays/suggestions (popular destinations, no typing needed). Format "<type>:<id>", e.g. city:-2092174 (id can be negative); for a map-point suggestion (autocomplete only — suggestions has never been seen to return one), "latlong:<latitude>,<longitude>", e.g. latlong:18.9333,72.8238. type is not checked against a fixed list — it's whatever the suggestion returned, and Booking.com is the one that ultimately accepts or rejects it (a made-up type degrades to "no results", not an error, ). Malformed values (no :, non-numeric id, out-of-range coordinates) are rejected before any Booking.com call. |
checkin |
yes, unless you use flexible dates | YYYY-MM-DD, a real calendar date. Not in the past (yesterday is accepted for time zones); at most 500 days from today (501 returns nothing). |
checkout |
yes, unless you use flexible dates | After checkin. The stay is at most 90 nights (91 returns nothing). |
flexibleMonths |
no (flexible dates) | Up to 3 months to look in, written YYYY-MM, comma-separated, e.g. 2026-11,2026-12. The current month is the earliest allowed; at most 500 days ahead. Give all three flexible parameters together, and never together with checkin/checkout. |
flexibleNights |
no (flexible dates) | The stay length, 1–90 nights. |
flexibleStartWeekday |
no (flexible dates) | The weekday the stay starts on: monday ... sunday (or 1 = Monday ... 7 = Sunday). |
flexibleDays |
no, default 0 |
Plus/minus days around checkin/checkout, like the Calendar tab's "± 1 / 2 / 3 / 7 days": 0 (exact dates), 1, 2, 3 or 7; nothing else is accepted. Each property then shows its cheapest window within that many days either side. Not together with the months mode. See Plus/minus days. |
adults |
no, default 2 | Guests, 1–30. Booking.com silently treats 0 or 31+ as 2, so we reject them. |
rooms |
no, default 1 | 1–30, and not more than adults: with fewer guests than rooms Booking.com silently cuts the rooms down (3 rooms for 2 guests gives 2). 31+ becomes 1. |
childrenAges |
no, default none | Comma-separated age of each child at check-out, 0–17 (0 = under 1 year old), at most 10 children. Not counted in adults. The count comes from how many ages are listed, so e.g. 0,3 always means exactly 2 children — there is no separate count to get out of sync. |
pets |
no, default false |
Travelling with pets. Internally this is just the "Pets allowed" facility filter — see below. |
filters |
no, default none | Comma-separated Booking.com filters, each key::value (Booking.com's own format, e.g. class::5,free_cancellation::1). See §4 below for every known key and value, or call GET /stays/search-filters with no filters applied to discover them live, with real counts. An unknown key, or a value outside a known closed list, is rejected before the call is made; pets and filters share the same underlying Booking.com filter and are deduped if both set facility::4. |
currencyCode |
no, default USD |
ISO code from GET /common/currencies (145 supported). Case-insensitive. An unsupported code makes Booking.com quietly use INR, so we reject it. |
languageCode |
no, default en-us |
Code from GET /common/languages. All 45 translate the results (property types, labels, room text). |
page |
no, default 1 | 1–50, 20 properties per page. Booking.com repeats earlier results beyond offset 1000, so at most 1,000 results can be paged. |
sortBy |
no, default popularity |
Known friendly names: popularity, homesAndApartmentsFirst, distance, classDescending, classAscending, reviewScore, price, priceDescending (ground truth from Booking.com's own "SorterBar" discovery call, not guessed). Not a closed list — any other string is passed straight through to Booking.com, so a providerValue copied from GET /stays/search-sort-options also works. See §5 below. |
Validation errors use the usual shape: {"status":false,"message":"Validation failed","errors":[{"field","message"}]}.
Flexible dates ("I'm flexible")
Instead of exact dates you can ask for a stay of N nights that starts on a weekday, in up to 3 months, like the app's "I'm flexible" tab. Booking.com then finds, for every property, its cheapest matching window, and each property shows its own dates and the price for exactly that window.
GET /api/v1/stays/search?destination=city:20088325&flexibleMonths=2026-11,2026-12&flexibleNights=2&flexibleStartWeekday=friday&adults=2¤cyCode=USD
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
| What the app offers | What to send |
|---|---|
| Weekend | flexibleNights=2 and flexibleStartWeekday=friday |
| Week | flexibleNights=7 and the weekday you want the week to start on |
| Month | flexibleNights=28 to 30 and a weekday |
| Other: a number of nights and a check-in weekday | flexibleNights and flexibleStartWeekday as chosen |
| When do you want to go (select up to 3 months) | flexibleMonths, e.g. 2026-11,2026-12,2027-01 |
Rules (each broken rule is a Validation failed answer, because Booking.com would otherwise silently run an ordinary search):
flexibleMonths,flexibleNightsandflexibleStartWeekdaymust all be given, and not together withcheckin/checkout.- At most 3 months, each
YYYY-MM, none in the past (the current month is fine: only its days after today are used), none more than 500 days ahead. Repeats are removed and the months are sorted. - 1–90 nights.
- The stay starts tomorrow at the earliest (today is never used, even on the chosen weekday). Only the check-in has to be in a chosen month; the check-out can fall in the next month.
- Everything else works as in an ordinary search:
adults,rooms,childrenAges,pets,filters,currencyCode,languageCode,sortBy(pricesorts by the flexible price) andpage. A month with no matching day left (or too far ahead) simply returnsstatusfalse, no properties. /stays/search-filtersand/stays/search-sort-optionsdo not accept flexible dates; call them with an ordinary date range.
What comes back:
properties[].stayis new and always present:{ checkin, checkout, nights, label }, the dates the property'spriceis for. In an ordinary search it is the searched range; in a flexible search every property has its own (its cheapest window in your months).labelis the same range as the app writes it, in your language (Fri 20 Nov – Sun 22 Nov,Sa., 21. Nov. – Di., 24. Nov.); it no longer also appears inbadges.search.modeisfixed,plusMinusDaysorflexibleMonths. In the months modesearch.checkinandsearch.checkoutarenullandsearch.flexiblesays what was asked:{ months: [{ year, month, name, value }], nights, startWeekday: { number, name } };search.nightsis the stay length.- The price of a property is the total for its own window, exactly what an ordinary search of those dates shows (checked on 18 hotels). Two properties in the same list can have different windows; compare them by
stay, not by position.
{
"search": { "mode": "flexibleMonths", "flexibleDays": 0, "checkin": null, "checkout": null, "nights": 2,
"flexible": { "months": [ { "year": 2026, "month": 11, "name": "November", "value": "2026-11" } ], "nights": 2, "startWeekday": { "number": 5, "name": "friday" } } },
"properties": [
{ "id": 1106729, "name": "HI New York City Hostel", "stay": { "checkin": "2026-11-20", "checkout": "2026-11-22", "nights": 2, "label": "Fri 20 Nov – Sun 22 Nov" },
"price": { "amount": 292, "currencyCode": "USD", "formatted": "US$292" } }
]
}
Plus/minus days (flexibleDays)
On the Calendar tab the app can search exact dates or ± 1, 2, 3 or 7 days. Send your checkin and checkout as usual and add flexibleDays:
GET /api/v1/stays/search?destination=city:20088325&checkin=2026-11-10&checkout=2026-11-12&flexibleDays=3
- Every property shows its cheapest window whose check-in is within 3 days either side of
checkin, for the same number of nights (here 2).properties[].stayhas that property's own dates andpriceis the total for exactly those dates (the same price an exact-dates search of that window gives). The exact dates are often not the cheapest: in the test, with ± 3 days none of 16 compared hotels was cheapest on the searched date's neighbours-only basis, the chosen check-ins were 3, 2 and 1 day before and 1 day after. - Only
0,1,2,3and7are accepted (the app's own five choices);4,5,6,10,14and others are rejected, because Booking.com answers them with an error. search.modeisplusMinusDays,search.flexibleDaysthe number, andsearch.checkin/search.checkoutstay as you sent them.search.nightsis the stay length.- It cannot be combined with
flexibleMonths/flexibleNights/flexibleStartWeekday(they are the app's two separate modes). Everything else (guests, filters, sorting, paging, currency, language) works as usual. The same options exist on the map:GET /stays/map.
What you get back
{
"status": true,
"message": "Properties found",
"data": {
"search": { "destination": "city:-2092174", "destinationId": -2092174, "destinationType": "city", "checkin": "2026-12-01", "checkout": "2026-12-02",
"adults": 2, "rooms": 1, "childrenAges": [0, 3], "pets": false, "currencyCode": "INR", "languageCode": "en-us", "page": 1,
"nights": 1, "sortBy": "popularity", "resolvedSortBy": "popularity", "searchId": "7e9db4bb-…", "pageViewId": "0dba3c04…" },
"pagination": { "page": 1, "pageSize": 20, "count": 20, "totalResults": 957, "totalResultsText": "957 properties",
"totalPages": 48, "maxPage": 50, "hasNextPage": true },
"propertyTypes": [ { "name": "Hotels", "count": 703, "countText": "703 properties", "filter": "property_type::204" } ],
"map": { "boundingBox": { "northEast": { "latitude": 19.358, "longitude": 73.163 }, "southWest": { "latitude": 18.657, "longitude": 72.782 } } },
"properties": [ { "…": "see below" } ],
"Booking.com": { "serverVersion": 180, "clientVersion": 180, "mfeId": "b-saba-mfe-appsearch/saba", "extras": null }
}
}
| Case | status |
message |
|---|---|---|
| At least one property | true |
Properties found |
| Nothing matches (unknown destination, etc.) | false |
No properties found for this search |
| Booking.com unavailable | false |
Stays provider is unreachable / …returned HTTP <n> |
| Bad parameters | false |
Validation failed + errors[] |
Page-level fields:
search: what was searched, plusmode(fixedorflexible; with flexible datescheckin/checkoutarenullandflexibledescribes the request),nights,sortBy(an echo of the request — always present),resolvedSortBy(Booking.com's own raw sort key it actually applied) and ids from Booking.com (searchId,pageViewId).resolvedSortByandpageViewIdare only present on page 1 and only whensortByis left at the default — asking Booking.com to sort at all (evenpopularityexplicitly) makes it stop returning this, ; omitting the parameter for the default case keeps it populated, since the result is identical either way.pagination.totalResults/totalPages/totalResultsText: page 1 only (nullon later pages; keep the value from page 1).hasNextPageis false on the last page or page 50.propertyTypes: Hotels / Apartments / Hostels / Guest houses with counts and Booking.com'sfiltervalue (for the filters to come). Page 1 of city/region searches only; empty otherwise and forlatlong/airport/hotel.map.boundingBox: the rectangle containing the results (page 1).
A property
{
"id": 10679861,
"name": "Aurika, Mumbai International Airport - Luxury by Lemon Tree Hotels",
"position": 7,
"starRating": 5,
"isPreferred": true,
"review": { "score": 8.5, "label": "Very Good", "count": 1637 },
"location": { "latitude": 19.103475, "longitude": 72.862584, "countryCode": "in", "cityId": -2092174,
"summary": "Western Suburbs • 3.4 km from downtown", "area": "Western Suburbs",
"distanceFromCenterKm": 3.4, "distanceFromCenterText": "3.4 km from downtown" },
"highlights": [ { "icon": "beach_palm", "text": "Beachfront", "distanceKm": null } ],
"perks": [ "Breakfast included" ],
"urgency": [ "We have 3 left at this price" ],
"roomsLeft": 3,
"stay": { "checkin": "2026-12-01", "checkout": "2026-12-02", "nights": 1, "label": null },
"badges": [ { "text": "Late Escape Deal", "variant": "constructive", "identifier": "Late Escape Campaign", "explanation": "Late Escape Deal" } ],
"roomSummary": "Hotel room: 2 beds",
"price": { "amount": 8228, "currencyCode": "INR", "formatted": "₹ 8,228", "taxesIncluded": false,
"taxesAndFees": { "amount": 2451.94, "currencyCode": "INR" }, "totalAmount": 10679.94,
"chargesInfo": "+₹ 2,452 taxes and fees", "originalAmount": 12100, "originalFormatted": "₹ 12,100",
"discountPercent": 32, "taxExceptions": [], "extras": null },
"checkInTime": { "from": "14:00", "until": "00:00" },
"checkOutTime": { "from": "00:00", "until": "12:00" },
"imageUrl": ".../square60/530661047.jpg?k=…&o=",
"mainPhotoId": 530661047,
"images": { "thumbnail": ".../square150/…", "medium": ".../square550/…", "large": ".../max1024x768/…" },
"blockIds": [ "1067986109_441325494_2_0_0_1447906" ],
"extras": { "wishlistName": "Mumbai", "isFirstPage": true, "currency": "INR", "optOutFromGalleryChanges": 0, "qualityClass": 0 }
}
| Field | Meaning |
|---|---|
id, name, position |
Property id, name, rank in the results (0 = first, continues across pages). Pass id straight into GET /stays/highlights's hotelId for the feature-badge strip (e.g. "Pet friendly", "Breakfast"), or into GET /stays/property-details's hotelId for the full picture: rooms, priced facilities, Q&A, gallery photos, or into GET /stays/photos's hotelId for every photo with room grouping. |
starRating |
Hotel stars 1–5, null when unrated. isPreferred: Booking.com's "Preferred" partner mark. |
review |
score (e.g. 8.4 of 10), label ("Very Good"), count. null when the property has no reviews. |
location |
Coordinates, country, cityId (the hotel's own city id: in an airport or landmark search it differs from result to result; the same number as location.destinationId of /stays/property-details), and the card's own line "Area • distance". distanceFromCenterKm is read from that text (assumed km; "500 m" becomes 0.5), the text is kept in distanceFromCenterText. Some cards say only "In downtown": area and the number are then null. |
highlights |
Icon + text facts such as Beachfront, 2.8 km from beach (distanceKm 2.8), Sustainability certification. |
perks |
Positive extras shown in green, e.g. Breakfast included. |
urgency |
Scarcity messages in red, e.g. We have 3 left at this price; roomsLeft is the number when there is exactly one. |
badges |
Deals such as Late Escape Deal, Limited-time Deal. |
roomSummary |
The recommended room as plain text (Hotel room: 1 bed, 2 hotel rooms: 2 beds). |
stay |
The dates price is for: checkin, checkout, nights and label (the range as the app writes it, only in a flexible search). The searched range in an ordinary search, the property's own cheapest window in a flexible one. |
price |
See below. |
checkInTime, checkOutTime |
Windows in 24 h time. |
imageUrl, images, mainPhotoId |
Same image fields as autocomplete: imageUrl is Booking.com's small picture, images has thumbnail (150), medium (550) and large (1024×768). |
blockIds |
Booking.com's ids of the offered rooms. Needed to book or look up the room later. |
extras |
Booking.com fields we do not interpret (kept so nothing is lost). extras.currency is Booking.com's default currency and does not follow currencyCode: always read the currency from price.currencyCode. |
Price
Prices are for the whole stay and all rooms you asked for.
amount/formatted: the main price shown by Booking.com, incurrencyCode.taxesIncluded:falsewhen taxes and fees are charged on top (taxesAndFeesgives them,totalAmount=amount+ taxes);truewhenamountalready contains them (taxesAndFeesisnull,totalAmount=amount). Which form comes back depends on Booking.com/market, so read this flag instead of assuming.originalAmount/originalFormatted/discountPercent: the struck-through price on discounted stays (nullotherwise). The percent is computed as1 - amount / originalAmount.chargesInfo: Booking.com's own wording ("+₹ 2,452 taxes and fees", "Includes taxes and charges").
6. Stays Map
What it does. The properties on the map: the same search as GET /stays/search, but you can ask for the visible map area (a bounding box) as well as for a destination, and you get up to 100 properties per call, each with its coordinates, price, review, its own stay dates and the room-level offers.
Where the inputs come from. Part 2 (The search list) in the journey overview, next to GET /stays/search. Use it to draw a map: send the corners of the area the user sees (northEast, southWest), and again whenever the map moves or zooms. The pins that are not properties (airports, landmarks, beaches ...) are in GET /stays/map-markers.
Request
GET /api/v1/stays/map?northEast=40.8327,-73.9109&southWest=40.6433,-74.0245&checkin=2026-11-10&checkout=2026-11-12&adults=4&rooms=2&childrenAges=0,3¤cyCode=INR&limit=100
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
destination |
one of destination or the map area |
<type>:<id> from /stays/autocomplete, /stays/suggestions or a pin of /stays/map-markers. Types: city, region, district, landmark, airport, hotel, country. Not latlong: use the map area. |
northEast, southWest |
one of destination or the map area; both together |
The two corners of the visible map as latitude,longitude, e.g. 40.8327,-73.9109. northEast must have the larger latitude and longitude (a box across the 180th meridian is not supported). Not together with destination. |
checkin, checkout |
yes, unless flexible dates are used | As in /stays/search: YYYY-MM-DD, not in the past, at most 500 days ahead, at most 90 nights. |
flexibleMonths, flexibleNights, flexibleStartWeekday |
no | The "I'm flexible" mode, all three together, instead of checkin/checkout: up to 3 months YYYY-MM, 1 to 90 nights, a weekday (monday ... sunday or 1 to 7). See Flexible dates. |
flexibleDays |
no, default 0 | Plus/minus days around checkin/checkout: 0 (exact), 1, 2, 3 or 7. Not with the months mode. |
adults, rooms, childrenAges |
no | As in search: adults 1 to 30 (default 2), rooms 1 to 30 and not more than adults, childrenAges such as 0,3. |
pets, filters |
no | As in search (filters=class::5,..., see /stays/search-filters). |
sortBy |
no, default popularity |
The same names as search: popularity, homesAndApartmentsFirst, distance, classDescending, classAscending, reviewScore, price, priceDescending, or a Booking.com key from /stays/search-sort-options. |
limit |
no, default 20 | Properties per page, 1 to 100. |
page |
no, default 1 | 1 to 50; the offset is (page - 1) * limit. The list ends where the availability ends. |
currencyCode, languageCode |
no | As in search (defaults USD, en-us). |
What you get back
{
"status": true,
"message": "Properties found",
"data": {
"search": { "mode": "fixed", "destination": null,
"boundingBox": { "northEast": { "latitude": 40.8327, "longitude": -73.9109 }, "southWest": { "latitude": 40.6433, "longitude": -74.0245 } },
"checkin": "2026-11-10", "checkout": "2026-11-12", "flexible": null, "flexibleDays": 0, "nights": 2, "firstWindow": null,
"adults": 4, "rooms": 2, "childrenAges": [0, 3], "filters": [], "pets": false, "sortBy": "popularity",
"currencyCode": "INR", "languageCode": "en-us", "searchId": "780280b2-...", "destinationName": "New York", "destinationCountryCode": "us" },
"pagination": { "page": 1, "limit": 100, "offset": 0, "count": 100, "hasNextPage": true },
"map": { "boundingBoxes": [ { "type": "SMART_AV", "northEast": { "latitude": 40.8485, "longitude": -73.9216 }, "southWest": { "latitude": 40.6897, "longitude": -74.0223 } } ] },
"properties": [
{ "id": 1106729, "name": "West Side YMCA", "position": 0, "accommodationTypeId": 203,
"starRating": 3, "qualityRating": null, "isPreferred": false, "isPreferredPlus": false, "isSponsored": false, "sponsored": null,
"review": { "score": 6.6, "label": "Pleasant", "count": 14063 },
"location": { "latitude": 40.7708451, "longitude": -73.9806124, "address": "5 West 63rd Street", "city": "New York (New York)", "countryCode": "us", "cityId": 20088325,
"area": "Upper West Side", "distanceFromCenterText": "350 m from centre", "distanceFromSearchPointKm": 0.33, "distanceText": "350 m",
"locationScore": 9.4, "locationScoreLabel": "Location", "displayLocation": null, "skiLiftDistance": null, "skiLiftDistanceDescription": null },
"stay": { "checkin": "2026-11-10", "checkout": "2026-11-12", "nights": 2, "isOwnWindow": false },
"price": { "amount": 34348.56, "currencyCode": "INR", "formatted": "Rs. 34,349", "taxesIncluded": true, "taxesAndFees": null, "totalAmount": 34348.56,
"chargesInfo": "Includes taxes and charges", "originalAmount": 40800.66, "originalFormatted": "Rs. 40,801", "discountPercent": 16,
"averagePricePerNight": null, "hasIncalculableCharges": false, "taxExceptions": [], "rewardsBenefits": [], "extras": null },
"badges": [ { "text": "Late Escape Deal", "style": "constructive", "name": "Late Escape Campaign" } ],
"labels": [], "mealPlan": null, "freeCancellation": false, "noPrepayment": false, "roomSummary": null, "units": { "commonConfiguration": { "beds": [ { "count": 3 } ], "nbUnits": 3 } },
"rooms": [ { "roomId": 110672904, "mealPlanId": 0, "occupancy": 2, "packageId": "0", "policyGroupId": "91476666", "price": { "amount": 11449.52, "currencyCode": "INR" }, "originalPrice": { "amount": 120.58, "currencyCode": "USD" }, "freeCancellationUntil": null, "onlyXLeft": null, "surfaceSize": 8 } ],
"soldOut": { "isSoldOut": false, "messages": [] }, "genius": null,
"checkInTime": { "from": "15:00", "until": null }, "checkOutTime": { "from": null, "until": "11:00" },
"imageUrl": ".../square200/204079362.jpg?k=…&o=", "mainPhotoId": 204079362, "images": { "thumbnail": "...", "medium": "...", "large": "..." }, "extras": { "bundleRatesAvailable": true, "visibilityBoosterEnabled": true } }
],
"sortOptions": [ { "name": "popularity", "caption": "Top picks for families", "selected": true, "tooltip": null } ],
"filterGroups": [ { "field": "class", "title": "Property rating" } ],
"appliedFilters": [], "recommendedFilters": [],
"Booking.com": { "appSearchMetaData": "last_x_property_ids=...,hotels_cc1=us,search_id=..." }
}
}
| Case | status |
message |
|---|---|---|
| At least one property | true |
Properties found |
| Nothing in the area / for the search (a box over the sea, a month without the weekday, ...) | false |
No properties found for this search |
| Booking.com down / HTTP error | false |
Stays map search provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
search.mode |
fixed, plusMinusDays or flexibleMonths. search.destination or search.boundingBox says which location form was used; checkin/checkout are null in the months mode, where search.flexible and search.nights describe the request. search.firstWindow is the first matching window of a flexible search (not what the properties show). |
pagination |
page, limit, offset, count; hasNextPage is true when the page was full (there is no total number). |
map.boundingBoxes[] |
The area Booking.com used (type SMART_AV is the area that holds the results). |
properties[].id, name, position, accommodationTypeId |
Property id (the hotelId of every property endpoint), name, rank (continues across pages) and Booking.com's type id (203 hotel, 204 apartment, 216, 201, 219 seen). |
starRating, qualityRating |
Stars (1 to 5) or, for properties with a quality tile rating instead, that rating; null when not given. |
isPreferred, isPreferredPlus, isSponsored, sponsored |
Booking.com's partner marks, and a paid placement (sponsored: nativeAdId, costPerClick, showsAdLabel, legalEntityName, designType). |
review |
score, label (translated word) and count; null without reviews. |
location |
latitude, longitude, address, city, countryCode, cityId (use it as city:<id> in review-score-comparison), area and distanceFromCenterText ("350 m from centre"), distanceFromSearchPointKm (from the centre of the destination or of the map area), distanceText, locationScore / locationScoreLabel (the guests' location score), ski fields when the property is at a lift. |
stay |
The dates price is for: checkin, checkout, nights. isOwnWindow is true when it is the property's own cheapest window (flexible modes) and false when it is the searched range. |
price |
The same fields as a search price: amount, formatted, taxesIncluded, taxesAndFees, totalAmount, chargesInfo, originalAmount / discountPercent; plus averagePricePerNight, hasIncalculableCharges, taxExceptions, rewardsBenefits. The price is for the whole stay and all rooms. extras holds wallet or reward amounts when Booking.com fills them (none were seen). |
badges, labels |
Deal badges (text, style, name) and other card labels (text, style, e.g. a sustainability ribbon). |
mealPlan, freeCancellation, noPrepayment |
Included meal plan (type, text), and whether the card shows free cancellation / no prepayment. |
roomSummary, units |
The recommended room as text and as numbers (commonConfiguration: beds, bedrooms, bathrooms, area, unitConfigurations). |
rooms[] |
The offers behind the price: roomId (the roomId of /stays/rooms), mealPlanId, occupancy, packageId, policyGroupId, price and originalPrice (note: Booking.com gives originalPrice in the property's own currency, not in currencyCode), freeCancellationUntil, onlyXLeft ("We have 3 left"), surfaceSize. |
soldOut, genius |
Sold-out flag with its messages; Genius benefits (geniusBenefits, geniusBenefitsData, showGeniusRateBadge). |
checkInTime, checkOutTime |
The windows as 24 h text, null where not limited. |
imageUrl, images, mainPhotoId |
Main photo (200 px square) and the same three sizes as in search. All photos: /stays/photo-list. |
sortOptions[], filterGroups[] |
The sort menu (name is what sortBy takes as a Booking.com key) and the filter groups of this search; the full filter list with counts is /stays/search-filters. |
extras |
Booking.com fields without a named field here (wallet credit, bundle rates, external reviews ...); null when none. |
7. Stays Search Filters (dynamic, live counts)
What it does. The live, per-search filter list with real counts — what the app's "Filter by" screen shows (e.g. "Pets allowed (41)"). Counts, and which filters are even offered, depend on the destination, dates, guests, and whatever filters are already applied. This is also the only way to discover which key::value pairs /stays/search's own filters parameter accepts — call this endpoint with no filters applied.
Where the inputs come from. The same destination, dates and guests you send to GET /stays/search (the destination comes from autocomplete or suggestions). Call it to build the filter menu, then pass the chosen filter strings to the search.
Request
GET /api/v1/stays/search-filters?destination=city:-2092174&checkin=2026-12-01&checkout=2026-12-02&filters=class::5
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
Same auth, subscription and quota as /stays/search (one call = one request).
| Parameter | Required | Rule |
|---|---|---|
destination |
yes | Same single-token format as /stays/search's own destination, except a latlong:... map-point token is not supported (rejected by validation, not by Booking.com — there's no coordinate form in this call's schema). type is not checked against a fixed list; an unmapped one falls back to a plain uppercase for Booking.com's destType enum (e.g. region → REGION), which matches every type confirmed so far. |
checkin, checkout |
yes | Same rules as /stays/search (not in the past, at most 500 days ahead, stay at most 90 nights). |
adults, rooms, childrenAges, pets |
no | Same as /stays/search. |
filters |
no, default none | Filters already applied, same key::value format and validation as /stays/search's own filters (see stays-search.md §4 for the known keys). Call once with this empty for the full list; call again with the caller's current picks to get the next, narrowed list. |
currencyCode, languageCode |
no | Same as /stays/search. currencyCode controls the price filter's currency. |
No page — this isn't paginated.
What you get back
{
"status": true,
"message": "Filters found",
"data": {
"destination": { "id": -2092174, "countryCode": "in", "name": "Mumbai" },
"totalResults": 1386,
"totalResultsExactDates": 1109,
"nights": 1,
"quickFilters": {
"popular": [ { "id": "class::5", "label": "5 stars", "count": 60 } ],
"yourPreviousFilters": [ { "id": "facility::4", "label": "Pets allowed", "count": 125 } ]
},
"families": [
{
"field": "class",
"title": "Property rating",
"subtitle": "Find high-quality hotels and holiday rentals",
"style": "checkbox",
"options": [
{ "id": "class::0", "label": "Unrated", "count": 336, "selected": false, "extras": null },
{ "id": "class::5", "label": "5 stars", "count": 60, "selected": true, "extras": null }
],
"collapsed": false,
"extras": null
},
{
"field": "price",
"title": "Your budget (for 1 night)",
"style": "slider",
"options": [],
"priceRange": { "min": 10000, "max": 400000, "step": 10000, "currency": "INR", "histogram": [ 42, 57, 57, "…50 buckets" ], "selectedMin": null, "selectedMax": null }
},
{
"field": "unit_config_grouped",
"style": "stepper",
"options": [ "…25 raw options, superseded by steppers below" ],
"steppers": [
{ "field": "entire_place_bedroom_count", "title": "Bedrooms", "min": 0, "max": 5, "default": 0, "selected": 0, "labels": [] },
{ "field": "num_beds", "title": "Beds", "min": 0, "max": 5, "default": 0, "selected": 0, "labels": [ "0 or more beds", "1 or more beds", "…" ] },
{ "field": "min_bathrooms", "title": "Bathrooms", "min": 0, "max": 15, "default": 0, "selected": 0, "labels": [ "0 or more bathrooms", "…" ] }
...
| Case | status |
message |
|---|---|---|
| At least one filter family | true |
Filters found |
| None (shouldn't normally happen) | false |
No filters available for this search |
latlong / bad filters value |
false |
Validation failed (no Booking.com call made) |
| Booking.com unavailable or returned an error | false |
Stays filters provider is unreachable / …provider error: <message> |
Fields
| Field | Meaning |
|---|---|
totalResults |
Matches /stays/search's pagination.totalResults for the same query. |
totalResultsExactDates |
Booking.com's own totalAvailableNotAutoextended — results for exactly these dates, before any nearby-date widening. Usually smaller than totalResults. |
quickFilters.popular, .yourPreviousFilters |
Shortcuts the app shows at the top. Not separate filters — every id here also appears inside families (checked on a real response); these just point at the same ids with a label and count, for a "quick pick" row. |
families[].field |
Booking.com's internal filter key (e.g. class, hotelfacility, di for neighbourhood). Doesn't always match the static catalog's family names 1:1 (e.g. "Family friendly" here is stay_type::3, not family_friendly_property::1 from the static list) — both are presumably valid; this dynamic data is the authoritative one per search. |
families[].style |
checkbox (pick one or more options), slider (use priceRange), stepper (use steppers), autocomplete_dropdown (free-text location search — see location). |
options[].id |
Feed straight into /stays/search's or this endpoint's own filters parameter. |
options[].count |
How many properties would match if this option were applied (on top of whatever's already applied) — recalculated per option, independently of its siblings; two unselected options in the same family do not need their counts to sum to anything in particular. |
options[].selected |
true for options in the caller's own filters. |
priceRange.histogram |
~50 buckets across min–max, for drawing the same bar chart the app shows under the price slider. |
steppers |
One entry per "at least N" control (bedrooms/beds/bathrooms); labels[i] is the display text for stepper value i, when Booking.com sends them (it didn't for bedrooms in the sample). |
smartFilters |
Display text only for the free-text "Smart filters" box. Booking.com's own extractedEntities (what a typed query would turn into) is always empty here: searching with typed text is not available, so this is informational only. |
Dropped as pure telemetry: service's own __typename tags, and Booking.com's trackOnClick/trackOnView/trackOnSelectPopular/etc. A/B-test fields — present on every single filter and option, confirmed empty of real data after stripping (checked on a live response: zero non-telemetry leftovers anywhere). The cleaned response is about 21 KB against Booking.com's ~165 KB.
8. Stays Search Sort Options (dynamic)
What it does. The live, per-search sort option list — what builds the app's "Sort by" screen. Also the one way to discover every valid sortBy value for /stays/search.
Where the inputs come from. The same destination, dates and guests you send to GET /stays/search. Call it to build the sort menu, then pass the chosen value as sortBy.
Request
GET /api/v1/stays/search-sort-options?destination=city:-2092174&checkin=2026-12-01&checkout=2026-12-02
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
Exactly the same required/optional parameters as /stays/search-filters — same Booking.com request shape, so the same schema is reused server-side. No page, latlong not supported.
What you get back
{
"status": true,
"message": "Sort options found",
"data": {
"options": [
{ "value": "homesAndApartmentsFirst", "label": "Entire homes & apartments first", "selected": false, "providerValue": "upsort_bh" },
{ "value": "popularity", "label": "Our top picks", "selected": true, "providerValue": "popularity" },
{ "value": "distance", "label": "Near city centre first", "selected": false, "providerValue": "distance" },
{ "value": null, "label": "Distance from closest beach", "selected": false, "providerValue": "closest_beach_distance" },
{ "value": "classDescending", "label": "Property rating (5 to 0)", "selected": false, "providerValue": "class_descending" },
{ "value": "classAscending", "label": "Property rating (0 to 5)", "selected": false, "providerValue": "class_ascending" },
{ "value": "reviewScore", "label": "Best reviewed first", "selected": false, "providerValue": "bayesian_review_score" },
{ "value": "price", "label": "Price (lowest first)", "selected": false, "providerValue": "price" },
{ "value": "priceDescending", "label": "Price (highest first)", "selected": false, "providerValue": "price_from_high_to_low" }
]
}
}
| Field | Meaning |
|---|---|
options[].value |
What to pass to /stays/search's sortBy. null when Booking.com has an option we haven't mapped into STAYS_SORT yet — still listed (with providerValue and label), not silently dropped, so a new Booking.com option is visible here immediately even before we've wired a friendly name for it. |
options[].label |
The exact UI caption, in the requested languageCode. |
options[].selected |
Matches whatever sortBy (or its default) was passed in this call — not independently meaningful beyond confirming the request was understood. |
options[].providerValue |
Booking.com's own raw sort key, e.g. upsort_bh. |
9. Stays Property Details (the stay detail page)
What it does. Everything the app shows on a hotel's page for the dates and guests you choose: the name, type, address and coordinates, the facilities, every room (description, size, beds, facilities, photos, child and bed rules) and every rate you could book (price breakdown with taxes and charges, cancellation and prepayment terms, meal plan, how many are left), plus the important information and, for homes, the host.
Where the inputs come from. Pick a property from GET /stays/search, pass its id as hotelId together with the same dates and guests. It is the "whole detail page in one call" of Part 3 in the journey overview. The other property endpoints each keep their own job: facilities and Q&A ids are in /stays/property-facilities, photos have their own endpoint (/stays/photos); reviews, scores and policies are in /stays/review-scores, /stays/reviews and /stays/policies. Every room type and every rate (not only the recommended ones) is in /stays/rooms; the IDs are explained in ids.md. Attractions near the property are in /stays/things-to-do: pass latlong:<location.latitude>,<location.longitude> or city:<location.destinationId> from this response as its destination.
Request
GET /api/v1/stays/property-details?hotelId=237786&checkin=2026-12-01&checkout=2026-12-03&adults=4&rooms=2&childrenAges=0,3¤cyCode=USD
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
checkin, checkout |
no, both or neither. Left out: tomorrow and the day after, and availability.datesAreDefault is true |
YYYY-MM-DD, same rules as search (not in the past, 1–90 nights, within the booking window). Send them if you want the rooms, rates, prices or availability (see "Dates" below). Only one of the two is rejected. |
adults |
no, default 2 | 1–30. |
rooms |
no, default 1 | 1–30, not more than adults. |
childrenAges |
no | Comma-separated ages, 0 = under 1 year, e.g. 0,3. |
currencyCode |
no, default USD |
A code from /common/currencies. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the room and rate names, meal plan, cancellation labels, facility names, property type and country (tested: de, fr, ja fully; hi partly). The property name and the room description text are Booking.com's own text and are not translated. |
Dates: what depends on them
Booking.com itself requires dates for this call, so when you send none we use tomorrow and the day after and say so with availability.datesAreDefault: true. Tested on three hotels with several dates:
| Part of the response | Depends on the dates? |
|---|---|
property (name, type, flags, host), location, policies |
No: identical on every date. |
reviews, facilityOverview |
Practically no (a breakfast score and a few "free facility" ids moved on 2 of 3 hotels). |
availability, pricing, recommendation, rooms[], rates[] |
Yes, completely. Hotel 6966158 had 0 rooms and 0 rates for tomorrow (sold out) and 1 room and 1 rate, at different prices, on later dates. |
So: if you only want to show what the property is, the dates can be left out. If you want what it costs or whether it is available, send checkin and checkout, and check availability.datesAreDefault before you trust "sold out". For the list of every room type with sold-out ones marked use /stays/room-types, for every rate /stays/rooms (both require dates). All endpoints and their date rules: dates-and-guests.md.
What you get back
{
"status": true,
"message": "Property page found",
"data": {
"hotelId": 237786,
"property": { "id": 237786, "name": "InterContinental Marine Drive Mumbai, an IHG Hotel", "accommodationType": "Hotels", "accommodationTypeId": 204, "url": "https://www.booking.com/hotel/in/...", "defaultLanguage": "en-gb", "timezone": "Asia/Kolkata", "isPreferred": true, "isPreferredPlus": false, "isClosed": false, "chains": [ "..." ], "...": "..." },
"location": { "fullAddress": "...", "street": "...", "city": "Mumbai", "district": "...", "zip": "...", "country": "India", "countryCode": "in", "latitude": 18.93, "longitude": 72.82, "distanceToCityCentreKm": 4.1, "isCityCentre": false, "destinationId": -2092174, "districtIds": [ 1 ] },
"reviews": { "reviewCount": 529, "breakfast": { "rating": 0, "reviewCount": 0, "...": "..." }, "wifi": { "rating": 9.4 } },
"facilities": { "facilityIds": [ 3, 4, 5 ], "popular": { "name": "Most popular facilities", "type": "popular", "facilities": [ { "name": "Free WiFi", "icon": "wifi" } ] }, "topBenefits": [ "..." ], "highlights": [ "..." ], "family": [ "Family rooms" ], "languagesSpoken": [ "en-gb", "hi" ], "roomsSummary": { "hasRefundable": true, "hasNonrefundable": false, "hasKitchen": false, "hasSeating": false, "commonKitchenFac": [] } },
"availability": { "checkin": "2026-12-01", "checkout": "2026-12-03", "datesAreDefault": false, "requestedCurrencyCode": "USD", "propertyCurrencyCode": "INR", "soldOut": false, "availableRooms": 3, "totalRates": 28, "rateCount": 2, "urgencyRoomText": "2 x Classic King Room with Bay View", "scarcityMessages": { "roomPage": [ { "id": "23778639_95438172_1_2_0", "value": "We have 6 left" } ], "...": "..." }, "stayLengthLimits": { "maxAllowedLos": 90, "defaultLos": 45, "extendedLos": 90, "...": "..." }, "maxRoomsPerBooking": 6, "cantBook": false },
"pricing": { "priceBreakdown": { "grossAmount": { "value": 0, "currency": "USD", "amountRounded": "US$0" }, "allInclusiveAmount": { "...": "..." }, "includedTaxesAndChargesAmount": { "...": "..." }, "chargesDetails": { "...": "..." }, "items": [ "..." ], "...": "..." }, "transparencyMode": "transparent", "isPriceTransparent": false, "averageRoomSizeM2": 40.1 },
"policies": { "importantInformation": [ { "sentenceId": 3, "phrase": "...", "executingPhase": 0 } ], "paymentDetail": { "model": "hybrid2.0" }, "creditCardRequired": true, "cvcRequired": true, "...": "..." },
"recommendation": { "title": "Enjoy some extra space with 3 rooms for 4 adults, 2 children (< 1 and 3 years old)", "guestsPerRoom": { "adults": 2, "children": [ 3 ] }, "childrenStayFree": [ { "blockId": "23778639_95438172_1_2_0", "title": "Free stay for both of your children", "content": "Your children (<1 and 3 years old) can sleep here for no additional charge.", "class": "CHILD_STAYS_FREE" } ], "rooms": [ "..." ] },
"roomCount": 2,
"rooms": [
{ "id": "23778621", "description": "...", "facilities": [ { "id": 74, "name": "Laptop safe", "facilitytypeId": 8, "altFacilitytypeId": 12, "altFacilitytypeName": "Kitchen" } ], "bedConfigurations": [ { "bedTypes": [ { "name": "Double bed", "count": 1, "description": "131-150 cm wide" } ] } ], "highlights": [ { "translatedName": "Free WiFi", "icon": "wifi" } ], "photos": [ { "photoId": 1, "urlSquare60": "...", "urlMax750": "...", "urlMax1280": "...", "ratio": 1.5 } ], "childrenAndBedsText": { "allowChildren": true, "childrenAtTheProperty": [ "..." ], "cribsAndExtraBeds": [ "..." ], "ageIntervals": [ ] }, "privateBathroomCount": 1 }
],
"rateCount": 2,
"rates": [
{ "blockId": "23778621_95438172_2_2_0", "roomId": 23778621, "name": "Classic King Room - Free cancellation", "roomName": "Classic King Room", "mealplan": "Breakfast ...", "breakfastIncluded": false, "refundable": true, "refundableUntil": "2026-11-30 23:59:59 -0400", "maxOccupancy": "2", "nrAdults": 2, "nrChildren": 0, "roomSurfaceInM2": 33, "productPriceBreakdown": { "grossAmount": { "value": 0, "currency": "USD", "amountRounded": "US$0" }, "items": [ "..." ], "chargesDetails": { "...": "..." }, "...": "..." }, "paymentterms": { "cancellation": { "type": "free_cancellation", "description": "...", "info": { "dateBefore": "...", "refundable": true } }, "prepayment": { "type": "no_prepayment", "description": "..." } }, "blockText": { "policies": [ { "class": "POLICY_CANCELLATION", "content": "..." } ] }, "...": "..." }
],
"extras": { "pageviewId": "...", "...": "..." }
}
}
(Heavily shortened - a real response is 50–60 KB for a property with availability. Field values above are illustrative; the field names are exact.)
| Case | status |
message |
|---|---|---|
| Property found (even if sold out for the dates) | true |
Property details found (check availability.soldOut; rooms and rates are empty when sold out) |
Unknown hotelId / empty reply |
false |
No property details found for this property |
| Booking.com unavailable | false |
Stays property page provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Groups
| Group | What it holds |
|---|---|
property |
id, name, translatedName, accommodationType/accommodationTypeId, url, defaultLanguage, timezone, status flags (isPreferred, isPreferredPlus, isExclusive, isGeniusDeal, isFamilyFriendly, isClosed, ...), chains, and for homes bookingHome, hostProfile, hostName, hostScore, hostSince, requestToBookRequired. |
location |
fullAddress, street, city, district, zip, country, countryCode, latitude, longitude, distanceToCityCentreKm, isCityCentre, destinationId (Booking.com's id for the city), districtIds, wishlistDestination. |
reviews |
reviewCount, and the breakfast and wifi review scores. The overall and category scores are in /stays/review-scores. |
facilityOverview |
facilityIds (sorted ids; names are in /stays/property-details), popular, topBenefits, highlights, family, languagesSpoken, roomsSummary. |
availability |
checkin, checkout, datesAreDefault (true when you sent no dates and tomorrow / the day after were used: the rooms, rates, prices and availability are then for that one night only), requestedCurrencyCode (the currency of every price), propertyCurrencyCode (what the property itself charges in), soldOut, soldOutMessage, availableRooms, totalRates, rateCount, urgencyRoomText, scarcityMessages (the "We have 2 left" texts, as lists), stayLengthLimits, maxRoomsPerBooking, cantBook. |
pricing |
priceBreakdown (gross, net, all-inclusive, taxes and charges, items, benefits) for the recommended rooms, transparencyMode, averageRoomSizeM2. |
policies |
importantInformation[], paymentDetail, creditCardRequired, cvcRequired, zipRequired, addressRequired, isCashAcceptedCheckEnabled, lastReservation, displayDetails. |
recommendation |
What the app suggests for the guests searched: title, rooms[] (extra beds and cots with prices), guestsPerRoom, childrenStayFree[]. |
rooms[] |
One per room type: id, description, bedConfigurations, facilities, highlights, photos (several sizes), childrenAndBedsText (the same shape as /stays/policies), privateBathroomCount, apartmentConfiguration for homes. |
rates[] |
One per bookable rate: blockId, roomId (matches rooms[].id), name, mealplan, refundable, refundableUntil, occupancy (nrAdults, nrChildren, maxOccupancy), productPriceBreakdown, paymentterms (cancellation and prepayment, with a timeline when available), blockText.policies[], flags (breakfastIncluded, halfBoard, fullBoard, allInclusive, ...). |
extras |
Booking.com fields not placed above (tracking ids and internal flags such as pageviewId, rbTrackerId); null when none. |
Booleans (true/false) replace Booking.com's 0/1; empty strings are null; nothing else is removed or renamed beyond snake_case → camelCase.
10. Stays Description
What it does. The text of a property: the "About this property" description and the check-in rules / important information, in any language. It is what GET /stays/property-details leaves empty (its hotel_text). - See also: GET /stays/description-sections has the sectioned overview (Prime Location, Dining Options ...) that this text does not.
Where the inputs come from. Part 3 (About the property) in the journey overview. Pick a property from GET /stays/search and pass its id as hotelId. The fine print as structured fields (legal and trader details, licences) is in GET /stays/important-info.
Request
GET /api/v1/stays/description?hotelId=6966158&languageCode=en-us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the text. |
What you get back
{
"status": true,
"message": "Description found",
"data": {
"hotelId": 6966158,
"description": "Stay in the heart of New York.\nRiu Plaza Manhattan Times Square has a fitness centre, terrace, a restaurant and bar in New York. ...",
"importantInformation": "Guests are required to show a photo identification and credit card upon check-in. ...",
"count": 2,
"descriptions": [
{ "typeId": 6, "type": "description", "languageCode": "en", "text": "Stay in the heart of New York.\n...", "extraLines": null, "extras": null },
{ "typeId": 7, "type": "importantInformation", "languageCode": "en", "text": "Guests are required to show a photo identification ...", "extraLines": { "importantInfo": "In the event of an early departure, the property will charge you the full amount for your stay.\n\n...", "extras": null }, "extras": null }
]
}
}
| Case | status |
message |
|---|---|---|
| At least one text | true |
Description found |
| Unknown property | false |
No description found for this property |
| Booking.com down / error | false |
Stays description provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
description |
The property description (type 6); null if missing. |
importantInformation |
The check-in rules and fine print (type 7); null if missing. |
descriptions[].typeId, type |
Booking.com's id and our name: 6 = description, 7 = importantInformation; any other id has type: null. |
descriptions[].languageCode |
The language of the text actually returned. |
descriptions[].text |
The text, with \n line breaks. |
descriptions[].extraLines |
{ importantInfo }, a longer important-information text, on the type 7 block of about half the properties; otherwise null. |
descriptions[].extras |
Anything Booking.com adds that is not mapped yet; null so far. |
11. Stays Description Sections
What it does. The property's description in the language you ask for, plus Booking.com's sectioned overview of the property: a short text with headings such as Prime Location, Comfortable Accommodations, Dining Options, Convenient Services and Nearby Attractions, already split into {title, text}.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId. See the journey overview.
Request
GET /api/v1/stays/description-sections?hotelId=6966158
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no, default en-us |
A code from /common/languages. Translates description; the overview stays English. |
What you get back
{
"status": true,
"message": "Description found",
"data": {
"description": "Riu Plaza Manhattan Times Square has a fitness centre, terrace, a restaurant and bar in New York. ...",
"markupDescription": "<h2>Prime Location</h2>\n\nRiu Plaza Manhattan Times Square in New York City offers a central location ...",
"hasOverview": true,
"sections": [
{ "title": "Prime Location", "text": "Riu Plaza Manhattan Times Square in New York City offers a central location with Radio City Music Hall a 7-minute walk away, ..." },
{ "title": "Comfortable Accommodations", "text": "Rooms feature air-conditioning, private bathrooms, free WiFi, ..." },
{ "title": "Dining Options", "text": "The family-friendly restaurant serves American cuisine with vegetarian and gluten-free options. ..." }
]
}
}
| Case | status |
message |
|---|---|---|
| The property has a description | true |
Description found (hasOverview false and sections [] when it has no overview) |
hotelId doesn't resolve |
false |
Stays description sections provider error: … |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
description |
The property's description text in languageCode. |
markupDescription |
The sectioned overview as Booking.com sends it (HTML with <h2> headings), English; null when the property has none. |
hasOverview |
true when markupDescription exists. |
sections[] |
The overview split at its headings: title and text. |
12. Stays Highlights (feature badges only)
What it does. The feature badges at the top of a property's page (this is only a summary strip, not the full detail - see the property endpoints linked below): "Pet friendly", "Breakfast", "Parking", "Wellness", "Accessibility", and so on, each with the specific facilities behind it (e.g. "Pet friendly" → "Pets welcome", "Charges may apply").
Where the inputs come from. Call GET /stays/search first; each item in its data.properties[] is a hotel. Take that hotel's own id and pass it here as hotelId — this is only the short badge strip at the top of a property page, NOT the full detail. For the rest of the property page see GET /stays/photos (all photos), GET /stays/important-info (fine print, legal) and GET /stays/property-details — same hotelId. For every photo of the property, see GET /stays/photos.
Request
GET /api/v1/stays/highlights?hotelId=59304
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
Same auth, subscription and quota as /stays/search (one call = one request).
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id — copy it from a GET /stays/search result's data.properties[].id. |
languageCode |
no | Same as /stays/search, default en-us. Controls the category/facility names. |
Deliberately not accepted here, unlike every other search-family endpoint: checkin, checkout, adults, rooms, childrenAges, currencyCode. All six were tested live and measured to have zero effect on this specific response — accepting-but-ignoring them would be misleading, so they are left out of the schema entirely rather than kept as optional no-ops.
What you get back
{
"status": true,
"message": "Highlights found",
"data": {
"categoryCount": 5,
"categories": [
{
"id": 11,
"icon": "food_coffee",
"name": "Breakfast",
"facilities": [
{ "id": 4000, "name": "Good breakfast", "extras": null }
],
"extras": null
},
{
"id": 12,
"icon": "pawprint",
"name": "Pet friendly",
"facilities": [
{ "id": 5000, "name": "Pets welcome", "extras": null },
{ "id": 5001, "name": "Charges may apply", "extras": null }
],
"extras": null
},
{
"id": 9,
"icon": "parking_sign",
"name": "Parking",
"facilities": [
{ "id": 2000, "name": "Private", "extras": null },
{ "id": 2001, "name": "Parking garage", "extras": null }
],
"extras": null
},
{
"id": 4,
"icon": "spa",
"name": "Wellness",
"facilities": [
...
| Case | status |
message |
|---|---|---|
| At least one highlight category | true |
Highlights found |
Property has none, or hotelId doesn't resolve without a service error |
false |
No highlights found |
hotelId doesn't resolve to a real property (service errors, ) |
false |
Stays property highlights provider error: Internal Server Error |
| Booking.com unavailable | false |
Stays property highlights provider is unreachable / …returned HTTP <n> |
Validation failure (missing hotelId, only one of checkin/checkout given, etc.) |
false |
Validation failed (+ errors[]) |
| Auth / quota problems | false |
the auth/quota message |
Fields
| Field | Meaning |
|---|---|
categoryCount |
Number of highlight categories returned. |
categories[].id |
Booking.com's own category id (stable across properties — 11 is always "Breakfast", 12 is always "Pet friendly", etc.). |
categories[].icon |
Booking.com's icon name, e.g. food_coffee, pawprint, parking_sign, spa, door_open. No icon asset is served — this is just the name, same convention as other stays endpoints that pass icon names through. |
categories[].name |
Display title, in the requested languageCode, e.g. Breakfast, Pet friendly. |
categories[].facilities[] |
The specific facilities behind this category, each with its own Booking.com id and name (e.g. Pets welcome, Charges may apply). |
extras |
Anything Booking.com sends on a category or facility that we don't map, so no data is silently lost; null when nothing extra. Only service's own __typename tags are dropped unconditionally. |
13. Stays Badges
What it does. The sustainability certifications of a property (Green Key, GSTC, LEED ...) and whether it carries the "Travel Proud" mark (Booking.com's LGBTQ+ welcoming programme).
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId. See the journey overview.
Request
GET /api/v1/stays/badges?hotelId=1150083
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no, default en-us |
A code from /common/languages. |
What you get back
Field names are Booking.com's own, under data.propertyDetails.
{
"status": true,
"message": "Badges found",
"data": {
"propertyDetails": {
"propertySustainability": {
"isSustainable": true,
"certifications": [
{ "name": "Green Key Global Eco-Rating", "logoUrl": "https://q-xx.bstatic.com/xdata/images/xphoto/max2048/336195245.webp?k=...", "issuerDetails": [ { "name": "company_name_1", "value": "Control Union" } ] }
]
},
"travelProud": { "isTravelProud": true }
}
}
}
| Case | status |
message |
|---|---|---|
| The property resolves | true |
Badges found (isSustainable false and certifications [] when it has none) |
hotelId doesn't resolve |
false |
Stays badges provider error: … |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
propertySustainability.isSustainable |
Whether Booking.com shows the property as sustainable. |
propertySustainability.certifications[] |
name, logoUrl (the certificate's logo) and issuerDetails[] (name = a label key, value = the issuing company; usually empty). |
travelProud.isTravelProud |
Whether the property has the Travel Proud mark. |
14. Stays House Rules
What it does. The check-in and check-out time windows of one property and its accepted payment methods (the credit cards it takes), as the app's "House rules" block shows them.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as the other property endpoints. See the journey overview.
Request
GET /api/v1/stays/house-rules?hotelId=1150083
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no, default en-us |
A code from /common/languages. Only the *Formatted times change with it (en-us: 12-hour). |
What you get back
Field names are Booking.com's own, under data.houseRules.
{
"status": true,
"message": "House rules found",
"data": {
"houseRules": {
"checkinCheckoutTimes": {
"checkinTimeRange": { "from": "15:00", "fromFormatted": "3:00 PM", "until": null, "untilFormatted": null },
"checkoutTimeRange": { "from": null, "fromFormatted": null, "until": "12:00", "untilFormatted": "12:00 PM" }
},
"paymentMethods": {
"acceptedCreditCards": [
{ "id": 1, "name": "American Express", "nameEn": "American Express" },
{ "id": 2, "name": "Visa", "nameEn": "Visa" },
{ "id": 3, "name": "Mastercard", "nameEn": "Euro/Mastercard" }
],
"isExclusive": false,
"isPropertyBookingManagedPayAtProperty": false
}
}
}
}
| Case | status |
message |
|---|---|---|
| The property resolves | true |
House rules found |
hotelId doesn't resolve |
false |
Stays house rules provider error: Internal Server Error |
| Booking.com down / HTTP error | false |
Stays house rules provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
checkinCheckoutTimes.checkinTimeRange, checkoutTimeRange |
The window: from and until as 24-hour "HH:MM", and fromFormatted / untilFormatted as the app shows them (en-us: 3:00 PM). A side that is not limited is null; 00:00 also means no limit. |
paymentMethods.acceptedCreditCards[] |
The cards the property accepts: id, name (as shown), nameEn (English name, e.g. Euro/Mastercard for the card shown as Mastercard). Empty for some properties. |
paymentMethods.isExclusive |
true on the properties tested that list no cards (payment is by another method); false otherwise. |
paymentMethods.isPropertyBookingManagedPayAtProperty |
Whether Booking.com manages the payment made at the property. |
IDs: a card id (1 American Express, 2 Visa, 3 Mastercard, 5 Diners Club, 7 JCB, 11 Discover, 44 UnionPay credit card) has no separate lookup; the name is in the same object. See ids.md.
15. Stays Important Info
What it does. The "Important information" part of a property page: fine print (deposit, ID at check-in, charges), the property's own extra notes, who legally runs the property (trader / company details), licence numbers, and the Polish consumer-authority text where it applies.
Where the inputs come from. Call GET /stays/search first; take a property's id and pass it here as hotelId, same as GET /stays/highlights, GET /stays/photos and GET /stays/property-details, GET /stays/review-filters, GET /stays/policies. See the journey overview for the full order.
Request
GET /api/v1/stays/important-info?hotelId=183564
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no | Default en-us. Translates finePrints only. |
What you get back
{
"status": true,
"message": "Important info found",
"data": {
"propertyDetails": {
"propertyGallery": {
"main": { "id": 753139154, "altText": "a building with flags in front of it at ...", "square60": { "absoluteUrl": "https://cf.bstatic.com/xdata/images/hotel/square60/753139154.jpg?k=..." } },
"all": [ { "id": 753139154, "altText": "...", "square60": { "absoluteUrl": "..." } } ]
},
"finePrints": [
"Guests are required to show a photo identification and credit card upon check-in. ...",
"A damage deposit of US$250 is required on arrival. ..."
],
"translation": { "finePrint": null },
"legalInfo": {
"traderInfo": {
"isTrader": true,
"legalEntityId": 186337,
"contactDetails": {
"address": { "addressLine1": "333 Ludlow Street", "addressLine2": "3rd Floor South Tower", "countryCode": "us", "city": "Stamford", "state": "CT", "postalCode": "06902" },
"registrationNumber": "26-3069031",
"tradeRegisterName": "Shared Mutual Services LLC Club Quarters",
"companyLegalName": "Shared Mutual Services LLC",
"firstName": null, "middleName": null, "lastName": null,
"email": "crs@clubquarters.com",
"phoneNumber": "+12039052083",
"regulatorySubjectType": "BUSINESS"
}
}
},
"licenseData": { "numbers": [], "phrases": [] },
"uokikSplitOfObligations": null
}
}
}
| Case | status |
message |
|---|---|---|
| Property resolves | true |
Important info found |
| Property block missing without a service error | false |
No important info found |
hotelId doesn't resolve (service errors, ) |
false |
Stays important info provider error: Internal Server Error |
| Booking.com unavailable | false |
Stays important info provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
propertyDetails.propertyGallery |
main (the cover photo) and all[] (the gallery, up to 100): id, altText, square60.absoluteUrl. Full-size images, tags and room photos: GET /stays/photos. |
propertyDetails.finePrints[] |
The important-information lines (ID/credit card at check-in, deposits, early-departure charges), in languageCode. |
propertyDetails.translation.finePrint |
The property's own longer free-text note (smoking policy, parking fees), exactly as it wrote it, never translated. null when none. |
propertyDetails.legalInfo.traderInfo |
Who legally operates the property: isTrader, legalEntityId, and contactDetails (companyLegalName, tradeRegisterName, registrationNumber, regulatorySubjectType, name parts, email, phoneNumber, address{addressLine1, addressLine2, city, state, postalCode, countryCode}). |
propertyDetails.licenseData |
numbers[] and phrases[] of local licence/registration info. |
propertyDetails.uokikSplitOfObligations |
Polish UOKiK text on who owes the guest what: title, body, serviceProviderObligations, bookingObligations (each {header, points[]}). null for most properties. |
16. Stays Policies
What it does. A property's house rules: whether children are allowed and what cots / extra beds cost by age, group-booking rules, internet, parking, pets, the minimum check-in age, curfew, and the "Booking.com takes your payment" note.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as /stays/highlights, /photos, /property-details, /important-info, /review-filters and /reviews. See the journey overview.
Request
GET /api/v1/stays/policies?hotelId=59304
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no | Default en-us. A code from /common/languages. |
What you get back
{
"status": true,
"message": "Policies found",
"data": {
"hotelId": 59304,
"policyGroups": [
{
"id": 246420356,
"typeId": 1,
"name": "General",
"hotelId": 59304,
"policyCount": 6,
"policies": [
{
"type": "POLICY_CHILDREN",
"key": "children",
"id": 1234567891,
"content": [
{
"text": "Children of any age are allowed.\n1 child (up to and including 2 years old) stays for free when using available cots.\t\n...",
"languageCode": "en-gb",
"allowChildren": true,
"childrenAtTheProperty": [ { "text": "Children of any age are welcome.", "highlight": false } ],
"cribsAndExtraBeds": [ { "text": "Supplements are not calculated automatically in the total costs ...", "highlight": false } ],
"ageIntervals": [
{ "minAge": 0, "maxAge": 2, "crib": { "id": 57224089, "price": 0, "priceType": "free", "priceMode": "per_stay", "priceTypeN": 0, "priceModeN": 1, "guaranteed": false }, "typesByPrice": [["crib"], ["existing_bed"]], "groupByPrice": [ { "priceType": "free", "priceMode": "per_stay", "price": "0", "types": ["crib"], "key": "free,per_stay,0" } ] },
{ "minAge": 3, "maxAge": 11, "extraBed": { "id": 57224088, "price": "US$35", "priceType": "fixed", "priceMode": "per_night" } }
]
}
],
"extras": null
},
{ "type": "POLICY_HOTEL_PETS", "key": "hotelPets", "id": 1234567891, "content": [ { "text": "Pets are allowed on request. No extra charges.\n", "languageCode": "en-gb" } ], "extras": null },
{ "type": "POLICY_AGE_RESTRICTION", "key": "ageRestriction", "id": null, "content": [ { "text": "The minimum age for check-in is 21", "languageCode": "en-gb" } ], "extras": null }
],
"extras": null
}
]
}
}
...
(Shortened; a real response has every policy the property has.)
| Case | status |
message |
|---|---|---|
| Property has policies | true |
Policies found |
Unknown hotelId (Booking.com returns an empty list) |
false |
No policies found for this property |
| Booking.com unavailable | false |
Stays policies provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
policyGroups[] |
One entry (the "General" group). name/typeId is only a rate-plan label; policyCount how many policies it holds. |
policies[].type, key |
Booking.com's type (POLICY_HOTEL_PETS) and a short camelCase key (hotelPets). Seen across 18 hotels: children (18), hotelInternet (18), hotelPets (18), ageRestriction (17), noCurfew (16), hotelGroups (13), hotelParking (10), bmp (3). Others may exist; unknown types are passed through the same way. |
policies[].id |
Booking.com's policy id; null when it sends an empty one. |
policies[].content[] |
Booking.com's content, camelCased. Most policies are {text, languageCode}. The children policy adds allowChildren, childrenAtTheProperty[], cribsAndExtraBeds[] (highlight = shown emphasised) and ageIntervals[]. |
ageIntervals[] |
Age bands minAge–maxAge (255 = no upper limit), each with the crib, extraBed and/or existingBed that applies: price (a number 0, or a formatted string like US$35 in the property's currency), priceType (free, fixed, adult_percentage), priceMode (per_night, per_stay), and Booking.com's numeric codes priceTypeN/priceModeN. groupByPrice[] lists which items share a price: {priceType, priceMode, price, types[]} (Booking.com sends this as an object whose key is the price description; it is returned as a list so no field name depends on the data, key keeps the original text). |
extras |
Anything Booking.com sends outside those; null when nothing. |
The 0/1 flags (highlight, allowChildren, allowExistingBeds, allowsCribs, allowsExtraBeds, guaranteed, onlyFreeExistingBedRules) are returned as booleans.
17. Stays Rooms (room list)
What it does. Every room type and every rate of a property for the dates and guests you choose: all rooms with size, beds, facilities, highlights and photos, and all rates with price breakdown, meal plan, cancellation and prepayment terms, plus which rates the app recommends for your guests. It is the app's room list.
Where the inputs come from. Part 3 (Rooms and prices) in the journey overview. Pick a property from GET /stays/search, pass its id as hotelId with the same dates and guests. GET /stays/property-details answers with the property page and only the 1-2 rooms and rates the app recommends for the guests; this endpoint returns all of them (for hotel 6966158, 4 adults + 2 children in 2 rooms: 2 rates there, 50 rates in 7 rooms here). This endpoint returns only the room types that can be booked; to also list the sold-out ones use GET /stays/room-types. The IDs in the response are explained in ids.md.
Request
GET /api/v1/stays/rooms?hotelId=6966158&checkin=2026-10-22&checkout=2026-10-23&adults=4&rooms=2&childrenAges=0,3¤cyCode=INR
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
checkin, checkout |
yes | YYYY-MM-DD, same rules as search (not in the past, 1–90 nights, within the booking window). Required because Booking.com rejects the call without dates and the rooms, rates and prices depend on them completely: for hotel 6966158 (2 adults) there were 0 rooms tomorrow and 4–7 rooms on later dates, the cheapest rate ranging from $246 to $871. |
adults |
no, default 2 | 1–30. |
rooms |
no, default 1 | 1–30, not more than adults. |
childrenAges |
no | Comma-separated ages, 0 = under 1 year, e.g. 0,3. |
currencyCode |
no, default USD |
A code from /common/currencies. |
languageCode |
no, default en-us |
A code from /common/languages. Translates rate names, policies and facility names. |
What you get back
{
"status": true,
"message": "Rooms found",
"data": {
"hotelId": 6966158,
"availability": { "checkin": "2026-10-22", "checkout": "2026-10-23", "propertyCurrencyCode": "USD", "requestedCurrencyCode": "INR", "totalRates": 50, "maxRoomsPerBooking": 10, "duplicateRatesRemoved": false, "lastMatchingRateIndex": -1, "soldOutRooms": [] },
"pricing": { "cheapestAvailablePriceEur": 1048.54, "paidMeals": [] },
"policies": {
"cancellation": [ { "blockId": "696615804_287466585_2_1_0_1457283", "policy": "non_refundable" } ],
"prepayment": [ { "blockId": "696615801_287466585_2_0_0_1457283", "policy": "no_prepayment_at_all" } ],
"displayDetails": { "legalCases": null }, "directPayment": { "isHppOnly": false }, "paymentDetail": { "model": "hybrid2.0" },
"creditCardRequired": true, "cvcRequired": true, "noCreditCardReservation": false, "addressRequired": false, "isCpv2Property": true, "useNeutralColorForLegal": false
},
"recommendation": {
"title": "2 rooms for 4 adults, 2 children (< 1 and 3 years old)",
"rooms": [ { "blockId": "696615802_287466585_4_0_0_1457283", "adults": 4, "children": 1, "babies": 0, "totalExtraBedPrice": 0, "totalExtraBedPriceInHotelCurrency": 0 } ],
"guestsPerRoom": { "adults": 2, "children": [ 3 ] },
"childrenStayFree": [ { "blockId": "696615801_287466585_2_0_0_1457283", "title": null, "content": null, "class": null } ],
"aiDescription": "This option has these additional features compared to Deluxe King .",
"selection": {
"roomCount": 2,
"rooms": [
{ "blockId": "696615802_287466585_4_0_0_1457283", "roomId": 696615802, "roomName": "Deluxe Two Queen Beds", "rateName": "Deluxe Two Queen Beds - Non-refundable", "mealplan": "There is no meal option with this room.", "refundable": false, "refundableUntil": null, "maxOccupancy": 4,
"price": { "grossAmount": { "value": 50327.37, "currency": "INR", "amountRounded": "₹ 50,327", "amountUnrounded": "₹ 50,327.37" }, "excludedAmount": { "value": 7756.33, "currency": "INR" }, "allInclusiveAmount": { "value": 58083, "currency": "INR" }, "...": "also grossAmountPerNight, strikethroughAmount, discountedAmount, includedTaxesAndChargesAmount" } },
{ "blockId": "696615801_287466585_2_0_0_1457283", "roomId": 696615801, "roomName": "Deluxe King ", "rateName": "Deluxe King - Non-refundable", "maxOccupancy": 2, "price": { "grossAmount": { "value": 46729.57, "currency": "INR" }, "allInclusiveAmount": { "value": 53954.53, "currency": "INR" } } }
],
"total": { "grossAmount": { "value": 97056.94, "currency": "INR" }, "excludedAmount": { "value": 14980.58, "currency": "INR" }, "allInclusiveAmount": { "value": 112037.53, "currency": "INR" }, "strikethroughAmount": { "value": 132659.84, "currency": "INR" }, "discountedAmount": { "value": 35602.9, "currency": "INR" } }
}
},
"roomCount": 7,
"rooms": [
{ "roomId": 696615801, "roomName": "Deluxe King ", "roomSurfaceInM2": 18, "roomSurfaceInFeet2": 193.75, "description": "The double room features air conditioning, ...", "onlyXLeftMessage": "We have 4 left", "isDormitory": false, "smoking": false, "numberOfBathrooms": 0,
"bedConfigurations": [ { "bedTypes": [ { "bedType": 3, "name": "Extra-large double bed(s)", "count": 1, "nameWithCount": "1 extra-large double bed", "description": "181-210 cm wide" } ] } ],
"facilities": [ { "id": 81, "name": "View", "facilitytypeId": 9, "altFacilitytypeId": 14, "altFacilitytypeName": "View" } ],
"highlights": [ { "id": 11, "translatedName": "Air conditioning", "icon": "snowflake" } ],
"photos": [ { "photoId": 280458367, "urlOriginal": "https://...", "urlMax1280": "https://..." } ],
"blockIds": { "occupancyMatch": [], "nonOccupancyMatch": [ "696615801_287466585_2_0_0_1457283", "..." ], "allMatch": [], "sharedDormitories": [] } }
],
"rateCount": 50,
"rates": [
...
(The example is trimmed; the real response has all 7 rooms and 50 rates with the full price breakdowns.)
| Case | status |
message |
|---|---|---|
| At least one room | true |
Rooms found |
| Unknown property | false |
No rooms found for this property (empty rooms and rates) |
| Booking.com down / error | false |
Stays room list provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
availability |
Dates, the property's own currency (propertyCurrencyCode) next to the one you asked for (requestedCurrencyCode; every price is in the latter), number of rates, rooms you may book at once, soldOutRooms. |
pricing |
cheapestAvailablePriceEur and paidMeals. Prices of each rate are in rates[].productPriceBreakdown. |
policies.cancellation, prepayment |
One entry per rate, matched by blockId: non_refundable, no_prepayment_at_all, full_prepayment ... The timelines with dates and amounts are inside each rate's paymentterms. |
recommendation.selection |
The app's "2 rooms for 4 adults, 2 children" summary, ready to show: rooms[] = each recommended room with its roomName, rateName, mealplan, refundable, maxOccupancy and price (the rate's amounts: grossAmount = the price shown, excludedAmount = taxes and charges paid at the property, allInclusiveAmount = both together, strikethroughAmount/discountedAmount = the crossed-out price and the saving, grossAmountPerNight), and total = the same amounts added up over the recommended rooms (null for an amount a room lacks). Booking.com sends the recommended block ids and the rates apart and adds them up in the app; we do the same, no extra call. Changing the choice is just picking other rates from rates[] and adding their productPriceBreakdown amounts; there is no booking/reserve call in this API. |
recommendation |
What the app suggests for your guests: the title, the recommended rates (rooms[].blockId, with adults/children per room and extra-bed prices), guestsPerRoom, childrenStayFree notes per rate. |
rooms[] |
One per room type: roomId, name, size in m² and ft², description, beds (bedConfigurations), facilities, highlights, photos (several sizes), blockIds (an object with the blockIds of the rates that fit your guests: occupancyMatch, nonOccupancyMatch, allMatch, sharedDormitories), onlyXLeftMessage, apartment layout when it is one. |
rates[] |
One per bookable rate: blockId, roomId, name, occupancy, meal plan, cancellation and prepayment terms, productPriceBreakdown, bundleExtras (e.g. "Late check-in + high-speed internet"), children and extra-bed rules. |
18. Stays Room Types (available and sold out)
What it does. Every room type of a property for your dates and guests, each marked available or sold out. If a hotel has a Suite, a Deluxe and a Special Deluxe and only the Suite can be booked tomorrow, you get all three: the Suite with its price, the other two named and marked sold out. How many individual rooms each type has is not part of it, and not available from Booking.com.
Where the inputs come from. Part 3 (Rooms and prices) in the journey overview. Pick a property from GET /stays/search, pass its id as hotelId with the dates and guests. For the rates, prices and conditions of the available types use GET /stays/rooms (the id here is that endpoint's roomId); GET /stays/rooms alone returns only the types that can be booked.
Request
GET /api/v1/stays/room-types?hotelId=6966158&checkin=2026-11-03&checkout=2026-11-04&adults=2&rooms=1¤cyCode=USD
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
checkin, checkout |
yes | YYYY-MM-DD, same rules as search. Required: the answer depends on them completely. |
adults |
no, default 2 | 1–30. |
rooms |
no, default 1 | 1–30, not more than adults. |
childrenAges |
no | Comma-separated ages, 0 = under 1 year, e.g. 0,3. |
currencyCode |
no, default USD |
A code from /common/currencies. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the room names. |
What you get back
{
"status": true,
"message": "Room types found",
"data": {
"hotelId": 6966158,
"checkin": "2026-11-03",
"checkout": "2026-11-04",
"requestedCurrencyCode": "USD",
"roomTypeCount": 7,
"availableCount": 4,
"soldOutCount": 3,
"roomTypes": [
{
"id": 696615803, "name": "Deluxe Family King", "isAvailable": true, "photoCount": 4,
"photos": [ { "id": 342959732, "thumbnail": "https://cf.bstatic.com/xdata/images/hotel/square60/342959732.jpg?k=...", "medium": "https://cf.bstatic.com/xdata/images/hotel/max500/342959732.jpg?k=...", "large": "https://cf.bstatic.com/xdata/images/hotel/max1024x768/342959732.jpg?k=..." }, "... (photoCount photos)" ],
"availability": { "rateCount": 4, "cheapestPrice": { "allInclusiveAmount": 622.56, "grossAmount": 539.49, "currency": "USD" }, "leftMessage": null, "sizeM2": 20 }
},
{ "id": 696615802, "name": "Deluxe Two Queen Beds", "isAvailable": true, "photoCount": 4, "photos": [ "..." ], "availability": { "rateCount": 4, "cheapestPrice": { "allInclusiveAmount": 633.43, "grossAmount": 548.96, "currency": "USD" }, "leftMessage": "We have 5 left", "sizeM2": 21 } },
{ "id": 696615801, "name": "Deluxe King", "isAvailable": false, "photoCount": 4, "photos": [ "..." ], "availability": null }
]
}
}
| Case | status |
message |
|---|---|---|
| At least one type bookable | true |
Room types found |
| Every type sold out for this search | true |
All N room types are sold out for these dates and guests (availableCount: 0) |
| Unknown property | false |
No room types found for this property |
| Booking.com down / error | false |
Stays room types provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
roomTypeCount, availableCount, soldOutCount |
Room types in the property, how many are bookable for this search, how many are not. |
roomTypes[] |
Bookable types first (cheapest first), then the sold-out ones in the property's own order. |
id, name |
The room type: id is the roomId of /stays/rooms, /stays/property-details and /stays/featured-reviews. The name is the property's own and is translated by languageCode where Booking.com translates it. |
isAvailable |
true if the type can be booked for these dates and guests. |
photoCount, photos[] |
All the photos of the room type (photoCount is the length of photos), each with its id and three sizes (thumbnail, medium, large). Photo tags and alt texts are in /stays/photos. Sold-out types keep their photos. |
availability |
null when sold out. Otherwise rateCount (bookable rates of the type; their details are in /stays/rooms under the same roomId), cheapestPrice (allInclusiveAmount and grossAmount for the whole stay and all rooms searched, in currency), leftMessage (Booking.com's "We have N left", shown only when stock is low, else null) and sizeM2. |
19. Stays Facilities
What it does. The facility list of a property, as the app's Facilities screen shows it: the total number of facilities, the top facilities for the trip, every facility with its opening hours (restaurants), pool details, whether it is free or paid and its sub-facilities, the facility groups and the ten most popular facilities. - See also: GET /stays/food-and-drink has the restaurant details (cuisine, atmosphere, meal types), the breakfast and the other meals.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as the other property endpoints. See the journey overview.
Request
GET /api/v1/stays/facilities?hotelId=6966158
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
excludeGroupIds |
no | Comma-separated facility group ids to leave out of facilities[], e.g. 37,38. Left out: 37,38,39,40,41 (Booking.com's own default, the old health and safety groups). Empty (excludeGroupIds=): nothing is excluded, so facilities[] has facilitiesCount entries. |
includeCommonAmenities |
no, default true |
false leaves the common amenities out of facilities[] (55 to 36 on hotel 6966158). |
topFacilitiesLimit |
no, default 5 |
How many entries accommodationHighlights (the top facilities for the trip) has, 1 to 100 (the app asks for 5, or 10 on the property page); a property returns at most what it has (21 for hotel 1150083). |
languageCode |
no, default en-us |
A code from /common/languages. Translates every title and group name. |
What you get back
Field names are Booking.com's own, under data.propertyDetails.
{
"status": true,
"message": "Facilities found",
"data": {
"propertyDetails": {
"facilitiesCount": 76,
"accommodationHighlights": [
{ "entities": [ { "type": "WifiFacilityHighlight", "icon": "internet", "title": "Free WiFi" } ] }
],
"facilities": [
{ "id": 109, "icon": "weather_snowflake", "groupId": 1, "slug": "airconditioning", "groupTitle": "General",
"instances": [ { "title": "Air conditioning", "subFacilities": [],
"attributes": { "name": null, "isOffsite": false, "paymentInfo": { "chargeMode": "FREE" },
"closureScheduleDuringStay": [], "scheduleEntry": [], "extendedAttributes": null } } ] },
{ "id": 3, "icon": "food", "groupId": 7, "groupTitle": "Food & Drink",
"instances": [ { "title": "Restaurant", "subFacilities": [],
"attributes": { "name": "Park Avenue", "isOffsite": false, "paymentInfo": null, "closureScheduleDuringStay": [],
"scheduleEntry": [ { "from": { "hours": 7, "minutes": 0 }, "to": { "hours": 10, "minutes": 0 }, "dayOfWeek": "MONDAY" } ],
"extendedAttributes": {} } } ] }
],
"facilityGroups": [ { "id": 11, "title": "Internet", "icon": "wifi", "summary": "WiFi is available in all areas and is free of charge." } ],
"highlights": { "entities": [
{ "type": "BaseFacility", "id": 47, "groupId": 11, "groupTitle": "Internet", "icon": "internet", "instances": [ { "title": "Internet services" } ] },
{ "type": "Meal" }
] }
}
}
}
| Case | status |
message |
|---|---|---|
hotelId resolves to a property |
true |
Facilities found |
hotelId doesn't resolve |
false |
Stays facilities provider error: Internal Server Error |
| Booking.com down / HTTP error | false |
Stays facilities provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
facilitiesCount |
The property's total number of facilities. facilities[] can be shorter (see excludeGroupIds, includeCommonAmenities). |
accommodationHighlights[].entities[] |
The top facilities for the trip: type (GenericFacilityHighlight, WifiFacilityHighlight, ...), icon, title. |
facilities[] |
id, icon, groupId, slug (a stable name such as airconditioning), groupTitle (the title of that group, from facilityGroups[]), and instances[]. |
instances[].title |
The facility's name (a facility can have several instances, e.g. two restaurants). |
instances[].subFacilities[] |
Variants, e.g. instances[].title "Parking garage", "Valet parking". |
instances[].attributes |
null when only the title is known. Otherwise: name (e.g. the restaurant's name), isOffsite, paymentInfo.chargeMode (FREE, PAID, UNKNOWN_CHARGE_MODE; paymentInfo can be null), scheduleEntry[] (opening hours: from/to {hours, minutes} and dayOfWeek MONDAY to SUNDAY), closureScheduleDuringStay[] (from/to {formattedDate}), extendedAttributes. |
extendedAttributes |
For a swimming pool: ageRestriction, availabilityType, isHeated, isInfinity, isPlungePool, isPoolWithView, isRooftop, isSaltWater, isShallowEnd, isShared, location (OUTDOOR, ...). Other kinds (restaurant, internet, parking, bathroom) come back as {}. Unknown pool flags are false, not "no". |
facilityGroups[] |
All groups: id, title, icon, summary (a sentence for some groups: internet, parking, pets). |
highlights.entities[] |
The ten most popular facilities: type, id, groupId, groupTitle, icon, instances[].title. A Meal entry has only type. The order changes between calls. |
IDs: facilities[].id and groupId are the same numbers as in /stays/property-facilities and in the room facilities of /stays/rooms; see ids.md.
20. Stays Property Facilities
What it does. The facility catalog of a property and a few id lists: the facility groups and facilities (with prices where a facility is charged, e.g. internet or parking per day), the amenity ids of each room type, the languages spoken, whether it is a Booking.com Homes listing, the Q&A question ids and the gallery photos grouped by tag. This is what GET /stays/property-details returned before 2026-10-19. That route is now the property detail page (stays-property-details.md); this data moved here unchanged. - See also: GET /stays/facilities has the same facilities plus restaurant opening hours, pool details, sub-facilities and the ten most popular facilities, but no prices; use this endpoint when you need facility prices, room amenities or languages spoken. - See also: the question and answer text behind questionsAndAnswers.questionIds is in GET /stays/questions.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as the other property endpoints. See the journey overview.
Request
GET /api/v1/stays/property-facilities?hotelId=59304
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
facilityGroupIds |
no | Comma-separated facility group ids, e.g. 12,7,13,15. Omit for every group and facility. |
languageCode |
no, default en-us |
Translates every title and name. |
What you get back
{
"status": true,
"message": "Property details found",
"data": {
"languagesSpoken": ["en", "hi", "mr"],
"isBookingHome": false,
"facilityGroupCount": 45,
"facilityGroups": [ { "id": 12, "title": "Internet", "icon": "wifi", "summary": "...", "extras": null } ],
"facilityCount": 109,
"facilities": [
{ "id": 46, "icon": "wifi", "groupId": 12, "groupTitle": "Internet",
"instances": [ { "title": "WiFi is available in all areas and is free of charge", "summary": "...", "name": "...", "isOffsite": false, "charge": null, "extras": null } ],
"extras": null }
],
"roomCount": 8,
"rooms": [ { "id": 5930456, "amenities": [ { "id": 11, "groupId": 3, "groupTitle": "Bathroom", "icon": "bath", "instances": [ "..." ], "extras": null } ] } ],
"questionsAndAnswers": { "partnerOptedOut": false, "questionIds": [1915675] },
"photoTags": [ { "tagId": 7, "photos": [ { "id": 607956163, "altText": "...", "photoType": "PROPERTY", "imageUrl": "...", "images": { "thumbnail": "...", "medium": "...", "large": "..." }, "extras": null } ] } ]
}
}
| Case | status |
message |
|---|---|---|
hotelId resolves to a property |
true |
Property details found |
hotelId doesn't resolve |
false |
Stays property details provider error: Internal Server Error |
| Booking.com down / HTTP error | false |
Stays property details provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
status says whether the property resolved, not whether the groups came back non-empty: an empty result for a narrow facilityGroupIds filter is a normal answer.
Fields
| Field | Meaning |
|---|---|
languagesSpoken |
Language codes the staff speak. |
isBookingHome |
Whether this is a Booking.com Homes ("vacation rental") listing. |
facilityGroupCount, facilityGroups[] |
The facility groups: id, title, icon, summary. |
facilityCount, facilities[] |
Facilities inside those groups: id, icon, groupId, groupTitle, and instances[] (title, summary, name, isOffsite, and charge {mode, amount {currency, frequency, price}} when it costs money). |
roomCount, rooms[] |
One per room type: id and its amenities[] (each with groupId, groupTitle, icon, instances[]). Room names, sizes and descriptions are in /stays/property-details. |
questionsAndAnswers |
partnerOptedOut and questionIds[] (ids only; the text is not available). |
photoTags[] |
Gallery photos grouped by Booking.com's tag id, with images (thumbnail, medium, large). All photos with tags and per-room photos: /stays/photos. |
extras |
Anything Booking.com sends that has no named field here; null when none. |
21. Stays Food and Drink
What it does. Everything about eating at a property, as the app's "Food & drink" block shows it: breakfast and the other meals (included or paid, the price, buffet or à la carte, the menu, the opening time and a food score from guests), the restaurants (name, cuisine, atmosphere, meal types, buffet / à la carte, which meals it is open for), and the food facilities (bar, snack bar, minimarket, wine, fruit ...) and food amenities in the room (fridge, coffee machine ...).
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId. See the journey overview.
Request
GET /api/v1/stays/food-and-drink?hotelId=6966158¤cyCode=USD
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
currencyCode |
no, default USD |
A code from /common/currencies. The meal prices (text such as € 22.22) are in this currency. |
languageCode |
no, default en-us |
A code from /common/languages. Translates names (cuisine, style, facilities). |
What you get back
Field names are Booking.com's own, under data.propertyDetails.
{
"status": true,
"message": "Food and drink found",
"data": {
"propertyDetails": {
"accommodationType": { "type": "HOTEL", "flags": { "isSingleTypeProperty": false } },
"foodFacilities": [ { "id": 7, "groupId": 7, "slug": "bar", "instances": [ { "title": "Bar" } ] } ],
"foodAmenities": [ { "id": 22, "groupId": 12, "slug": "refrigerator", "instances": [ { "title": "Refrigerator" } ] } ],
"meals": [
{ "offer": "INCLUDED", "mealType": "BREAKFAST", "price": null,
"attributes": { "foodMenu": [], "style": ["Buffet"], "cuisine": [], "dietary": [], "drinks": [],
"openingTime": { "startTime": "07:00", "endTime": "10:00" },
"foodScore": { "score": 8.8, "nReviews": 134 },
"photo": "/xdata/images/hotel/max400/342959701.jpg?k=...", "photoUrl": "https://cf.bstatic.com/xdata/images/hotel/max400/342959701.jpg?k=..." } }
],
"restaurants": [
{ "id": 3, "groupId": 7, "slug": "restaurant",
"instances": [ { "title": "Restaurant",
"attributes": { "name": "Park Avenue",
"extendedAttributes": { "ambiances": [ { "name": "Family friendly" }, { "name": "Modern" } ], "cuisines": [ { "name": "American" } ],
"mealTypes": [ { "name": "Vegetarian" }, { "name": "Gluten-free" } ], "openForMeals": [ { "name": "Breakfast" } ], "isBuffet": true, "isAlacarte": false } } } ] }
]
}
}
}
| Case | status |
message |
|---|---|---|
| The property resolves | true |
Food and drink found (empty lists when it has nothing) |
hotelId doesn't resolve |
false |
Stays food and drink provider error: … |
| Booking.com down / HTTP error | false |
Stays food and drink provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
accommodationType |
type (HOTEL, APARTHOTEL, APARTMENT, HOMESTAY ...) and flags.isSingleTypeProperty. |
foodFacilities[], foodAmenities[] |
Facilities with id, groupId, slug and instances[].title: the same ids as /stays/facilities and /stays/property-facilities. Facilities are the property's (bar, snack bar, minimarket ...), amenities are in the rooms (fridge, coffee machine). |
meals[].mealType |
BREAKFAST, LUNCH, DINNER or BRUNCH. |
meals[].offer |
INCLUDED (in the room price), BOTH (included in some rates, otherwise paid), OPTIONAL_PAID (you can add it), NOT_OFFERED. |
meals[].price |
The price as text in currencyCode (€ 22.22), or null when it is included or not offered. |
meals[].attributes |
null when no details are given. Otherwise style (Buffet, À la carte, Breakfast to go), foodMenu (Bread, Eggs, Fruit ...), cuisine, dietary (Vegetarian, Vegan ...), drinks, openingTime {startTime, endTime} (or null), foodScore {score, nReviews} (the guests' score for the food and how many reviews), photo and photoUrl (the same picture as a full URL). |
restaurants[].instances[] |
One per restaurant: title and attributes.name (the restaurant's name) with extendedAttributes: ambiances, cuisines, mealTypes and openForMeals (each a list of {name}), isBuffet, isAlacarte. The opening hours per weekday are in /stays/facilities. |
22. Stays Photos
What it does. Every photo of a property: the main gallery (with tags) plus each room's own photos, each in three sizes. - See also: GET /stays/photo-list is a lighter list of the same photos with the aspect ratio (ratio), the rooms of each photo as a flat list and more sizes; the alt texts and AI tags are only here.
Where the inputs come from. Call GET /stays/search first; take a property's id and pass it here as hotelId, same as GET /stays/highlights and GET /stays/property-details. Property-details also returns photos, but only grouped by tag and with no room grouping; this endpoint is the full photo grid.
Request
GET /api/v1/stays/photos?hotelId=183564
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
Same auth, subscription and quota as /stays/search (one call = one request).
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no | Same as /stays/search, default en-us. Translates alt texts, tag names and room names. |
Not accepted: dates, guests, currencyCode, gallery limit (see above).
What you get back
{
"status": true,
"message": "Photos found",
"data": {
"photoCount": 145,
"photos": [
{
"id": 753139154,
"altText": "a building with flags in front of it at Club Quarters Hotel World Trade Center, New York in New York",
"photoType": "PROPERTY",
"images": {
"thumbnail": "https://cf.bstatic.com/xdata/images/hotel/square60/753139154.jpg?k=...&o=",
"medium": "https://cf.bstatic.com/xdata/images/hotel/max500/753139154.jpg?k=...&o=",
"large": "https://cf.bstatic.com/xdata/images/hotel/max1024x768/753139154.jpg?k=...&o="
},
"tags": [{ "id": 3, "name": "Property building" }],
"aiTags": [],
"extras": null
}
],
"roomCount": 18,
"rooms": [
{
"id": 18356401,
"name": "Standard Queen Room",
"photoCount": 13,
"photos": [
{
"id": 583896226,
"altText": "Gallery image of Club Quarters Hotel World Trade Center, New York in New York",
"photoType": "ROOM",
"images": { "thumbnail": "...", "medium": "...", "large": "..." },
"tags": [{ "id": 13, "name": "Bed" }, { "id": 154, "name": "TV and multimedia" }],
"aiTags": [{ "id": 13, "name": "Bed", "confidence": 100 }],
"extras": null
}
]
}
]
}
...
| Case | status |
message |
|---|---|---|
| At least one photo (main or room) | true |
Photos found |
| Property resolves but has no photos | false |
No photos found |
hotelId doesn't resolve (service errors, ) |
false |
Stays property photos provider error: Internal Server Error |
| Booking.com unavailable | false |
Stays property photos provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
photos[] |
The main gallery (property-level photos: building, lobby, pool, and so on). |
photos[].photoType |
Booking.com's own type, e.g. PROPERTY or ROOM. Passed through as-is, not a closed list. |
photos[].images |
thumbnail (60px square), medium (max 500px), large (max 1024x768). |
photos[].tags[] |
Booking.com's photo tags (e.g. Bed, Bedroom, Property building) with their ids. |
photos[].aiTags[] |
Machine-detected tags with a confidence of 0 to 100; usually only present on room photos. |
rooms[] |
Every room of the property, with its own photos grouped under it. The id matches rooms[].id from GET /stays/property-details. |
extras |
Anything Booking.com sends on a photo that we don't map; null when nothing extra. |
23. Stays Photo List
What it does. A compact list of a property's photos: for every photo its aspect ratio, the rooms it shows, its tags and six image sizes. It is the light, fast sibling of GET /stays/photos (the same photos, 55 for hotel 6966158) and adds one thing that endpoint cannot give: the aspect ratio, so a gallery can reserve the right space before an image loads.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId. See the journey overview.
Request
GET /api/v1/stays/photo-list?hotelId=6966158
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the tag names. |
What you get back
{
"status": true,
"message": "Photos found",
"data": {
"hotelId": 6966158,
"photoCount": 55,
"photos": [
{ "photoId": 598995411, "ratio": 1.54428, "filters": ["room:696615817"], "roomIds": [696615817],
"tags": [ { "id": 159, "tag": "Living room" }, { "id": 1000000001, "tag": "Property" } ],
"images": { "square60": "https://cf.bstatic.com/xdata/images/hotel/square60/598995411.jpg?k=...",
"square90": "...", "max300": "...", "max500": "...", "max1024": "...", "max1280": "..." },
"extras": null }
],
"extras": null
}
}
| Case | status |
message |
|---|---|---|
| The property has photos | true |
Photos found |
| Unknown property | false |
No photos found |
| Booking.com down / HTTP error | false |
Stays photo list provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
photoId |
The photo's id: the id of the same photo in /stays/photos. |
ratio |
Width divided by height (1.54 = a landscape photo). |
roomIds |
The rooms the photo shows (the roomId of /stays/rooms); empty for a general photo. filters is Booking.com's own list these come from. |
tags[] |
The photo's tags: id and tag (the name, translated). The same ids as the tags in /stays/photos. |
images |
Full URLs in six sizes: square60, square90 (square crops), max300, max500, max1024 (1024x768), max1280 (1280x900). |
extras |
Anything Booking.com sends that has no named field here; null when none. |
24. Stays Review Photos
What it does. The highlighted photos guests attached to their reviews for a property: up to five photos, each in four sizes, with the id of the review it belongs to and the date it was added. It is the photo strip the app shows in the reviews section.
Where the inputs come from. Part 3 (Photos) in the journey overview. Pick a property from GET /stays/search and pass its id as hotelId. Use the reviewId of a photo to find its review text in GET /stays/reviews; the official property photos are in GET /stays/photos.
Request
GET /api/v1/stays/review-photos?hotelId=6966158
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
What you get back
{
"status": true,
"message": "Review photos found",
"data": {
"hotelId": 6966158,
"count": 5,
"photos": [
{
"id": 551521325,
"reviewId": 5181440717,
"photoCreatedAt": "2025-07-16",
"urls": [
{ "size": "max500_ao", "url": "https://r-xx.bstatic.com/xdata/images/xphoto/max500_ao/551521325.jpg?k=..." },
{ "size": "square60_ao", "url": "https://r-xx.bstatic.com/xdata/images/xphoto/square60_ao/551521325.jpg?k=..." },
{ "size": "square90", "url": "https://r-xx.bstatic.com/xdata/images/xphoto/square90/551521325.jpg?k=..." },
{ "size": "max1280x900", "url": "https://r-xx.bstatic.com/xdata/images/xphoto/max1280x900/551521325.jpg?k=..." }
],
"extras": null
}
]
}
}
| Case | status |
message |
|---|---|---|
| At least one photo | true |
Review photos found |
| No review photos, or unknown property | false |
No review photos found for this property |
| Booking.com answered with its own error type | false |
Booking.com could not return review photos: … |
| Booking.com down / error | false |
Stays review photos provider is unreachable / …returned HTTP <n> / …provider error: <message> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
count |
Number of photos (0 to 5). |
photos[].id |
The photo's id (also in its image URLs). |
photos[].reviewId |
The review the guest attached it to; find the text with /stays/reviews. |
photos[].photoCreatedAt |
Day it was added, YYYY-MM-DD. |
photos[].urls[] |
size and url: square60_ao / square90 (thumbnails), max500_ao (up to 500 px), max1280x900 (largest). |
photos[].extras |
Anything Booking.com adds that is not mapped yet; null so far. |
25. Stays Review Scores
What it does. How guests scored a property: the overall score, the scores per category (cleanliness, comfort, facilities, location, staff, value for money, WiFi), the same split by guest type (couples, families, solo travellers, ...), how many reviews fall in each score band (Superb, Good, Okay, Poor, Very poor) and how many reviews gave each whole score from 1 to 10.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as the other property endpoints. The review texts are in GET /stays/reviews; the sort/filter menus and counts are in GET /stays/review-filters. See the journey overview.
Request
GET /api/v1/stays/review-scores?hotelId=183564
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no | Default en-us. A code from /common/languages. Translates the score words and category labels. |
What you get back
{
"status": true,
"message": "Review scores found",
"data": {
"hotelId": 183564,
"overall": {
"customerType": "total",
"averageScore": 8.7,
"reviewCount": 3221,
"fromYear": 2023,
"categories": [
{ "id": "hotel_clean", "label": "Cleanliness", "score": 8.8, "reviewCount": 3157, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "hotel_comfort", "label": "Comfort", "score": 8.9, "reviewCount": 3160, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "hotel_services", "label": "Facilities", "score": 8.6, "reviewCount": 3166, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "hotel_location", "label": "Location", "score": 9.4, "reviewCount": 3156, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "hotel_staff", "label": "Staff", "score": 9, "reviewCount": 3164, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "total", "label": "Total", "score": 8.5, "reviewCount": 3221, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "hotel_value", "label": "Value for money", "score": 8.2, "reviewCount": 3159, "comparisonToDestinationAverage": 0, "extras": null },
{ "id": "hotel_wifi", "label": "WiFi", "score": 8.3, "reviewCount": 102, "comparisonToDestinationAverage": 0, "extras": null }
],
"extras": null
},
"guestTypes": [
{ "customerType": "family", "averageScore": 8.6, "reviewCount": 1362, "fromYear": 2023, "categories": [ "..." ], "extras": null },
{ "customerType": "couple", "averageScore": 8.7, "reviewCount": 928, "fromYear": 2023, "categories": [ "..." ], "extras": null }
],
"scoreBands": [
{ "label": "Superb", "from": 9, "to": 10.1, "reviewCount": 1763, "percent": 55, "extras": null },
{ "label": "Good", "from": 7, "to": 9, "reviewCount": 1147, "percent": 36, "extras": null }
],
"scoreDistribution": [
{ "score": 1, "reviewCount": 45, "percent": 1.4, "extras": null },
{ "score": 10, "reviewCount": 1025, "percent": 31.82, "extras": null }
],
"extras": null
}
}
(Shortened: a real response has all 8 categories for every group, every guest type, 5 bands and 10 scores.)
| Case | status |
message |
|---|---|---|
| Property has scores | true |
Review scores found |
No reviews, or unknown hotelId (everything zero) |
false |
No review scores found for this property (overall is null) |
| Booking.com unavailable | false |
Stays review scores provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
overall |
The property's overall result (Booking.com's total group): averageScore, reviewCount and the categories. fromYear is the year Booking.com counts reviews from (2023 seen). |
categories[] |
id (hotel_clean, hotel_comfort, hotel_services = Facilities, hotel_location, hotel_staff, hotel_value, hotel_wifi, total), the translated label, score (0–10, as a number), reviewCount and comparisonToDestinationAverage (0 = in line with the destination's average; 1 seen on a standout score). WiFi has far fewer reviews than the others. |
guestTypes[] |
The same shape for each guest type, most reviews first. customerType ids seen: family, family_with_young_children, couple, young_couple, solo_traveller, group, with_friends, review_category_business_travellers, and null where Booking.com sends an empty id (its count matched the "Group of friends" count of /stays/review-filters on the one property checked). Several ids carry identical numbers (couple = young_couple, family = family_with_young_children) - Booking.com lists both. |
scoreBands[] |
Reviews per band: label (Superb, Good, Okay, Poor, Very poor), the score range from (inclusive) to to (exclusive), reviewCount, percent. |
scoreDistribution[] |
How many reviews gave each whole score 1–10 (score, reviewCount, percent as a number). |
extras |
Anything Booking.com sends that we don't map; null when nothing extra. |
26. Stays Review Score Comparison
What it does. The review categories of a property (Cleanliness, Comfort, Facilities, Location, Staff, Value for money, Free WiFi) with the exact (unrounded) score and the range that the other properties of the same destination score in. It answers "is 9.2 for cleanliness good for this city?".
Where the inputs come from. Part 3 (Reviews, scores and questions) in the journey overview, next to GET /stays/review-scores. Pick a property from GET /stays/search, pass its id as hotelId, and the hotel's city as destination: city:<location.cityId> of the same GET /stays/search result (no extra call), or city:<location.destinationId> of GET /stays/property-details.
Request
GET /api/v1/stays/review-score-comparison?hotelId=6966158&destination=city:20088325&languageCode=en-us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
destination |
no | The hotel's city as city:<id>: city:<location.cityId> of the hotel's /stays/search result, or city:<location.destinationId> of /stays/property-details (the two are the same number: checked on 15 hotels found by airport, landmark, district and city searches). Note it is the hotel's own city, not what you searched for: a hotel found by searching an airport belongs to the city it stands in. Without it the scores come back and destinationAverage is null. Other types (hotel:, airport:, latlong: ...) are rejected. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the category labels. |
What you get back
{
"status": true,
"message": "Review score comparison found",
"data": {
"hotelId": 6966158,
"destinationId": 20088325,
"categoryCount": 7,
"categories": [
{ "id": "hotel_clean", "label": "Cleanliness", "score": 9.19564151763916, "destinationAverage": { "lowerBound": 7.640125274658203, "higherBound": 9.253375053405762 }, "extras": null },
{ "id": "hotel_comfort", "label": "Comfort", "score": 9.298111915588379, "destinationAverage": { "lowerBound": 7.688374996185303, "higherBound": 9.301799774169922 }, "extras": null },
{ "id": "hotel_services", "label": "Facilities", "score": 8.906320571899414, "destinationAverage": { "lowerBound": 7.2856245040893555, "higherBound": 8.964300155639648 }, "extras": null },
{ "id": "hotel_location", "label": "Location", "score": 9.69638442993164, "destinationAverage": { "lowerBound": 8.476824760437012, "higherBound": 9.78427505493164 }, "extras": null },
{ "id": "hotel_staff", "label": "Staff", "score": 9.137491226196289, "destinationAverage": { "lowerBound": 7.994899749755859, "higherBound": 9.368974685668945 }, "extras": null },
{ "id": "hotel_value", "label": "Value for money", "score": 8.38898754119873, "destinationAverage": { "lowerBound": 7.173224449157715, "higherBound": 8.66717529296875 }, "extras": null },
{ "id": "hotel_free_wifi", "label": "Free WiFi", "score": 9.228316307067871, "destinationAverage": { "lowerBound": 7.897200107574463, "higherBound": 9.088449478149414 }, "extras": null }
]
}
}
| Case | status |
message |
|---|---|---|
| At least one category | true |
Review score comparison found |
| No reviews, or unknown property | false |
No review scores found for this property |
| Booking.com answered with its own error | false |
Booking.com could not return review scores: … |
| Booking.com down / error | false |
Stays review score comparison provider is unreachable / …returned HTTP <n> / …provider error: <message> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
destinationId |
The city used for the range (null if you gave none). |
categories[].id, label |
Booking.com's category id and its translated name: hotel_clean, hotel_comfort, hotel_services (Facilities), hotel_location, hotel_staff, hotel_value, hotel_free_wifi. |
categories[].score |
The property's score for that category, not rounded (0–10). Round it yourself for display. |
categories[].destinationAverage |
lowerBound and higherBound: the range the destination's properties score in. A score above higherBound is above the destination's range. null without a destination. |
categories[].extras |
Anything Booking.com adds that is not mapped yet; null so far. |
27. Stays Featured Reviews
What it does. The review overview at the top of a property's reviews: a title ("Guests who stayed here loved") and ten featured reviews, each with the guest (name, country, guest type, how many reviews they wrote) and the review text (title, what they liked, what they did not like). For the full list with paging, sorting and filters use GET /stays/reviews; for the scores use GET /stays/review-scores.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId. To feature only the guests of one room, pass roomId (a rooms[].id from GET /stays/property-details). See the journey overview.
Request
GET /api/v1/stays/featured-reviews?hotelId=183564
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
roomId |
no | A room id (rooms[].id of /stays/property-details) to feature only that room's reviews. |
languageCode |
no, default en-us |
A code from /common/languages. Translates the title and guest types and decides whose reviews are featured. |
What you get back
{
"status": true,
"message": "Featured reviews found",
"data": {
"hotelId": 183564,
"roomId": null,
"title": "Guests who stayed here loved",
"count": 10,
"reviews": [
{
"id": 5343489281,
"score": 10,
"isNonStayedReview": false,
"guest": { "name": "Cecilia", "avatarUrl": "https://xx.bstatic.com/static/img/review/avatars/ava-c.png", "countryCode": "us", "country": "United States", "showCountryFlag": true, "isAnonymous": false, "isGenius": null, "type": "Couple", "reviewCount": 14, "joinedDate": null },
"text": { "title": "I’ve stayed before, will stay again.", "positive": "Quiet and convenient location, easy check-in/out, comfortable beds, nice bathrooms, and spacious for just me!", "negative": "The carpets in the rooms need refreshing or replacing. Stains and stick spots.", "languageCode": "xu", "isTrivial": false },
"translation": null
}
]
}
}
| Case | status |
message |
|---|---|---|
| At least one featured review | true |
Featured reviews found |
No reviews, unknown roomId, or unknown property |
false |
No featured reviews found for this property |
| Booking.com answered with its own error type | false |
Booking.com could not return featured reviews for this request |
| Booking.com down / error | false |
Stays featured reviews provider is unreachable / …returned HTTP <n> / …provider error: <message> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
title |
The overview heading, translated ("Guests who stayed here loved"). |
count |
Number of featured reviews (10, or fewer). |
reviews[].id, score |
Review id and its score (0–10). |
reviews[].isNonStayedReview |
True for a review by a guest who did not stay. |
reviews[].guest |
name, avatarUrl, countryCode/country, showCountryFlag, isAnonymous, isGenius (null when not shown), type (guest type, translated), reviewCount (how many reviews this guest wrote), joinedDate (null in every sample). |
reviews[].text |
title, positive (liked), negative (did not like; null when empty), languageCode (the review's own language: en, xu = American English, de, ...), isTrivial. |
reviews[].translation |
null unless Booking.com machine-translated the review into the requested language: then provider, title, positive, negative. |
28. Stays Review Filters
What it does. The menus of a property's reviews page: how many reviews it has, the sort options (most relevant, newest, oldest, highest/lowest scores) and four filter menus - guest type, review language, time of year and topics - each option with its id and how many reviews match it. Review scores are in GET /stays/review-scores. This is the review metadata, not the review texts. The ids it returns are what GET /stays/reviews takes to sort and filter (sortBy, customerType, reviewLanguages, topicIds, timeOfYear).
Where the inputs come from. Call GET /stays/search first; take a property's id and pass it here as hotelId, same as /stays/highlights, /stays/photos, /stays/property-details and /stays/important-info. See the journey overview for the whole order.
Request
GET /api/v1/stays/review-filters?hotelId=183564
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no | Default en-us. A code from /common/languages. Translates every label. |
What you get back
{
"status": true,
"message": "Review filters found",
"data": {
"hotelId": 183564,
"totalReviews": 3221,
"sort": {
"id": "user_sort",
"title": "Sort by:",
"options": [
{ "id": "sort_most_relevant", "label": "Most relevant", "extras": null },
{ "id": "sort_recent_desc", "label": "Newest first", "extras": null },
{ "id": "sort_recent_asc", "label": "Oldest first", "extras": null },
{ "id": "sort_score_desc", "label": "Highest scores", "extras": null },
{ "id": "sort_score_asc", "label": "Lowest scores", "extras": null }
],
"extras": null
},
"filterCount": 4,
"filters": [
{
"id": "filter_customer_type",
"title": "Filter by:",
"type": "radio_button",
"defaultLabel": "All reviews",
"defaultLabelWithCount": "All reviews (3221)",
"optionCount": 4,
"options": [
{ "id": "couple", "label": "Couple", "labelWithCount": "Couple (928)", "count": 928, "extras": null },
{ "id": "family_with_children", "label": "Family", "labelWithCount": "Family (1362)", "count": 1362, "extras": null }
],
"extras": null
}
],
"extras": null
}
}
(filters is shortened above; a real response has all four.)
| Case | status |
message |
|---|---|---|
| Property has reviews | true |
Review filters found |
No reviews, or unknown hotelId |
false |
No reviews found for this property |
| Booking.com unavailable | false |
Stays review filters provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
hotelId |
The property id, as a number. null when Booking.com omits it (unknown property). |
totalReviews |
All reviews of the property. |
sort |
The sort menu: id (user_sort), title, and options[] {id, label}. Ids seen: sort_most_relevant, sort_recent_desc, sort_recent_asc, sort_score_desc, sort_score_asc. |
filters[] |
One entry per menu, in Booking.com's order: filter_customer_type, filter_language, filter_time_of_year, filter_topic. |
filters[].type |
radio_button (pick one), checkbox (pick several) or tags (topic chips). |
filters[].defaultLabel, defaultLabelWithCount |
The "no filter" choice, e.g. "All reviews" / "All reviews (3221)", "All languages (3206)". Note the language total can be smaller than totalReviews. |
filters[].optionCount, options[] |
The choices. Each has id, label, labelWithCount (e.g. "Family (1362)"), count. |
| Guest types (ids seen) | couple, family_with_children, review_category_group_of_friends, solo_traveller. |
| Languages | Two-letter ids (en, de, ...) plus Booking.com's variants xu American English, xa Argentine Spanish, xb Brazilian Portuguese, xt Traditional Chinese. Only languages the property has reviews in are listed (39 for hotel 183564). |
| Time of year | 03_06 Mar-May, 06_09 Jun-Aug, 09_12 Sep-Nov, 12_03 Dec-Feb. Booking.com sends count: 0 and no number in the label for these: it means "not provided", not "no reviews". |
| Topics | Numeric ids (e.g. 249 Location, 270 Room) with how many reviews mention each; sorted by count. Up to 51 per property. |
| Using the ids | Pass them to GET /stays/reviews: sort id → sortBy, guest type → customerType, languages → reviewLanguages, topics → topicIds, seasons → timeOfYear. |
extras |
Anything Booking.com sends that we don't map; null when nothing extra. |
29. Stays Reviews
What it does. One page of a property's guest reviews: score, title, what they liked and disliked, who the guest is, the room they stayed in, their photos and the hotel's reply. The short overview with featured reviews is GET /stays/featured-reviews. Overall and per-category scores are in GET /stays/review-scores. Sort and filter with the ids from GET /stays/review-filters.
Where the inputs come from. Pick a property from GET /stays/search (its id is hotelId). Call GET /stays/review-filters first if you want the review total, the sort ids and the filter options with their counts; then call this with those ids. See the journey overview for the whole order.
Request
GET /api/v1/stays/reviews?hotelId=183564&sortBy=sort_recent_desc&customerType=couple&page=1&pageSize=25
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result. |
page |
no | From 1, default 1. Past the last page → empty list. |
pageSize |
no | 1–100, default 25. |
sortBy |
no | A sort id (see above). Omit for most relevant. |
customerType |
no | One guest-type id: couple, family_with_children, review_category_group_of_friends, solo_traveller. |
reviewLanguages |
no | Comma list of language ids from review-filters, e.g. de,fr. |
topicIds |
no | Comma list of topic ids, e.g. 249,270. A review matching any is returned. |
timeOfYear |
no | Comma list of 03_06, 06_09, 09_12, 12_03. |
languageCode |
no | Default en-us. The language shown first. Not a filter. |
What you get back
{
"status": true,
"message": "Reviews found",
"data": {
"page": 1,
"pageSize": 25,
"count": 25,
"hasNextPage": true,
"sortOptions": [
{ "id": "sort_most_relevant", "label": "Most relevant", "isDefault": true, "extras": null },
{ "id": "sort_recent_desc", "label": "Date (newer to older)", "isDefault": false, "extras": null }
],
"reviews": [
{
"id": 5354374431,
"hash": "c271fcf0cde7b344",
"hotelId": 183564,
"date": "2026-10-18 02:29:59",
"score": 3.6,
"title": "I would go back again",
"titleTranslated": null,
"titleIsGenerated": false,
"pros": "The room and the bed were better than in other CQ ...",
"prosTranslated": null,
"cons": "The staff member I dealt with on the day I checked out was not very nice. ...",
"consTranslated": null,
"languageCode": "en-us",
"countryCode": "us",
"travelPurpose": "leisure",
"stayStatus": "stayed",
"anonymous": null,
"isIncentivised": false,
"isModerated": false,
"helpfulVoteCount": 0,
"author": { "name": "Maria", "userId": 967191017, "countryCode": "us", "avatar": "https://...", "reviewCount": 0, "type": "family_with_children", "typeLabel": "Family", "city": null, "helpfulVoteCount": 0, "extras": null },
"stayedRoom": {
"roomId": 18356408, "roomName": "Mobility Accessible Standard Room",
"checkin": "2026-09-05", "checkout": "2026-09-07", "nights": 2,
"photo": { "id": 280834956, "ratio": 1.5, "images": { "square60": "...", "max300": "...", "max500": "...", "wide640x200": "..." }, "extras": null },
"extras": null
...
| Case | status |
message |
|---|---|---|
| At least one review on the page | true |
Reviews found |
| Empty page (past the end, filters match nothing, unknown property) | false |
No reviews found |
Booking.com unavailable (also an unknown sortBy id → 400 Booking.com) |
false |
Stays reviews provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
count, pageSize, page |
Reviews on this page, the page size and the page number. No total here - /stays/review-filters has totalReviews and a count per filter option. |
hasNextPage |
true when the page is full, so there may be more (it can be a false alarm when the last page is exactly full). |
sortOptions[] |
Booking.com's own sort menu for this call. |
reviews[].id, hash |
Review id and Booking.com's short hash. |
date |
When it was written, YYYY-MM-DD HH:MM:SS, exactly as Booking.com gives it (no time zone). |
score |
The review score, 0–10, one decimal. |
title, titleIsGenerated |
The title; titleIsGenerated is true when the guest wrote none and Booking.com filled one in (e.g. "Exceptional"). |
pros, cons |
What the guest liked / disliked. null when left empty. |
titleTranslated, prosTranslated, consTranslated |
Translations; empty (null) in every sample seen. |
languageCode, countryCode |
The review's language (en-us, en-gb, de, ...) and the guest's country. |
travelPurpose |
leisure, business or other. |
stayStatus |
stayed or non_stayed. |
anonymous, isIncentivised, isModerated |
Booking.com flags; anonymous is empty in every sample. |
helpfulVoteCount |
"Helpful" votes the review received. |
author |
name, userId, countryCode, avatar (some guests have none), reviewCount (their number of reviews), type/typeLabel (same ids as the guest-type filter), city, helpfulVoteCount. |
stayedRoom |
The room: roomId, roomName, checkin, checkout, nights, photo. |
reviewerPhotos[] |
Photos the guest added, at four sizes. |
badges, tags |
Booking.com lists, empty in every sample. |
hotelierResponse, hotelierResponseDate |
The hotel's reply and when ({unix, iso}). null when there is none. |
extras |
Anything not mapped, e.g. reviewng: 1 (a Booking.com flag whose meaning is unknown). null when empty. |
30. Stays Questions
What it does. The guest questions of a property with the property's answers, in one language per call - the app's "Questions and answers" screen: the question, the answer, how many guests found it useful (votes), when it was asked and answered, which room it is about, and how fast the property usually answers. One call returns the questions of one language, all in one response (hotel 1169919: 1,150 in English), most-voted first. No single language holds every question of a property: that hotel has 1,589 across languages (see below).
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as the other property endpoints. See the journey overview.
Request
GET /api/v1/stays/questions?hotelId=6966158
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
languageCode |
no, default en-us |
A code from /common/languages. The language of the list: the questions written in it plus the ones translated into it (translatedQuestion/translatedAnswer filled). The default (English) is not every question of the property - questions written in Spanish, Korean, Chinese ... only appear in their own language's list. Call once per language and merge by questionId for more. |
What you get back
{
"status": true,
"message": "Questions found",
"data": {
"hotelId": 6966158,
"optedOut": false,
"collectsQuestions": true,
"averageResponseTime": { "text": "Subject to availability at the property", "summary": "This property usually replies within a few days", "seconds": 8887804 },
"questionCount": 199,
"questions": [
{ "questionId": 24492748, "question": "Hi do you take visa debit?", "translatedQuestion": null,
"answer": "Yes visa, mastercard, american express, discover ...", "translatedAnswer": null, "votes": 60,
"roomId": 696615801, "roomName": null, "language": "en",
"askedAt": "2022-05-12 23:07:01", "askedAtEpoch": 1652396821, "answeredAt": "2022-05-13 10:12:44", "answeredAtFormatted": "2022-05-13 10:12:44", "answeredAtEpoch": 1652436764,
"hidden": false, "isOrCouldBeTranslated": null, "signOff": null, "naiveSentiment": 52,
"extras": { "pxUpsortCovidQAndADsModelWouldResort": 1 } }
],
"extras": null
}
}
| Case | status |
message |
|---|---|---|
| The property has questions | true |
Questions found |
| No questions (a new property, or Q&A switched off) | false |
No questions found (see optedOut, collectsQuestions) |
| Unknown hotel / Booking.com down | false |
Stays questions provider returned HTTP <n> / …is unreachable |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
optedOut |
true when the property switched Q&A off. collectsQuestions: whether guests can still ask. |
averageResponseTime |
How fast the property usually answers: text ("Usually hear back within 4 days", or "Subject to availability at the property"), summary and seconds. |
questions[].questionId |
The question's id (the ids in /stays/property-facilities questionsAndAnswers.questionIds are the 20 most-voted). |
question, answer |
The texts as written. translatedQuestion, translatedAnswer are filled only when languageCode is a translated language. |
votes |
How many guests found the question useful. The list is sorted by it, most first. |
roomId, roomName |
The room the question is about (the roomId of /stays/rooms); null for a question about the property. |
askedAt, answeredAt (+ askedAtEpoch, answeredAtEpoch) |
When, as text and as seconds since 1970. answeredAtFormatted is the same as answeredAt. |
language |
The language of the version returned. |
hidden, isOrCouldBeTranslated, signOff, naiveSentiment |
Booking.com's own fields as sent (naiveSentiment is a score from -100 to 100). |
extras |
Anything Booking.com sends that has no named field here; null when none. |
31. Stays Surroundings
What it does. What is around a property, as the app's "Surroundings" block shows it, in 11 lists: top landmarks, nearby landmarks, beaches, ski lifts, restaurants, cafes and bars, supermarkets, bus stops, metro stops, train stations and airports. Every item has its distance and the walking and driving time and distance.
Where the inputs come from. Pick a property from GET /stays/search and pass its id as hotelId, same as the other property endpoints. See the journey overview.
Request
GET /api/v1/stays/surroundings?hotelId=1150083&languageCode=en-gb&limit=5&maxDistanceKm=25
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
hotelId |
yes | The property's own id, from a GET /stays/search result's data.properties[].id. |
limit |
no, default 5 |
Items per list, 1 to 100. |
maxDistanceKm |
no, default 25 |
How far to look, 1 to 1,000 km. Raise it to see farther airports. |
languageCode |
no, default en-us |
A code from /common/languages. Translates names and decides the unit text: en-gb gives metres and kilometres, en-us feet and miles. |
What you get back
Field names are Booking.com's own, under data.propertySurroundings.
{
"status": true,
"message": "Surroundings found",
"data": {
"propertySurroundings": {
"landmarks": {
"top": [ { "id": "77788", "name": "Rockefeller Center", "latitude": 40.758677, "longitude": -73.978533, "distance": 1.496,
"commute": { "best": { "commuteType": "ByFoot", "commuteDetails": { "distanceLocalized": "1.7 km", "distanceMeters": 1744, "timeLocalized": "20 min", "timeMillis": 1255837 } }, "byFoot": { "distanceLocalized": "1.7 km", "distanceMeters": 1744, "timeLocalized": "20 min", "timeMillis": 1255837 },
"byCar": { "distanceLocalized": "2.2 km", "distanceMeters": 2179, "timeLocalized": "2 min", "timeMillis": 165865 } } } ],
"nearby": [ "..." ]
},
"beaches": [], "skiSurroundings": { "lifts": [] },
"dining": { "restaurants": [ "..." ], "cafeBars": [ "..." ] },
"supermarkets": [ "..." ],
"publicTransport": { "bus": [], "metro": [ "..." ], "train": [ "..." ] },
"airports": [ "..." ]
}
}
}
| Case | status |
message |
|---|---|---|
| The property resolves | true |
Surroundings found (a list with nothing in range is []) |
hotelId doesn't resolve |
false |
Stays surroundings provider error: … |
| Booking.com down / HTTP error | false |
Stays surroundings provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
landmarks.top, landmarks.nearby |
The most popular and the closest landmarks. |
beaches, skiSurroundings.lifts, dining.restaurants, dining.cafeBars, supermarkets, publicTransport.bus / metro / train, airports |
The other lists. Each is an array of the item below, at most limit long. |
item id, name, latitude, longitude |
The place (the id is not an autocomplete id). |
item distance |
Straight-line distance in km. |
item commute.best |
The app's pick: commuteType (ByFoot or ByCar, whichever distance is shorter) and its commuteDetails (same four fields as below). |
item commute.byFoot, commute.byCar |
distanceLocalized and timeLocalized as text (units follow languageCode), distanceMeters and timeMillis as numbers (the real route distance and time). byCar can be null. |
32. Stays Things To Do
What it does. The "Things to do" carousel the app shows on a property page: five bookable attractions (tours, tickets, admissions) near a city or map point, each with its name, a "From" price, "Free cancellation available", a badge such as "Bestseller", a photo and a link to book. It also returns the "See all" link and the "Good to know" footnote. The full list behind "See all", with filters, sorting and paging, is GET /attractions/search.
Where the inputs come from. Part 3 (Around the property) in the journey overview. It takes a place, not a hotelId: a city (city:<id>, from GET /stays/autocomplete) or a map point. For a property from GET /stays/search, take its coordinates (location.latitude, location.longitude) or its location.destinationId from GET /stays/property-details: latlong:<latitude>,<longitude> or city:<destinationId>.
Request
GET /api/v1/stays/things-to-do?destination=city:20088325&checkin=2026-12-01&checkout=2026-12-03¤cyCode=USD&languageCode=en-us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
destination |
yes | city:<id> (copy from a type: "city" suggestion of /stays/autocomplete) or a map point latlong:<latitude>,<longitude>. Any other type (hotel, airport, landmark, district, region) is rejected: Booking.com returns nothing for them. For a property or landmark use its coordinates. |
checkin, checkout |
no, both or neither. Left out: tomorrow and the day after, and datesAreDefault is true |
YYYY-MM-DD, same date rules as /stays/search. They change the prices and the links; the attractions themselves are the same. Booking.com only answers from about 3 days back to 180 days ahead; outside that the list is empty. Only one of the two is rejected. |
currencyCode |
no, default USD |
A code from /common/currencies. |
languageCode |
no, default en-us |
A code from /common/languages. |
What you get back
{
"status": true,
"message": "Things to do found",
"data": {
"datesAreDefault": false,
"checkin": "2026-10-22",
"checkout": "2026-10-23",
"title": "Things to do",
"distributionId": "2OIAFHV1r6MkX8RHL8bcu",
"seeAll": { "text": "See all", "url": "https://ch.booking.com/c?target=...", "webUrl": "https://www.booking.com/attractions/searchresults/us/new-york.en-gb.html?end_date=2026-10-23&selected_currency=INR&dest_id=20088325&start_date=2026-10-22&..." },
"footnote": { "text": "Certain conditions apply.", "linkText": "Show details", "details": { "title": "Good to know", "points": [ "Free cancellation policy may change based on the booking dates you select." ], "dismissText": "Got it" } },
"attractionCount": 5,
"attractions": [
{
"id": "PRCMOkYUz7Um",
"rank": 1,
"vertical": "ATTRACTION",
"name": "SUMMIT One Vanderbilt Tickets",
"perks": [ "Free cancellation available" ],
"badges": [ { "text": "Bestseller", "variant": "brand_primary" } ],
"price": { "label": "From", "amount": "₹ 4,549", "originalAmount": null, "text": "From ₹ 4,549" },
"image": { "url": "https://r-xx.bstatic.com/xdata/images/xphoto/300x320/662759882.jpg?k=...", "aspectRatio": 1.5 },
"url": "https://ch.booking.com/c?target=...",
"webUrl": "https://www.booking.com/attractions/searchresults/us/new-york.en-gb.html?...&pinned_product=PRCMOkYUz7Um&...",
"extras": null
}
]
}
}
| Case | status |
message |
|---|---|---|
| At least one attraction | true |
Things to do found |
| Nothing for this place or these dates (outside the date window, unknown city) | false |
No things to do found (attractions: [], title: null) |
| Booking.com down / error | false |
Stays things-to-do provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
datesAreDefault, checkin, checkout |
The dates used for the prices and links. datesAreDefault is true when you sent none and tomorrow / the day after were used. |
title |
The carousel heading, translated ("Things to do"). |
distributionId |
Booking.com's id for this set of recommendations (also inside the links). |
seeAll |
The "See all" button: text, url (Booking.com's click-tracking redirect) and webUrl (the booking.com attractions search it leads to, decoded from the redirect). |
footnote |
The line under the carousel and the pop-up its link opens: text, linkText, details {title, points[], dismissText}. null when none. |
attractions[].id |
Booking.com's product id (PR…); it is also the pinned_product in the link. |
attractions[].rank |
Position in the carousel (1 = first). |
attractions[].vertical |
Always ATTRACTION so far. |
attractions[].name |
The attraction's name, in the requested language where the supplier translates it. |
attractions[].perks |
Green selling points, e.g. "Free cancellation available". |
attractions[].badges |
text and style variant ("Bestseller"). Empty on attractions without one. |
attractions[].price |
label ("From"), amount (display text such as ₹ 4,549, US$48, € 18: formatted for the currency and language, not a number), originalAmount (a struck-through amount if the app shows one, else null) and text (label and amount together). |
attractions[].image |
url (300×320) and aspectRatio. |
attractions[].url, webUrl |
The click-tracking redirect and the booking.com page it leads to (attractions search for the city, with your dates and pinned_product). |
attractions[].extras |
Anything on the card that was not recognised; null so far. |
Shared lookups
33. Common Languages (shared by every module)
What it does. The list of language codes accepted by the languageCode parameter. It lives in the shared common module because it is not specific to stays: flights, car rentals, taxis and attractions use the same list. Today it is used by stays suggestions and stays search. Stays autocomplete has no language parameter: its results follow the language of the search text.
Where the inputs come from. Nothing: no parameters. Use the languageCode values it returns in every endpoint that has a languageCode parameter.
Request
GET /api/v1/common/languages
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
What you get back
{
"status": true,
"message": "Languages",
"data": {
"default": "en-us",
"count": 45,
"languages": [
{ "languageCode": "en-us", "name": "English (US)", "nativeName": "English (US)" },
{ "languageCode": "hi", "name": "Hindi", "nativeName": "हिन्दी" },
{ "languageCode": "pt-br", "name": "Portuguese (Brazil)", "nativeName": "Português (Brasil)" }
]
}
}
| Field | Meaning |
|---|---|
languageCode |
Lower-case Booking.com site language code; the same name and value you send as the languageCode parameter. Region codes exist: en-us, en-gb, es-ar, es-mx, pt-pt, pt-br, zh-cn, zh-tw. Hindi is plain hi; en-hi is not a valid code. |
name |
English name. |
nativeName |
The language's own name, for showing in a language picker. |
default |
Used when languageCode is not sent: en-us. |
34. Common Currencies (shared by every module)
What it does. The list of currency codes accepted by the currencyCode parameter. Like languages it lives in the shared common module because flights, cars and taxis will price in the same currencies.
Where the inputs come from. Nothing: no parameters. Use the currencyCode values it returns in every endpoint that has a currencyCode parameter. flights: true marks the codes that can be used for flight prices.
Request
GET /api/v1/common/currencies
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
What you get back
{
"status": true,
"message": "Currencies",
"data": {
"default": "USD",
"count": 145,
"flightsCount": 34,
"currencies": [
{ "currencyCode": "AED", "name": "United Arab Emirates Dirham", "flights": true },
{ "currencyCode": "AFN", "name": "Afghan Afghani", "flights": false },
{ "currencyCode": "INR", "name": "Indian Rupee", "flights": true },
{ "currencyCode": "USD", "name": "US Dollar", "flights": true }
]
}
}
currencyCode is the ISO 4217 code (same name and value you send as the currencyCode parameter); name is the English name. default is used when the parameter is not sent.
35. Common Exchange Rates (shared by every module)
What it does. Booking.com's own exchange rates: for one base currency, how many units of each of 189 currencies one unit of the base buys, with the day the rates are from. It sits next to GET /common/currencies because it is app-wide, not specific to stays; use it to show a price in another currency or to compare prices. - What was already available: only the list of currency codes (/common/currencies). No endpoint gave rates. (Prices in /stays/search, /stays/rooms and the others are already converted by Booking.com into the currencyCode you ask for.)
Where the inputs come from. The base currency is a currencyCode from GET /common/currencies.
Request
GET /api/v1/common/exchange-rates?baseCurrency=USD
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
baseCurrency |
no, default USD |
A 3-letter currency code, upper or lower case (see /common/currencies; rates exist for 189 codes, a few more than that list). An unknown code answers status false. |
What you get back
{
"status": true,
"message": "Exchange rates found",
"data": {
"baseCurrency": "USD",
"baseCurrencyName": "US Dollar",
"date": "2026-10-18",
"ageDays": 1,
"stale": false,
"attempts": 1,
"rateCount": 189,
"rates": [
{ "currencyCode": "EUR", "name": "Euro", "usableAsCurrencyCode": true, "exchangeRateBuy": 0.88865192 },
{ "currencyCode": "INR", "name": "Indian Rupee", "usableAsCurrencyCode": true, "exchangeRateBuy": 94.95371944 },
{ "currencyCode": "VEB", "name": null, "usableAsCurrencyCode": false, "exchangeRateBuy": 2000000 }
],
"extras": null
}
}
| Case | status |
message |
|---|---|---|
| Rates came back | true |
Exchange rates found |
| Unknown base currency | false |
No exchange rates found for this base currency |
| Booking.com down / HTTP error | false |
Exchange rates provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
baseCurrency, baseCurrencyName |
The base currency and its English name (when it is in /common/currencies). |
date |
The day the rates are from (YYYY-MM-DD). |
ageDays |
Whole days between date and today (UTC); normally 1. |
stale |
true when the rates are still older than 2 days after all retries; use them with care or ask again later. |
attempts |
How many Booking.com calls this request made (1 to 5). |
rates[].currencyCode |
The currency. Sorted by code. |
rates[].exchangeRateBuy |
How many units of this currency one unit of the base buys: an amount in the base times this number is the amount in this currency. 1 for the base itself. |
rates[].name |
English name; null for codes not in the currency list. |
rates[].usableAsCurrencyCode |
true when the code is accepted as currencyCode by the other endpoints. |
extras |
Anything Booking.com sends that has no named field here; null when none. |
Attractions and things to do
36. Attractions Autocomplete
What it does. Destinations, points of interest and attractions that match typed text.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/autocomplete
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
query |
yes | The text typed, 1 to 100 characters. |
limit |
no | 1 to 50, default 5. Applies to products; destinations and pointsOfInterest stop at 10 whatever the limit (measured at 10, 50, 200). |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Autocomplete",
"data": {
"destinations": [
{
"cityName": "Statte",
"country": "Italy",
"productCount": 293,
"ufi": -130183,
"destination": "city:-130183"
}
],
"pointsOfInterest": [
{
"cc1": "us",
"country": "United States",
"cityName": "Memphis",
"id": "DRc0CyRFL00f",
"scopeName": "Statue of Elvis",
"ufi": 20123619,
"destination": "city:20123619"
},
{
"cc1": "jp",
"country": "Japan",
"cityName": "Tokyo",
"id": "DRwLyWfuAHaE",
"scopeName": "Hachiko Statue",
"ufi": -246227,
"destination": "city:-246227"
}
],
"products": [
{
"cityUfi": 20088325,
"cityName": "New York",
"countryCode": "us",
"productId": "PRJi4JHoYUQw",
"productSlug": "prji4jhoyuqw-afternoon-statue-of-liberty-tour",
...
| Field | Meaning |
|---|---|
destinations[].destination, pointsOfInterest[].destination |
Use this one. city:<id> for the destination parameter of suggestions, search and search-filters. A landmark's own id goes in filters as landmark::<id>. |
destinations[].ufi |
The city id inside it. |
pointsOfInterest[].id / ufi |
Landmark id and its city id. |
products[].productId |
The id for reviews and the calendar. |
products[].productSlug |
The whole slug for product and availability. |
status |
message |
When |
|---|---|---|
true |
Autocomplete |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
37. Attractions Destinations
What it does. The best-selling attraction cities of a country. Its ufi is the city id used by suggestions.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/destinations
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
countryCode |
yes | Two-letter country code, e.g. us, in, fr. An unknown code gives an empty cities list. |
limit |
no | 1 to 5, default 5. A bigger number is cut to 5 by Booking.com, so it is rejected here (measured with 0, 1-6, 10, 50, 1000). |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Destinations",
"data": {
"cities": [
{
"country": {
"name": "United States"
},
"distance": null,
"imageUrl": "https://q-xx.bstatic.com/xdata/images/city/720x405/977436.jpg?k=ee0baaf82d482fae02bcb8dda25be1abff1da43d187bbb…",
"productCount": 2152,
"ufi": 20088325,
"ufiCity": "New York",
"destination": "city:20088325"
},
{
"country": {
"name": "United States"
},
"distance": null,
"imageUrl": "https://q-xx.bstatic.com/xdata/images/city/720x405/976876.jpg?k=0431a4ff8274f5ddd491d12e5cb34ce5ef2afd67b1adf1…",
"productCount": 647,
"ufi": 20050264,
"ufiCity": "New Orleans",
"destination": "city:20050264"
}
]
}
}
| Field | Meaning |
|---|---|
destination |
Use this one. city:<id>, ready for the destination parameter of suggestions, search and search-filters. |
ufi |
The city id inside it. |
ufiCity |
City name. |
country.name |
Country. |
productCount |
Attractions in the city. |
imageUrl |
City image. |
distance |
Always null here. |
status |
message |
When |
|---|---|---|
true |
Destinations |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
38. Attractions Suggestions
What it does. Attractions Booking.com suggests for a city, with the discounted ones listed in discountedProductIds.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/suggestions
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
destination |
yes | city:<id> exactly as returned in destination by destinations or autocomplete, e.g. city:20088325. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Suggestions",
"data": {
"discountedProductIds": [
"PR473pyq8Tgw"
],
"dealsOfTheMonth": null,
"products": [
{
"cancellationPolicy": {
"hasFreeCancellation": true
},
"distances": {
"distanceFromSearchInputCoordinates": null,
"distanceToAccommodation": null
},
"duration": {
"label": "Duration: 55 minutes",
"value": "PT55M"
},
"earlyBookingStats": null,
"flags": null,
"hasFreeGeniusUpgrades": false,
"id": "PR473pyq8Tgw",
"name": "NYC Statue of Liberty Express Sightseeing Cruise",
"offers": [
{
"availabilityType": "date_time",
"id": "OFY58IIqgk28",
"items": [
"…"
]
}
],
"photos": [
{
"caption": "the statue of liberty on the water with a cruise ship",
"gallery": "https://q-xx.bstatic.com/xdata/images/xphoto/max1200/751560094.webp?k=da0d2572461ec21e9786ccb821c9ddea287aaa26…",
"isPrimary": true,
...
Each products[] item has the same fields as an attraction of search (id, slug, name, representativePrice, photos, offers ...), under Booking.com's own names.
status |
message |
When |
|---|---|---|
true |
Suggestions |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
39. Attractions Search
What it does. Every bookable attraction (tickets, tours, activities) in a city, with the filter menus, sort options and paging the app shows behind "Things to do → See all". Each attraction has its name, short description, price (with supplier discounts), free cancellation, duration, review score, flags (Bestseller, Skip the line, Audio guide ...), photos and offers.
Where the inputs come from. The Attractions vertical (separate from Stays, like Flights, Car rental and Taxi) - see "Attractions" in the journey overview. The stays endpoint GET /stays/things-to-do is the five-card carousel on a hotel page; this is the full list behind its "See all" link. The detail, reviews and availability calls of one attraction will live here too, once captured. It takes a city (city:<id>, from GET /stays/autocomplete, or city:<location.destinationId> from GET /stays/property-details); pass a property's coordinates as latitude/longitude to get each attraction's distance from it.
Request
GET /api/v1/attractions/search?destination=city:20088325&checkin=2026-12-20&checkout=2026-12-21&filters=label::free_cancellation,rating::4.5&sortBy=lowest_price&pageSize=20&page=1¤cyCode=USD
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
destination |
yes | city:<id>: the destination of /attractions/autocomplete or /attractions/destinations (or a type: "city" suggestion of /stays/autocomplete, or city:<location.destinationId> of /stays/property-details). Other types and latlong: are rejected. |
checkin, checkout |
no (both or neither) | YYYY-MM-DD, same date rules as /stays/search. Keeps only attractions bookable in that window and prices them for it. |
latitude, longitude |
no (both or neither) | A point, e.g. a property's coordinates. Fills distances.fromSearchPointMeters in metres. |
query |
no | Free-text search, up to 100 characters. |
productIds |
no | Comma list of attractions[].id to look up. |
minReviewCount |
no | Whole number 0-100000: only attractions with at least that many reviews (New York: 2143 attractions, 420 with 10+, 113 with 100+, 13 with 1000+). It also lowers unfilteredCount. The menu alone, without products: search-filters. |
filters |
no | Comma list of family::value, copied from filterGroups[].options[].filter of a previous response. Families: landmark, area, label, type, language, rating (one value only), time. Several values of one family are OR; families are AND. |
sortBy |
no | A sorters[].value from a previous response. Omitted: Booking.com's default (trending, or most relevant with query). |
page |
no, default 1 | page × pageSize must be at most 10,000. |
pageSize |
no, default 20 | 1–500. |
currencyCode |
no, default USD |
A code from /common/currencies. |
languageCode |
no, default en-us |
A code from /common/languages. |
What you get back
{
"status": true,
"message": "Attractions found",
"data": {
"totalCount": 1748,
"unfilteredCount": 1748,
"page": 1,
"pageSize": 20,
"hasNextPage": true,
"isSuggestion": false,
"defaultSorter": { "name": "Our top picks", "value": "trending" },
"sorters": [ { "name": "Our top picks", "value": "trending" }, { "name": "Lowest price", "value": "lowest_price" }, { "name": "Best reviewed", "value": "highest_weighted_rating" } ],
"filterGroups": [
{ "family": "label", "providerName": "labelFilters", "options": [ { "name": "Free cancellation", "productCount": 1522, "tag": "free_cancellation", "filter": "label::free_cancellation", "children": [], "extras": null } ] },
{ "family": "type", "providerName": "typeFilters", "options": [ { "name": "Tours ", "productCount": 1200, "tag": "PTCMCuXtHgrC", "filter": "type::PTCMCuXtHgrC", "children": [ { "name": "Walking & hiking tours", "productCount": 479, "tag": "PTCMC74RQHpJ", "filter": "type::PTCMC74RQHpJ" } ], "extras": null } ] }
],
"attractionCount": 20,
"attractions": [
{
"id": "PRZtshIDqvnN",
"name": "The Museum of Modern Art Admission",
"slug": "prztshidqvnn-the-museum-of-modern-art-admission",
"shortDescription": "A ticket to explore the art museum and see some of the most popular artworks",
"availableFrom": "2026-10-22",
"price": { "chargeAmount": 2848.61, "publicAmount": 2848.61, "currency": "INR", "discounts": [], "extras": null },
"hasFreeCancellation": false,
"hasFreeGeniusUpgrades": false,
"duration": { "label": "Duration: 2 hours", "value": "PT2H", "minutes": 120 },
"reviews": { "average": 9, "total": 13, "scale": "TEN_POINT", "originalScale": "FIVE_POINT", "reviewScore": "WONDERFUL", "scoreWord": "Fabulous", "categories": [ { "categoryName": "easyToAccess", "average": 4.8, "total": 5 } ], "extras": null },
"flags": [ { "flag": "aiBadgesAdmissionIncluded", "rank": 0.1, "value": true, "label": null } ],
"distances": { "fromSearchPointMeters": null, "toAccommodationMeters": null, "toAccommodationDescription": null },
"primaryPhotoUrl": "https://q-xx.bstatic.com/xdata/images/xphoto/300x320/403849877.webp?k=...",
"photos": [ { "photoId": 403849877, "isPrimary": true, "galleryUrl": "https://q-xx.bstatic.com/xdata/images/xphoto/max1200/403849877.webp?k=...", "mediumUrl": "https://r-xx.bstatic.com/xdata/images/xphoto/900x600/403849877.webp?k=...", "caption": "a view of the city from the top of a skyscraper", "extras": null } ],
"offers": [ { "id": "OF6QAt39k8m9", "availabilityType": "date_time", "itemIds": [ "OIH87uMSWfPa" ] } ],
"earlyBookingStats": null,
"supportsNativeApp": true,
"selfFundedDiscountTrackingSupported": null,
"location": { "cityName": "New York", "ufi": 20088325, "countryCode": "us" },
"extras": null
}
...
| Case | status |
message |
|---|---|---|
| At least one attraction | true |
Attractions found |
| Search text with no match | true |
Nothing matched; these are Booking.com suggestions (totalCount: 0, isSuggestion: true) |
| Nothing for the city, dates or filters | false |
No attractions found |
| Booking.com answered with its own error | false |
Booking.com could not return attractions: … |
| Booking.com down / error | false |
Stays attractions provider is unreachable / …returned HTTP <n> / …provider error: <message> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
totalCount, unfilteredCount |
Attractions matching your filters / in the city before any filter (with dates, only the bookable ones). |
hasNextPage |
page × pageSize < totalCount. |
isSuggestion |
true when a text search matched nothing and the list holds Booking.com's suggestions instead. |
sorters, defaultSorter |
The sort menu for this search. Pass value as sortBy. |
filterGroups[] |
One per filter family that has options: family (our name), providerName (Booking.com's menu name), options[] with name, productCount (follows the filters applied), tag, filter (the exact family::value string for filters) and children (sub-types of a type). |
attractions[].id |
Booking.com's product id (PR…). |
price |
chargeAmount (what you pay), publicAmount (the list price before the supplier discount), currency, and discounts[] (chargeAmountDifference, discountCampaign, discountProvider, labels, upgradesOfferItem). These are numbers. |
availableFrom |
First bookable date. |
duration |
label (translated), value (ISO 8601, e.g. PT72H) and minutes. null when the attraction has none. |
reviews |
average on scale (TEN_POINT; originalScale is the supplier's FIVE_POINT), total reviews, reviewScore / scoreWord, and four categories (easyToAccess, facilitiesRating, qualityOfService, valueOfExperience). null for attractions with no reviews (about a third). |
flags[] |
Badges: bestseller (label "#1 Best seller in New York"), exclusiveForBooking, newproduct, and the aiBadges… set: ExpertGuide, AdmissionIncluded, Pickup, SkipTheLine, Audio. |
distances |
fromSearchPointMeters when latitude/longitude were given; the two accommodation fields are always null so far. |
photos[] |
All photos (galleryUrl 1200 px, mediumUrl 900×600) with caption (translated). primaryPhotoUrl is the 300×320 thumbnail. |
offers[] |
Booking.com's offer ids and availabilityType (date_time or no_date_time), with each offer's itemIds. |
earlyBookingStats, supportsNativeApp, selfFundedDiscountTrackingSupported |
Booking.com's own flags; earlyBookingStats was never populated in 1,520 products. |
location |
cityName, ufi and countryCode of the attraction. |
40. Attractions Search Filters
What it does. The filter menu of an attractions search without the products: every filter with the number of attractions it would leave. Lighter than search, whose filterGroups it repeats exactly.
Where the inputs come from. The attractions journey in the journey overview.
Request
GET /api/v1/attractions/search-filters
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
destination |
yes | city:<id> (as in search). |
checkin, checkout |
no | Both or neither, YYYY-MM-DD. |
latitude, longitude |
no | Both or neither. |
filters |
no | family::value list, as in search; the counts follow them. |
minReviewCount |
no | Whole number 0-100000: only attractions with at least that many reviews. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
Sort, paging, text and product ids are not parameters here.
What you get back
{
"status": true,
"message": "Filters found",
"data": {
"totalCount": 113,
"unfilteredCount": 113,
"filterGroups": [
{
"family": "landmark",
"providerName": "destinationFilters",
"options": [
{
"name": "Statue of Liberty",
"productCount": 31,
"tag": "DRzgorRcotfZ",
"filter": "landmark::DRzgorRcotfZ",
"children": [],
"extras": null
}
]
}
],
"extras": null
}
}
Each option's filter is what filters takes. See filters.md.
status |
message |
When |
|---|---|---|
true |
Filters found |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
41. Attraction Product
What it does. One attraction in full: description, highlights, what is included and not, itinerary, offers, photos, review summary, cancellation policy, addresses, operator and similar attractions.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/product
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
slug |
yes | The whole slug of a product in search (id and name together, lowercase). The bare id is rejected: Booking.com answers "not found". |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Attraction",
"data": {
"product": {
"accessibility": [
"Accessible to pushchairs/prams"
],
"additionalBookingInfo": null,
"additionalInfo": "Suitable for all physical fitness levels\n\nPlease arrive 30 min prior to boarding time. Boarding will begin app…",
"addresses": {
"arrival": [
{
"address": "Pier 78 at Hudson River Park, 12th Ave 455",
"city": "New York, NY",
"country": "us",
"googlePlaceId": "ChIJCwHl5EpYwokR-q8jdQg_ER8",
"id": "LO3NKhflY06b",
"instructions": null,
"latitude": "40.759715",
"locationType": "arrival",
"longitude": "-74.0039699",
"publicTransport": null,
"zip": "10018"
}
],
"attraction": null,
"departure": [
{
"address": "Pier 78 at Hudson River Park, 12th Ave 455",
"city": "New York, NY",
"country": "us",
"googlePlaceId": "ChIJCwHl5EpYwokR-q8jdQg_ER8",
"id": "LO2ip3h3WcXo",
"instructions": "Located on the north side of Pier 78. Look for Starship Ticket Booth specifically and all the blue canopies",
"latitude": "40.759715",
"locationType": "departure",
"longitude": "-74.0039699",
"publicTransport": null,
"zip": "10018"
...
Booking.com's own field names are kept and nothing is dropped; only the service type markers are removed. Ids from here: offers[].id and offers[].items[].
status |
message |
When |
|---|---|---|
true |
Attraction |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
42. Attraction Comparison
What it does. The short "compare" view of an attraction: addresses, what is and is not included.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/comparison
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
slug |
yes | The whole slug of a product in search. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Attraction comparison",
"data": {
"product": {
"addresses": {
"arrival": [
{
"address": "Pier 78 at Hudson River Park, 12th Ave 455",
"city": "New York, NY",
"country": "us",
"googlePlaceId": "ChIJCwHl5EpYwokR-q8jdQg_ER8",
"id": "LO3NKhflY06b",
"instructions": null,
"latitude": "40.759715",
"locationType": "arrival",
"longitude": "-74.0039699",
"publicTransport": null,
"zip": "10018"
}
],
"attraction": null,
"departure": [
{
"address": "Pier 78 at Hudson River Park, 12th Ave 455",
"city": "New York, NY",
"country": "us",
"googlePlaceId": "ChIJCwHl5EpYwokR-q8jdQg_ER8",
"id": "LO2ip3h3WcXo",
"instructions": "Located on the north side of Pier 78. Look for Starship Ticket Booth specifically and all the blue canopies",
"latitude": "40.759715",
"locationType": "departure",
"longitude": "-74.0039699",
"publicTransport": null,
"zip": "10018"
}
],
"entrance": null,
"guestPickup": null,
"meeting": null,
...
status |
message |
When |
|---|---|---|
true |
Attraction comparison |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
43. Attraction Review Snippets
What it does. The reviews shown on the product page, with the total number of reviews. For paging, sorting and filters use reviews.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/review-snippets
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
productId |
yes | The id of a product in search, e.g. PRrBHbvtdbF5. |
limit |
no | 2 to 300, default 10. Measured: 1 returns no reviews, 301 and more is an Booking.com HTTP 500, so both are rejected. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Review snippets",
"data": {
"total": 1852,
"reviews": [
{
"content": "We spend a wonderfully time. It was an incredible experience that we will never forget",
"epochMs": 1743245765000,
"id": "RS2l2kQ9JZLT",
"language": "en-gb",
"numericRating": 10,
"originalScale": "FIVE_POINT",
"providerName": null,
"scale": "TEN_POINT",
"travelPartnerTypes": [
"family"
],
"user": {
"avatar": null,
"cc1": "co",
"name": "Sanchez Gooding"
},
"votes": {
"count": 1,
"userVoted": false
},
"photos": []
},
{
"content": "We all enjoyed a fantastic sailing . Darius was an informative and entertaining host.",
"epochMs": 1760858971000,
"id": "RSdGLsYFruBI",
"language": "en-gb",
"numericRating": 10,
"originalScale": "FIVE_POINT",
"providerName": null,
"scale": "TEN_POINT",
"travelPartnerTypes": [
"family"
...
| Field | Meaning |
|---|---|
total |
All reviews of the attraction. |
reviews[].numericRating |
Rating on scale. |
reviews[].epochMs |
When it was written (milliseconds). |
reviews[].travelPartnerTypes |
Who travelled (family, couple ...). |
status |
message |
When |
|---|---|---|
true |
Review snippets |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
44. Attraction Reviews
What it does. Guest reviews of an attraction with paging, sorting, three filters, and the sort and filter menus (with counts).
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/reviews
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
productId |
yes | The id of a product in search. |
page |
no | From 1, default 1. A page past the end is an empty list. |
pageSize |
no | 1 to 300, default 20 (301 is an Booking.com HTTP 500). |
sortBy |
no | most_relevant (default), newest, oldest. Any other value is an Booking.com HTTP 500, so it is rejected. |
time |
no | Time of the visit: Q1 January-March, Q2, Q3, Q4. |
language |
no | A review language id from filters of the answer (en-us, de, pt-br ...). One that the attraction has no reviews in is an error: "is not a review language of this attraction". |
hideEmpty |
no | true leaves out reviews without text (default false). |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Reviews",
"data": {
"total": 426,
"page": 1,
"pageSize": 2,
"defaultSorter": {
"id": "most_relevant",
"label": "Most relevant"
},
"sorters": [
{
"id": "most_relevant",
"label": "Most relevant"
},
{
"id": "newest",
"label": "Newest first"
}
],
"filters": [
{
"name": "hide_empty_reviews",
"label": "Hide reviews without comments",
"selectionType": "binary",
"options": []
},
{
"name": "time",
"label": "Time of year",
"selectionType": "single",
"options": [
{
"id": "Q1",
"label": "January to March",
"count": null
},
{
"id": "Q2",
...
filters[] is the menu: name (hide_empty_reviews, time, language), selectionType, and options[] {id, label, count}. sorters[] is the sort menu.
status |
message |
When |
|---|---|---|
true |
Reviews |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
45. Attraction Availability Calendar
What it does. Which days an attraction can be booked (about 180 days from today) and its lowest price for those days.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/availability-calendar
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
productId |
yes | The id of a product in search. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Availability calendar",
"data": {
"firstDate": "2026-10-21",
"lastDate": "2027-04-19",
"availableCount": 175,
"dates": [
{
"available": true,
"date": "2026-10-21"
},
{
"available": true,
"date": "2026-10-22"
}
],
"defaultJuxtapositionType": "standard",
"availableJuxtapositions": [
{
"juxtapositionType": "standard",
"title": "Free cancellation available",
"message": "Up to 24 hours before the start time",
"applicableTerms": null
}
],
"cheapestPrices": [
{
"offerItemId": "OIzosGatSObj",
"dates": [
"2026-10-21",
"2026-10-22"
],
"price": {
"currency": "USD",
"chargeAmount": 26.24,
"publicAmount": 34.99
},
"convertedPrice": {
"currency": "USD",
...
| Field | Meaning |
|---|---|
dates[] |
One entry per day: date, available. |
availableCount |
Number of bookable days. |
cheapestPrices[] |
Per ticket type (offerItemId): the days it is sold and its lowest price. |
availableJuxtapositions[] |
The cancellation / change terms that apply. |
status |
message |
When |
|---|---|---|
true |
Availability calendar |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
46. Attraction Availability
What it does. The time slots of an attraction on one day, with the tickets (Adult / Child ...), their prices, cancellation terms and languages.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
GET /api/v1/attractions/availability
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
slug |
yes | The whole slug of a product in search. |
date |
yes | The day, YYYY-MM-DD; it must be a real date. A day outside the calendar (past, or about 180 days on) gives timeslotCount: 0. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
| What you get back |
{
"status": true,
"message": "Time slots",
"data": {
"timeslotCount": 4,
"timeslots": [
{
"applicableTerms": null,
"fullDay": false,
"start": "2026-11-26T10:00:00-05:00",
"timeSlotId": "ATS-PRrBHbvtdbF5-202611261000-nullnull",
"timeSlotOffers": [
{
"additionalInfo": null,
"benefits": "…",
"description": "Panoramic views of the New York City skyline and landmarks",
"id": "OFmPPmNnL0c3",
"juxtapositions": [
"…"
],
"label": "General Cruise Admission",
"languageOptions": [
"…"
],
"locationInstructions": null,
"notIncluded": null,
"reservationRestrictions": "…",
"typicalDuration": null,
"whatsIncluded": null
}
]
}
]
}
}
| Field | Meaning |
|---|---|
timeslots[].start |
Start time with the local offset. |
timeslots[].timeSlotOffers[] |
The options of the slot (language, guide, inclusions). |
...juxtapositions[].items[] |
The tickets: id (starts with ATO-), offerItemId, label, price, ticketsAvailable, minPerReservation, maxPerReservation. |
The id and price of an item are what live availability takes.
status |
message |
When |
|---|---|---|
true |
Time slots |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
47. Attraction Live Availability
What it does. Checks right now that chosen tickets can still be booked. Read-only: nothing is reserved or booked.
Where the inputs come from. The attractions journey in the journey overview: autocomplete / destinations -> search -> product, reviews, availability.
Request
POST /api/v1/attractions/live-availability
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
Body (JSON):
| Parameter | Required | Rule |
|---|---|---|
items |
yes | 1 to 20 tickets. |
items[].timeSlotOfferItemId |
yes | id of a ticket in availability (starts with ATO-). |
items[].quantity |
yes | Whole number 1 to 1000. 0 or less is an Booking.com HTTP 500. |
items[].amount |
yes | That ticket's price.chargeAmount. Required Booking.com (HTTP 400 without); a wrong value did not change the answer. |
items[].currency |
yes | That ticket's price.currency. |
What you get back
{
"status": true,
"message": "Live availability",
"data": {
"state": "available",
"reason": null
}
}
state is available, unavailable or unknown; reason explains it (unavailable_on_booking, error_on_provider) or is null.
status |
message |
When |
|---|---|---|
true |
Live availability |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
48. Attraction Legal Consent
What it does. The consent texts shown before booking: terms and conditions, privacy statement, right of withdrawal and the detailed supplier terms with their links.
Where the inputs come from. The attractions journey in the journey overview.
Request
GET /api/v1/attractions/legal-consent
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
productId |
yes | The id of a product in search. Decides the supplier in the details. |
supplierName |
no | Supplier name (e.g. Viator). Without it the booking-terms consent is left out. |
buttonLabel |
no | Name of the booking button quoted in the text; default Next step. |
dataPrivacy |
no | Include the privacy consent; default true. |
rightOfWithdrawal |
no | Include the right-of-withdrawal text; default false. |
termsDetails |
no | Include the detailed terms (supplier and Booking.com, with links); default false. |
currencyCode |
no | A code of /common/currencies. Default USD. |
languageCode |
no | A code of /common/languages. Default en-us. |
What you get back
{
"status": true,
"message": "Legal consents",
"data": {
"consents": [
{
"actions": [
{
"actionType": "tnc-booking-supplier-details",
"label": "Terms and conditions and privacy policy",
"url": null
}
],
"consentName": "tnc-booking-supplier",
"consentText": {
"text": "By clicking \"Next step\" and completing a booking, you agree with the terms and conditions and privacy policy o…"
},
"consentType": "plain",
"required": null,
"validationErrorMessage": null
},
{
"actions": null,
"consentName": "right-of-withdrawal",
"consentText": {
"text": "The statutory consumer law right of withdrawal does not apply when you book this product."
},
"consentType": "plain",
"required": null,
"validationErrorMessage": null
}
]
}
}
consents[].actions[] are the links (url is null when the action opens the details instead).
status |
message |
When |
|---|---|---|
true |
Legal consents |
Success. |
false |
Validation failed |
A parameter is missing or wrong (the errors list names it; no quota used). |
false |
Attractions provider … |
Booking.com failed or is unreachable (HTTP 502). |
Flights
49. Flights Autocomplete
What it does. The places (cities and airports) matching what the traveller typed. Each result carries a ready-made token ("BOM.CITY", "DEL.AIRPORT") - exactly what GET /flights/search takes in from and to.
Where the inputs come from. Step 1 of the flights journey in the journey overview: find the places -> search -> details -> fare quote.
Request
GET /api/v1/flights/autocomplete?q=mum
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
q |
yes | What the user typed, 1 to 100 characters. |
languageCode |
no, default en-us |
data.languages[].languageCode of GET /common/languages; names come back in that language. |
What you get back
{
"status": true,
"message": "Places found",
"data": {
"places": [
{ "token": "BOM.CITY", "type": "CITY", "code": "BOM", "name": "Mumbai", "cityCode": null, "cityName": null, "regionName": "Maharashtra", "country": "IN", "countryName": "India", "countryNameShort": null, "photo": "https://q-xx.bstatic.com/xdata/images/city/square150/1000023.jpg?k=…", "distanceToCity": null, "parentCode": null },
{ "token": "BOM.AIRPORT", "type": "AIRPORT", "code": "BOM", "name": "Chhatrapati Shivaji International Airport Mumbai", "cityCode": "BOM", "cityName": "Mumbai", "regionName": "Maharashtra", "country": "IN", "countryName": "India", "countryNameShort": "India", "photo": "…", "distanceToCity": { "value": 15.74, "unit": "km" }, "parentCode": "BOM" }
]
}
}
| Case | status |
message |
|---|---|---|
| At least one place | true |
Places found |
| Nothing matches | true |
No places found (empty places) |
| Booking.com error | false |
the mapped message, e.g. Booking.com rejected the search text |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
token |
<code>.<TYPE>: pass it as from / to of /flights/search. A CITY token covers every airport of the city; an AIRPORT token that one airport. |
type |
CITY or AIRPORT. |
code |
The IATA code (BOM). A city and its main airport can share a code; the type tells them apart. |
name, regionName, country (ISO), countryName, countryNameShort |
Place names in languageCode. |
cityCode, cityName, parentCode |
Airports only: the city they belong to. |
distanceToCity |
Airports only: { value, unit } from the airport to the city centre. |
photo |
A square photo of the city. |
extras |
Present only if Booking.com adds a field this API does not map yet. |
50. Flights Fly Anytime ("I'm flexible")
What it does. The dates Booking.com picks for a month and a trip length - the app's "I'm flexible" tab (a weekend / a week / two weeks, in a month). Give the route, the month and the length; get back one departure and one return date to put into /flights/search.
Where the inputs come from. An alternative to typing dates, between autocomplete and search in the journey overview.
Request
GET /api/v1/flights/fly-anytime?from=BOM.CITY&to=DEL.AIRPORT&duration=WEEKS&weeks=2&month=2026-12
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
from, to |
yes | One place each: data.places[].token of GET /flights/autocomplete, e.g. BOM.CITY, DEL.AIRPORT. |
duration |
yes | A fixed list (no endpoint returns it): WEEKEND or WEEKS. |
weeks |
with WEEKS |
1 or 2. |
month |
yes | Chosen by the user. YYYY-MM, from next month up to 12 months ahead. |
What you get back
{ "status": true, "message": "Dates found", "data": { "departure": "2026-12-19", "return": "2026-12-31", "nights": 12, "estimated": false } }
nights is added by this API (return minus departure). estimated is Booking.com's flag: true means the dates are a guess, not a priced find. Use data.departure and data.return as depart / return of /flights/search.
51. Flights Search
What it does. The flights list for a one-way, round-trip or multi-city trip: the offers (price, flights, times, stops, baggage, fare), the filter menu with counts, the best / cheapest / fastest deals of the whole result, sorting and paging - all from one Booking.com call.
Where the inputs come from. Step 2 of the flights journey in the journey overview. The places come from /flights/autocomplete (or the dates from /flights/fly-anytime); each offer's id goes to /flights/details.
Request
GET /api/v1/flights/search?from=BOM.CITY&to=DEL.AIRPORT&depart=2026-11-20&return=2026-11-28&adults=1¤cyCode=INR&sort=CHEAPEST&airlines=AI,6E&stops=1
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
from, to |
yes | The token of a place: data.places[].token of GET /flights/autocomplete, e.g. BOM.CITY, DEL.AIRPORT. Several places in a leg: comma (DEL.AIRPORT,HDO.AIRPORT). Several legs (multi-city): ` |
depart |
ONEWAY / ROUNDTRIP | Chosen by the user, or data.departure of GET /flights/fly-anytime. YYYY-MM-DD, today up to 359 days ahead. |
return |
ROUNDTRIP | Chosen by the user, or data.return of GET /flights/fly-anytime. YYYY-MM-DD, not before depart, up to 360 days ahead. Giving it makes the trip a round trip. |
legDates |
MULTISTOP | Chosen by the user (no endpoint lists dates). One date per leg separated by ` |
type |
no | ONEWAY, ROUNDTRIP, MULTISTOP. Worked out from legDates / return when missing; contradictions are rejected. |
adults |
no, default 1 | 1 to 9. |
childrenAges |
no | Comma-separated ages 0-17 (4,12). Adults + children at most 9; ages 0 and 1 are infants (one adult each). |
cabinClass |
no, default ECONOMY |
A fixed list (no endpoint returns it): ECONOMY, PREMIUM_ECONOMY, BUSINESS, FIRST. |
currencyCode |
no, default USD |
A code from GET /common/currencies whose entry has flights: true - 34 of the 145: AED AUD BRL CAD CHF CLP COP CZK DKK EUR GBP HKD HUF IDR INR JPY KRW KWD KZT MXN MYR NOK NZD PEN PLN QAR SAR SEK SGD THB UAH USD VND ZAR. The others are not priced for flights. |
sort |
no, default BEST |
A fixed list (no endpoint returns it): BEST, CHEAPEST, FASTEST. |
page, limit |
no, default 1 and 15 | limit 1 to 60. |
combineTickets |
no, default true |
false = no combinations of separate one-way tickets (fewer results). |
stops |
no | 0, 1 or 2: the most stops allowed. Options and counts: data.filters.stops.options[] of a search without this filter. |
maxDuration, maxLayoverDuration |
no | Whole hours. The ranges: data.filters.duration.journey and data.filters.duration.layover (min, max) of a search without this filter. |
airlines |
no | One comma list of airline codes for the whole trip (AI,6E). The codes come from data.filters.airlines.options[].code of GET /flights/search for the same trip without this filter: run the search once, show the airlines (each option has name, logo, count, minPrice), then search again with the chosen codes. |
includedBaggage |
no | CABIN, CHECKIN or CABIN,CHECKIN (the options and counts: data.filters.baggage.options[] of a search without this filter). |
maxBudget, maxBudgetPerAdult |
no | Whole amounts in currencyCode. The range: data.filters.budget (min, max, perAdultMin, perAdultMax) of a search without this filter. |
airports |
no | Comma list of airport codes (BOM,NMI). The codes: data.filters.airports.byCity[].airports[].code of a search without this filter. |
preferSameAirport |
no | true/false, round trip only (the count: data.filters.airports.preferSameAirport.count of a search without this filter). |
departureTimes, arrivalTimes |
no | HH-HH ranges (the suggested ranges and counts per leg: data.filters.times.perLeg[].departure[] / .arrival[] of a search without this filter), ranges of a leg comma-separated, one group per leg separated by ` |
The filters combine (AND). Where a filter's values come from: every filter value is in the data.filters menu of a GET /flights/search response (the table above names the exact field), so the way to use one is: search without it, read the menu, search again with the chosen value. Each menu also names the parameter that applies it (param). Counts in the menu follow the filters already applied.
What you get back
{
"status": true,
"message": "Flights found",
"data": {
"search": { "type": "ONEWAY", "from": [["BOM.CITY"]], "to": [["DEL.AIRPORT"]], "depart": "2026-11-20", "return": null, "legDates": null, "adults": 1, "childrenAges": [], "cabinClass": "ECONOMY", "currencyCode": "USD", "sort": "BEST", "combineTickets": true, "appliedFilters": {}, "searchId": "0B399C76…", "source": "live" },
"pagination": { "page": 1, "pageSize": 15, "count": 15, "totalCount": 255, "filteredCount": 255, "hasNextPage": true },
"offers": [
{
"id": "d7699_H4sIAAAA…",
"key": "1_6E615.BOM20261120",
"tripType": "ONEWAY",
"badges": [{ "type": "BEST", "text": "Best", "variant": "BRAND_PRIMARY" }],
"price": { "total": { "currencyCode": "USD", "amount": 72.39 }, "baseFare": { "currencyCode": "USD", "amount": 54.13 }, "tax": { "currencyCode": "USD", "amount": 18.26 }, "taxByAirline": [], "breakdown": { "items": [] } },
"travellers": [{ "traveller": "1", "type": "ADULT", "price": {} }],
"segments": [
{
"departure": { "airport": { "type": "AIRPORT", "code": "BOM", "name": "Chhatrapati Shivaji International Airport Mumbai", "cityName": "Mumbai", "country": "IN" }, "time": "2026-11-20T13:00:00", "timeWithOffset": "2026-11-20T13:00:00+05:30" },
"arrival": { "airport": { "code": "DEL" }, "time": "2026-11-20T15:10:00", "timeWithOffset": "2026-11-20T15:10:00+05:30" },
"durationMinutes": 130,
"numberOfStops": 0,
"layovers": [],
"legs": [{ "flightNumber": 615, "marketingCarrier": { "code": "6E", "name": "IndiGo", "logo": "https://r-xx.bstatic.com/data/airlines_logo/6E.png" }, "operatingCarrier": { "code": "6E", "name": "IndiGo" }, "cabinClass": "ECONOMY", "durationMinutes": 130 }],
"baggage": { "checked": [{ "traveller": "1", "luggageType": "CHECKED_IN", "ruleType": "PIECE_BASED", "maxPiece": 1, "maxWeightPerPiece": 33.1, "massUnit": "LB" }], "cabin": [{ "traveller": "1", "personalItem": true, "luggageType": "HAND", "maxPiece": 1, "maxWeightPerPiece": 15.4, "massUnit": "LB" }] }
}
],
"fare": { "name": "Saver", "cabinClass": "ECONOMY", "features": [{ "code": "BK01", "featureName": "CHECK_BAGGAGE", "category": "BAGGAGE", "availability": "INCLUDED", "label": "1 checked bag (33.1 lbs)" }] },
"hasMoreFares": true,
"flexibleTicket": { "price": { "total": {} }, "recommended": false },
"genius": { "airlineFunded": false, "selfFunded": false }
}
],
"deals": [{ "type": "BEST", "offerId": "d7699_H4sI…", "price": { "currencyCode": "USD", "amount": 72.39 } }, { "type": "CHEAPEST", "offerId": "…", "price": { "currencyCode": "USD", "amount": 69.79 } }],
"filters": {
"totalCount": 255, "filteredCount": 255,
"stops": { "param": "stops", "options": [{ "stops": 0, "count": 74 }, { "stops": 1, "count": 254 }, { "stops": 2, "count": 255 }] },
"airlines": { "param": "airlines", "options": [{ "code": "6E", "name": "IndiGo", "count": 52, "minPrice": {} }] },
"times": { "params": { "departure": "departureTimes", "arrival": "arrivalTimes" }, "perLeg": [{ "leg": 1, "departure": [{ "from": "00:00", "to": "05:59", "count": 29 }], "arrival": [] }] },
"duration": { "unit": "hours", "journey": { "param": "maxDuration", "min": 3, "max": 29 }, "layover": { "param": "maxLayoverDuration", "min": 1, "max": 23 } },
"baggage": { "param": "includedBaggage", "options": [{ "type": "CABIN", "count": 192 }] },
"budget": { "totalParam": "maxBudget", "perAdultParam": "maxBudgetPerAdult", "min": {}, "max": {} },
...
| Case | status |
message |
|---|---|---|
| Offers on this page | true |
Flights found |
| A page past the end | true |
No flights on this page |
| Nothing matches the search | false |
No flights were found for this search |
| Booking.com rejected an input | false |
the mapped message (dates, airports, passengers ...) |
| Booking.com down / HTTP error | false |
Flights provider is unreachable / …returned HTTP <n> |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
offers[].id |
The offer id: pass it to /flights/details. Valid for a short time. |
offers[].key |
Booking.com's key for the flights (flight numbers + route + dates); the same flights with another fare share it. |
offers[].price |
total for all travellers, baseFare, fee, tax, discount, totalWithoutDiscount, the *Rounded totals the app shows, taxByAirline[] and breakdown (the app's itemised tree: "Adults (2)" > "Flight fare", "Airline taxes and fees"). Money is { currencyCode, amount }. |
offers[].travellers[] |
One entry per traveller (type ADULT / KID) with that traveller's own price. |
offers[].segments[] |
One per direction: the outbound, the return, or each city pair of a multi-city trip. legs[] are the actual flights inside it; a segment with two legs has one connection. layovers[] (added here) gives the wait at each connection in minutes and whether the airport changes. |
segments[].baggage |
checked[] and cabin[] allowances per traveller in Booking.com's own fields (maxPiece, maxWeightPerPiece, maxTotalWeight, ruleType, sizeRestrictions, massUnit). |
legs[] |
flightNumber, marketingCarrier (the airline that sells it) and operatingCarrier (the one that flies it) each with code, name and logo, departure / arrival (airport, terminal, time, timeWithOffset), durationMinutes, cabinClass, aircraft, technicalStops[]. |
offers[].fare |
The fare (name such as Saver, cabinClass) and every feature in the app's order with availability INCLUDED, SELLABLE (can be added for a fee) or NOT_INCLUDED. hasMoreFares says /flights/details lists other fares of the same flight. |
offers[].baggageIncluded, flexibleTicket, genius, pointOfSale, badges, seatsLeft |
What the fare includes per segment; the optional flexible-ticket add-on (price, supplier); Genius campaign flags; the sales country; "Best" / "Cheapest" labels; seats left when low. |
deals[] |
The BEST, CHEAPEST, CHEAPEST_DIRECT and FASTEST offer of the whole result (not only this page) with their offerId. |
filters |
The menu: stops (cumulative: "1 stop" counts include direct), airlines (one list), times.perLeg[], duration, baggage, budget, airports (with preferSameAirport), summary (the app's quick stats) and menuOrder. Counts follow the filters you applied; totalCount is all, filteredCount after filters. |
search |
What was searched, as understood (from / to are lists of legs, each a list of places). |
extras |
On an object: fields Booking.com sends that this API does not map yet. |
Written once instead of repeated (checked field by field against the raw response): the airports and times on a segment and again on its legs (the segment's are the first leg's departure and the last leg's arrival, both kept on the segment); the price in priceBreakdown, per traveller and as the itemised tree; baggage in three shapes (includedProductsBySegment repeats the segments' allowances); the flexible ticket in ancillaries, offerExtras and extraProducts (a differing supplier name is kept as flexibleTicket.offerSupplier); the fare's features as three lists plus the combined featuresList.
52. Flights Details
What it does. One offer in full. Open a search result: the same offer plus the fare rules (what changing or cancelling costs), the other fares of the same flight (Saver / Classic / Flex ...), the fare comparison table, what the booker must provide and the baggage-policy links.
Where the inputs come from. Step 3 of the flights journey in the journey overview: search -> details -> fare quote. The input is an offer id from a search (or from deals[].offerId).
Request
GET /api/v1/flights/details?offerToken=d7699_H4sIAAAAAAAA_…
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
offerToken |
yes | An offer id: data.offers[].id of /flights/search, data.deals[].offerId, or data.otherFares[].id of this endpoint. |
What you get back
{
"status": true,
"message": "Flight details found",
"data": {
"id": "d7699_H4sIAAAA…", "key": "1_AI9549_2_AI9550.BOM20261120.DEL20261128", "tripType": "ROUNDTRIP",
"price": { "total": { "currencyCode": "INR", "amount": 15300 }, "breakdown": { "items": [] } },
"travellers": [], "segments": [], "fare": { "name": "ECO VALUE", "features": [] },
"reference": "d7699_3758897977",
"fareRules": {
"perSegment": [{ "segments": [{ "segmentIndex": 0, "legIndex": 0 }], "available": [{ "type": "CANCEL_BEFORE", "price": { "total": { "currencyCode": "INR", "amount": 4999 } } }, { "type": "CHANGE_BEFORE", "price": { "total": { "currencyCode": "INR", "amount": 3499 } } }], "unavailable": [] }],
"features": [{ "featureName": "CANCELLABLE_TICKET", "label": "You’re allowed to cancel this flight for a fee" }]
},
"otherFares": [
{ "index": 0, "id": "d7699_3904B@H4sI…", "reference": "d7699_3904B@…", "fare": { "name": "ECO VALUE" }, "price": { "total": { "currencyCode": "INR", "amount": 15300 } }, "eligibleFilters": ["CABIN_BAGGAGE", "CHECKIN_BAGGAGE", "SEAT_SELECTION"] },
{ "index": 1, "id": "d7699_3904B@H4sI…", "fare": { "name": "ECO CLASSIC" }, "price": { "total": { "currencyCode": "INR", "amount": 16579.54 } } },
{ "index": 2, "id": "d7699_3904B@H4sI…", "fare": { "name": "ECO FLEX" }, "price": { "total": { "currencyCode": "INR", "amount": 18483.71 } } }
],
"fareComparison": { "fares": ["ECO VALUE", "ECO CLASSIC", "ECO FLEX"], "rows": [{ "title": "1 personal item", "icon": "PERSONAL_LUGGAGE_ICON", "values": ["INCLUDED", "INCLUDED", "INCLUDED"] }, { "title": "Flight change allowed", "icon": "PLANE_TICKET_RETURN_ICON", "values": ["SELLABLE", "SELLABLE", "INCLUDED"] }] },
"bookerMustProvide": ["EMAIL", "PHONE"],
"travellerTypes": [{ "traveller": "1", "type": "ADULT" }],
"oneWayCombination": null,
"baggagePolicies": [{ "airline": { "code": "AI", "name": "Air India" }, "url": "https://www.airindia.com/…" }]
}
}
| Case | status |
message |
|---|---|---|
| Offer found | true |
Flight details found |
| Expired or unknown id | false |
This offer has expired or is not valid - run the search again and use a fresh offer id |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
Everything of a search offer (see flights-search.md) plus:
| Field | Meaning |
|---|---|
reference |
Booking.com's own reference of this offer. |
fareRules.perSegment[] |
For each segment (segmentIndex, legIndex) the policies that are available (with their fee: CANCEL_BEFORE, CHANGE_BEFORE, CHANGE_AFTER ...) and the unavailable ones. fareRules.features[] are the plain-language lines. |
otherFares[] |
The same flights as other fares: id (use it for /flights/fare-quote), index, reference, fare (name + every feature), price (+ farePriceDifference against the first fare), travellers[], baggageIncluded, flexibleTicket, eligibleFilters. Empty when the offer has only one fare. |
fareComparison |
fares[] (names) and rows[] (title, icon, values[] = INCLUDED / SELLABLE / NOT_INCLUDED, one per fare in the order of otherFares). null when there is no table. |
bookerMustProvide |
What the booker has to give at booking: EMAIL, PHONE. |
oneWayCombination |
Present for a round trip built from two separate one-way tickets: the app's heading, explanation and terms link. |
baggagePolicies[] |
The airlines' own baggage-rule pages. |
53. Flights Fare Quote
What it does. Confirms the offer or fare the traveller chose and returns its final price and an expiry time; nothing is booked, reserved or charged, and this API has no booking step - this is where the flights journey ends.
Where the inputs come from. Step 4 of the flights journey in the journey overview: details -> fare quote -> fare quote extras / seat map.
Request
POST /api/v1/flights/fare-quote
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Content-Type: application/json
{ "offerToken": "d7699_H4sIAAAAAAAA_…" }
Parameters, rules and the answer
| Body field | Required | Rule |
|---|---|---|
offerToken |
yes | The chosen offer id: data.offers[].id of /flights/search or data.otherFares[].id of /flights/details. |
What you get back
{
"status": true,
"message": "Fare confirmed",
"data": {
"passengers": [{ "traveller": "1", "type": "ADULT", "firstName": null, "lastName": null, "gender": "UNKNOWN_GENDER" }],
"quote": {
"token": "52585366dc7c65f3a07e…",
"reference": "d7699_…",
"status": "DRAFT",
"supplyType": "AGENCY",
"expires": "2026-10-19T23:27:47+02:00",
"offerReference": "d7699_3758925729",
"price": { "total": { "currencyCode": "INR", "amount": 16579.54 }, "baseFare": {}, "tax": {}, "taxByAirline": [], "breakdown": {} },
"travellers": [], "segments": [], "baggageIncluded": {}, "fareRules": { "reliable": false, "flightSegments": [] }
}
}
}
| Case | status |
message |
|---|---|---|
| Fare confirmed | true |
Fare confirmed |
| Expired or unknown offer id | false |
Booking.com could not process the request / the mapped message |
| Validation failure | false |
Validation failed (+ errors[]) |
Fields
| Field | Meaning |
|---|---|
quote.token |
The key for /flights/fare-quote/extras. |
quote.reference, quote.offerReference |
Booking.com's references of the quote and of the offer in it. |
quote.status, quote.supplyType, quote.expires |
DRAFT; who sells it; when the quote (and its price) stops being valid. |
quote.price, travellers, segments, baggageIncluded |
As in a search offer, for the offer in the fare quote. |
quote.fareRules |
Booking.com's structured fare rules per flight segment (reliable: false = it could not read them all). |
passengers[] |
The traveller slots, still empty. |
54. Flights Fare Quote Extras
What it does. The add-ons for a fare quote: the optional flexible ticket (price, supplier, whether Booking.com recommends it). The seat map has its own endpoint, GET /flights/seat-map.
Where the inputs come from. Step 4 of the flights journey in the journey overview: fare quote -> extras (and seat map). The input is quote.token of the fare quote call.
Request
GET /api/v1/flights/fare-quote/extras?quoteToken=52585366dc7c65f3a07e…
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
quoteToken |
yes | data.quote.token of POST /flights/fare-quote. |
What you get back
{
"status": true,
"message": "Extras found",
"data": {
"flexibleTicket": {
"price": { "total": { "currencyCode": "INR", "amount": 2155.34 } },
"travellers": ["1"], "preSelected": false, "recommended": false, "confidence": "UNKNOWN_LEVEL", "highlight": true,
"supplier": { "name": "Gotogate International AB", "termsUrl": "https://flights-in.gotogate.com/rf/travel-conditions", "privacyPolicyUrl": "https://flights-in.gotogate.com/rf/privacy-policy" }
},
"purchasePrediction": { "lowLikelihood": false }
}
}
| Case | status |
message |
|---|---|---|
| Extras found | true |
Extras found |
| Unknown or expired fare quote | false |
No extras found for this fare quote (it may have expired) / the mapped message |
| Validation failure | false |
Validation failed (+ errors[]) |
flexibleTicket is null when the offer has none.
55. Flights Seat Map
What it does. The seat map of a fare quote: cabins, rows and columns, the characteristics of each seat (window, aisle, front of cabin ...) and a price per seat, one map per flight.
Where the inputs come from. Step 4 of the flights journey in the journey overview: fare quote -> seat map (and extras). The input is quote.token of the fare quote call.
Request
GET /api/v1/flights/seat-map?quoteToken=52585366dc7c65f3a07e…
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
quoteToken |
yes | data.quote.token of POST /flights/fare-quote. |
What you get back
{
"status": true,
"message": "Seat map found",
"data": {
"seatMap": {
"recommended": false,
"confidence": "UNKNOWN_LEVEL",
"airProductReference": "n/a",
"options": [
{ "segmentIndex": 1, "legIndex": 0, "travellers": ["1"], "cabins": [{ "class": "ECONOMY", "deck": "MAIN", "columns": [], "rows": [], "cabinCharacteristics": [] }], "priceDistribution": [0, 1996.96] }
]
}
}
}
| Case | status |
message |
|---|---|---|
| Seat map found | true |
Seat map found |
| The flight has no seat map | false |
This quote has no seat map |
| Unknown or expired fare quote | false |
Booking.com could not process the request |
| Validation failure | false |
Validation failed (+ errors[]) |
Car rental
56. Cars Countries
What it does. The list of countries a renter can live in. Its code is the countryCode that every other cars call needs.
Where the inputs come from. Step 1 of the cars journey in the journey overview: countries -> autocomplete -> search -> vehicle -> supplier / terms -> price summary.
Request
GET /api/v1/cars/countries?languageCode=en-us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
languageCode |
no | A code of /common/languages. Default en-us. Only the names change. |
What you get back
{
"status": true,
"message": "Countries found",
"data": {
"countries": [
{ "code": "af", "name": "Afghanistan", "flag": "https://www.rentalcars.com/images/flags/af.png" }
]
}
}
| Field | Meaning |
|---|---|
code |
Lowercase two-letter code. Use it as countryCode. |
name |
Country name in languageCode. |
flag |
Flag image URL. |
status |
message |
When |
|---|---|---|
true |
Countries found |
Always on success. |
false |
Validation failed |
languageCode is not a supported language (no quota used). |
false |
Car rental provider returned HTTP … |
Booking.com failed. |
57. Cars Autocomplete
What it does. Places for typed text: cities, districts, airports and points of interest, for the pick-up and drop-off of a rental car.
Where the inputs come from. Step 2 of the cars journey in the journey overview: countries -> autocomplete -> search.
Request
GET /api/v1/cars/autocomplete?term=newark
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
term |
yes | The text typed, 1 to 100 characters. |
languageCode |
no | A code of /common/languages. Default en-us. |
What you get back
{
"status": true,
"message": "Places found",
"data": {
"places": [
{
"name": "Newark Liberty International Airport",
"title": "Newark Liberty International Airport",
"subtitle": "New York, New York, United States",
"type": "airport",
"iataCode": "EWR",
"city": "New York",
"country": "United States",
"latitude": 40.69169998168945,
"longitude": -74.18009948730469,
"locationId": null,
"cityId": null,
"icon": "bui_transport_airplane"
}
]
}
}
How to use a result in /cars/search: every place, airports too → its latitude + longitude as pickUpLatitude + pickUpLongitude (iataCode is information).
status |
message |
When |
|---|---|---|
true |
Places found |
At least one place. |
false |
No places found |
Nothing matches the text. |
false |
Validation failed |
term missing or empty (no quota used). |
58. Cars Search
What it does. Rental cars for a pick-up place and a date range: every car with its price, supplier, rating, fees and specifications, plus the filter menu and the sort menu.
Where the inputs come from. Step 3 of the cars journey in the journey overview: autocomplete -> search -> vehicle / supplier / terms -> price summary. Filters and sorting: filters.md.
Request
GET /api/v1/cars/search?pickUpLatitude=40.6413&pickUpLongitude=-73.7781&pickUpDate=2026-11-20&dropOffDate=2026-11-23&countryCode=us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
pickUpLatitude + pickUpLongitude |
required | The pick-up place, both together: latitude and longitude of a result of autocomplete (an airport has them too). |
dropOffLatitude + dropOffLongitude |
optional | One-way rental, both together. Leave both out to return the car where it was picked up. |
pickUpDate, dropOffDate |
required (the drop-off date may equal the pick-up date if the drop-off time is later) | YYYY-MM-DD. Pick-up not in the past and under 3 years ahead; drop-off after pick-up, at most 62 days later. |
pickUpTime, dropOffTime |
optional | HH:mm, default 10:00. |
driverAge |
optional | Whole number 18 to 99, default 30. |
countryCode |
required | A code of /cars/countries. |
currencyCode |
optional | One of 79 codes, default USD. |
languageCode |
optional | Default en-us. |
sortBy |
optional | recommended (default), price_low_to_high, review_score. |
filters |
optional | Comma-separated family::value from data.filters.families[].options[].filter. |
What you get back
{
"status": true,
"message": "Cars found",
"data": {
"search": { "pickUp": { "iata": "JFK" }, "dropOff": null, "pickUpDateTime": "2026-11-20T10:00", "dropOffDateTime": "2026-11-23T10:00", "rentalDays": 3, "driverAge": 30, "countryCode": "us", "currencyCode": "USD", "languageCode": "en-us", "sortBy": null, "appliedFilters": [] },
"searchKey": "eyJkcml2ZXJzQWdlIjozMCwi…",
"totalCount": 304,
"returnedCount": 297,
"truncated": false,
"lowestPrice": { "amount": 222.69, "currency": "USD" },
"sort": [{ "name": "Recommended", "identifier": "recommended", "titleTag": "tr.searchresults.sortBy.recommended" }],
"filters": { "families": [ { "family": "depotLocationType", "title": "Location", "style": "checkbox", "options": [ { "id": "SHUTTLE_BUS", "filter": "depotLocationType::SHUTTLE_BUS", "name": "Airport (shuttle)", "label": "Airport (shuttle) (15)", "count": 15, "selected": false, "disabled": false } ] } ], "smartFilters": { "title": "Smart filters" } },
"depots": [{ "name": "John F Kennedy International Airport", "label": "304 cars · 11 suppliers", "carCount": 304, "supplierCount": 11, "fromPrice": "$164", "latitude": 40.663756, "longitude": -73.818973 }],
"cars": [
{
"id": "695750666",
"name": "Wild Card", "groupOrSimilar": "or similar", "carClass": "Special",
"seats": 5, "airbags": 1, "airConditioning": true, "transmission": "Automatic",
"fuelPolicy": "Like for like", "mileage": "Unlimited mileage", "unlimitedMileage": true,
"freeCancellation": true,
"badges": [{ "type": "CONSTRUCTIVE", "text": "Free cancellation", "variation": "DEFAULT" }],
"specs": [{ "icon": "TRANSMISSION_AUTOMATIC", "text": "Automatic", "accessibility": "Automatic gearbox" }],
"price": { "currency": "USD", "price": 164.11, "driveAwayPrice": 164.11, "deposit": 0, "discount": 0, "payWhen": "PAY_NOW", "quoteAllowed": true, "fees": [{ "type": "DEPOSIT", "amount": 500, "currency": "USD", "taxIncluded": true }] },
"rating": { "average": 4.8, "title": "Disappointing", "subtitle": "236 reviews", "ratingCount": 236, "cleanliness": 5.3, "valueForMoney": 4.2 },
"supplier": { "name": "ACE Rent A Car", "locationType": "Shuttle Bus", "address": "124-10 South Conduit Avenue, …" },
"pickUp": { "locationId": "481525" },
"freebies": ["Amendments"],
"extras": {}
}
]
}
}
| Field | Meaning |
|---|---|
searchKey |
Signed key of this search, bound to its countryCode. Goes into every follow-up call with cars[].id. |
totalCount / returnedCount / truncated |
Booking.com's count / cars in this answer / more existed than were returned (500 cap). |
lowestPrice |
The cheapest car. |
filters.families[] |
The filter menu of THIS search with counts; each option's filter is pasted into filters. |
depots[] |
Pick-up depots on the map with car count and "from" price. |
cars[].price.price |
Price in currencyCode; null for cars paid at pick-up (PAY_LOCAL). driveAwayPrice = everything payable, taxes and fees included, and is always present: show this one. payWhen: PAY_NOW, PART_PAY or PAY_LOCAL (at pick-up). price.fees[] lists deposit, excess, extra fees. |
cars[].rating |
Customer score (0 to 10) of the car + the supplier at this depot, with sub-scores. |
cars[].pickUp.locationId |
Booking.com's id of the depot; information only (this API takes coordinates). |
extras |
Booking.com fields without a named place here (nothing is dropped). |
Using the search for a map view
GET /cars/search is also the map-view call: the pins are data.depots[]. There is no separate map endpoint.
1. Ask for the visible map area. Send the centre of the map as the pick-up place:
GET /api/v1/cars/search?pickUpLatitude=40.7923&pickUpLongitude=-73.8845&pickUpDate=2026-11-20&dropOffDate=2026-11-23&countryCode=us
| Parameter | Use on the map |
|---|---|
pickUpLatitude + pickUpLongitude (required) |
The centre of the map. Send the new centre each time the user moves or zooms the map. |
pickUpDate, dropOffDate (required), pickUpTime, dropOffTime |
The rental period; the "from" price on every pin is for this period. |
countryCode (required) |
The renter's country (changes which depots and prices exist). |
driverAge, currencyCode, languageCode (optional) |
Driver age, price currency and text language of the pins. |
filters (optional) |
Narrow the pins: only depots that still have a matching car stay on the map, and their carCount / fromPrice follow the filter (e.g. filters=supplier::Hertz). |
sortBy (optional) |
Orders data.cars. |
2. Draw the pins from data.depots[]:
{
"name": "LaGuardia Airport",
"address": "90-05 25th Avenue, East Elmhurst, USA, 11369-1509",
"latitude": 40.76416,
"longitude": -73.87866,
"carCount": 38,
"supplierCount": 3,
"fromPrice": "US$379",
"fromPriceLabel": "Price for 3 days: from US$379",
"locationHash": "TGFHdWFyZGlhIEFpcnBvcnQ="
}
Put the marker at latitude / longitude, label it with fromPrice (text in the chosen currency, for the whole rental) and show carCount cars from supplierCount suppliers (see the measured notes below on carCount).
3. Show the cars of a tapped pin. They are already in data.cars (no second call): keep the cars whose pickUp.locationHash equals the pin's locationHash. Tested in New York (482 cars, 9 pins) and London (500 cars, 63 pins): every car matched a pin and every pin had at least one car. Each car's pickUp has the depot name, address, latitude, longitude (the same coordinates as the pin) and locationId.
What was measured
fromPriceis the lowestprice.driveAwayPriceamong that depot's cars indata.cars, rounded to whole units (522.15 → "$522"; checked on 5 pins). It is notprice.price: that field isnullfor cars paid at pick-up (payWhenPAY_LOCAL, 410 of 482 cars), so always showdriveAwayPriceon a car.carCountcan be larger than the cars returned for that pin: 314 against 139 for the biggest New York pin, 327 against 131 in London, even when the search was under the 500 cap. TreatcarCountas Booking.com's number for the depot and the cars indata.carsas the ones you can show; the reason for the difference is not known.sortBydoes not change the pins (identical pins and counts forrecommended,price_low_to_high,review_score).filtersdoes (the Hertz filter cut 9 pins to 2).- Moving the centre: 1 km from the first centre gave the same 9 pins; 10 km gave 20 pins, central Manhattan 19, Brooklyn 12, a point far outside (New Jersey) 19 pins with none shared with the first search. The middle of the Atlantic gave no pins and no cars (
status: false). So the pins follow the centre point, not a fixed rectangle, and a small move may change nothing. - Results move over time: the same search gave 442, then 482 cars, and a
totalCountof 579, 639 and 659 within minutes. Stock and prices are live; do not cache a map for long.
Good to know
- The search takes a centre point, not a map rectangle, so Booking.com decides which depots count as near that point.
data.carsholds at most 500 cars (truncated); in London all 63 pins still had cars, but a busy area is better narrowed withfilters.
status |
message |
When |
|---|---|---|
true |
Cars found |
At least one car. |
false |
No cars found for this search |
HTTP 200 with an empty list: too young or too old driver for the place, a currency without prices, the depot closed at that time, or filters that match nothing. |
false |
Validation failed |
A bad parameter (named in message); no quota used. |
false |
Booking.com rejected the search … |
Booking.com answered 400 (e.g. a pick-up id it does not know). |
59. Cars Vehicle
What it does. One car in full: price breakdown, fees, specification, the rentable extras, insurance packages, what is included, and the important information (deposit, damage excess, what is needed at pick-up).
Where the inputs come from. Step 4 of the cars journey in the journey overview: search -> vehicle -> supplier / terms -> price summary.
Request
GET /api/v1/cars/vehicle?searchKey=eyJkcml2…&vehicleId=806930766&countryCode=us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
searchKey |
yes | data.searchKey of /cars/search, exactly as returned. |
vehicleId |
yes | data.cars[].id of the same search. |
countryCode |
yes | The same country the search was made with. Another country gives "cannot find this car" (see below). |
currencyCode |
no | One of 79 codes, default USD. May differ from the search. |
languageCode |
no | Default en-us. May differ from the search. |
What you get back
{
"status": true,
"message": "Car found",
"data": {
"vehicle": {
"id": "806930766",
"name": "Kia e-Niro", "groupOrSimilar": "or similar large car", "carClass": "Intermediate",
"freeCancellation": true, "rentalDays": 3,
"specification": { "airConditioning": true, "mileage": "Unlimited", "transmission": "Automatic", "suitcaseCount": 3, "numberOfDoors": 4, "numberOfSeats": 5 },
"sippCode": "IXAE", "vehicleBroadCategory": "Medium", "depotLocationType": "InTerminal", "mileageType": "Unlimited",
"price": { "driveAway": { "amount": 226.68, "currency": "USD" }, "base": { "amount": 173.64, "currency": "USD" }, "payWhen": "PAY_LOCAL", "driveAwayPriceIsApprox": false },
"totalPriceText": "$226.68",
"fees": { "payableFees": [], "otherFees": [] },
"pickUp": { "locationId": "356666", "name": "John F Kennedy International Airport", "address": "310 Federal Cir, Jamaica, US, 11430", "latitude": 40.66001, "longitude": -73.80328, "locationType": "IN_TERMINAL" },
"dropOff": { "locationId": "356666", "name": "John F Kennedy International Airport" },
"supplier": { "name": "Budget", "locationType": "In Terminal", "rating": {} },
"insurancePackages": [{ "id": "RC_US_CITIZEN_DP", "title": "Add insurance...", "price": "$48", "priceNote": "Free cancellation" }],
"optionalExtras": [{ "id": "14494938411010", "type": "BABY_SEAT", "name": "Baby seat", "detail": "For babies: up to 9 kg / 20 lbs (about 1 year old)", "maxQuantityAvailable": 2, "prePayable": false, "price": { "display": { "amount": 43.5, "currency": "USD" }, "base": { "amount": 43.5, "currency": "USD" } } }],
"whatsIncluded": { "title": "What's included", "items": [] },
"importantInfo": { "title": "Important information", "items": [] },
"rentalTermsUrl": "https://cars.booking.com/terms/…"
}
}
}
| Field | Meaning |
|---|---|
price.driveAway |
Everything payable for the rental, taxes and fees included. base = the rental alone. |
price.payWhen |
PAY_NOW, PART_PAY or PAY_LOCAL. Only pay-now and part-pay cars have a terms page. |
optionalExtras[] |
Add-ons with a price; maxQuantityAvailable is how many can be taken; id goes to the price summary. |
pickUp.locationId |
Booking.com's depot id (information only). |
status |
message |
When |
|---|---|---|
true |
Car found |
Normal. |
false |
Booking.com cannot find this car for the searchKey … |
The vehicleId is not in that search, or countryCode differs from the search's. |
false |
Validation failed |
A parameter is missing or malformed; no quota used. |
60. Cars Supplier
What it does. The rental company at the pick-up place: its rating with a breakdown, address, opening times for pick-up and drop-off, and pick-up instructions. This is the "details" tab of the supplier page; the other two tabs are reviews and location.
Where the inputs come from. Step 5 of the cars journey in the journey overview, after vehicle.
Request
GET /api/v1/cars/supplier?searchKey=eyJkcml2…&vehicleId=806930766&countryCode=us
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
searchKey |
yes | data.searchKey of /cars/search, exactly as returned. |
vehicleId |
yes | data.cars[].id of the same search. |
countryCode |
yes | The same country the search was made with. Another country gives "cannot find this car" (see below). |
currencyCode |
no | One of 79 codes, default USD. May differ from the search. |
languageCode |
no | Default en-us. May differ from the search. |
What you get back
{
"status": true,
"message": "Supplier found",
"data": {
"supplier": {
"name": "Budget",
"title": "Rental company",
"logo": "https://cdn.rcstatic.com/sp/images/suppliers/438_logo_200.png",
"rating": { "average": 7.8, "rawValue": 7.8, "title": "Good", "subtitle": "565 reviews", "breakdown": [] },
"address": "310 Federal Cir, Jamaica, US, 11430",
"openingTimes": { "title": "Opening times", "pickUp": {}, "dropOff": {} },
"pickUpInstructions": null,
"furtherInfo": []
}
}
}
status |
message |
When |
|---|---|---|
true |
Supplier found |
Normal. |
false |
Booking.com cannot find this car … |
Wrong vehicleId or countryCode. |
false |
Validation failed |
No quota used. |
61. Cars Supplier Reviews
What it does. Customer reviews of the rental company at the pick-up place, with the sort menu.
Where the inputs come from. Step 5 of the cars journey in the journey overview, the "reviews" tab next to supplier.
Request
GET /api/v1/cars/supplier-reviews?searchKey=eyJkcml2…&vehicleId=806930766&countryCode=us&sortBy=date.descending
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
searchKey |
yes | data.searchKey of /cars/search, exactly as returned. |
vehicleId |
yes | data.cars[].id of the same search. |
countryCode |
yes | The same country the search was made with. Another country gives "cannot find this car" (see below). |
currencyCode |
no | One of 79 codes, default USD. May differ from the search. |
languageCode |
no | Default en-us. May differ from the search. |
sortBy |
no | score.descending (default), score.ascending, date.descending, date.ascending. |
What you get back
{
"status": true,
"message": "Reviews found",
"data": {
"supplier": { "name": "Budget", "rating": { "average": 7.8, "title": "Good", "subtitle": "565 reviews" } },
"sortBy": "score.descending",
"sortOptions": [{ "id": "score.descending", "label": "Highest scores" }],
"noReviewsText": null,
"reviewCount": 71,
"reviews": [
{ "guestType": "Family", "rating": 10, "date": "Thu, Oct 8 2026", "epochDay": 20734, "positive": "Service was great!", "negative": null }
]
}
}
| Field | Meaning |
|---|---|
rating |
Review score 0 to 10. |
epochDay |
Days since 1970-01-01, the value used for date sorting. |
positive / negative |
What the guest liked / disliked; null when left empty. |
status |
message |
When |
|---|---|---|
true |
Reviews found |
Normal. |
false |
No reviews found (or the app's own "no reviews" text) |
The supplier has none at this depot. |
false |
Booking.com cannot find this car … |
Wrong vehicleId or countryCode. |
62. Cars Supplier Location
What it does. Address and coordinates of the pick-up depot, for a map.
Where the inputs come from. Step 5 of the cars journey in the journey overview, the "map" tab next to supplier.
Request
GET /api/v1/cars/supplier-location?searchKey=eyJkcml2…&vehicleId=806930766&countryCode=us
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
searchKey |
yes | data.searchKey of /cars/search, exactly as returned. |
vehicleId |
yes | data.cars[].id of the same search. |
countryCode |
yes | The same country the search was made with. Another country gives "cannot find this car" (see below). |
currencyCode |
no | One of 79 codes, default USD. May differ from the search. |
languageCode |
no | Default en-us. May differ from the search. |
What you get back
{
"status": true,
"message": "Location found",
"data": { "location": { "title": "Supplier location", "address": "310 Federal Cir, Jamaica, US, 11430", "latitude": 40.66001, "longitude": -73.80328 } }
}
status |
message |
When |
|---|---|---|
true |
Location found |
Normal. |
false |
Booking.com cannot find this car … |
Wrong vehicleId or countryCode. |
63. Cars Terms
What it does. The full rental terms of one car as readable text: the key facts (security deposit and accepted cards, driver and licence requirements, mileage) and every chapter of the terms and conditions.
Where the inputs come from. Step 5 of the cars journey in the journey overview, next to vehicle.
Request
GET /api/v1/cars/terms?searchKey=eyJkcml2…&vehicleId=695750666&countryCode=us
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
searchKey |
yes | data.searchKey of /cars/search. |
vehicleId |
yes | data.cars[].id, a car whose price.payWhen is PAY_NOW or PART_PAY. |
countryCode |
yes | The country the search was made with. |
languageCode |
no | Default en-us. |
What you get back
{
"status": true,
"message": "Rental terms found",
"data": {
"supplier": "ACE Rent A Car",
"isPayLocal": false,
"isOpaque": false,
"keyInfo": {
"deposit": { "title": "Security deposit", "subtitle": {}, "content": [], "acceptedCards": [], "warning": null },
"driverAndLicence": { "title": "Driver & license requirements", "topText": {}, "neededItems": [] },
"mileage": { "title": "Mileage", "subtitle": {}, "content": {} },
"common": { "driverAge": 30, "insuranceAvailable": true, "rentalDuration": 3, "debitCardsAllowed": false, "creditCardsAllowed": true, "supplier": "ACE Rent A Car", "countryOfResidence": "US", "destinationCountry": "US" },
"disclaimers": []
},
"terms": [
{ "id": 2, "type": "chapters", "title": "Included in the rental price", "titleKey": "Chapter.Included.Heading", "text": null, "textKey": null, "hideName": false, "order": 0, "labels": [], "children": [] }
]
}
}
| Field | Meaning |
|---|---|
keyInfo.* |
The summary cards. Texts that carry values are { "text": "…", "key": "…", "values": […] }. |
keyInfo.common |
Facts the terms were computed for (driver age, rental days, which cards are allowed, countries). |
terms[] |
The chapters, a tree: each node has title, text (null for a heading) and children[]. titleKey / textKey are Booking.com's message keys. |
status |
message |
When |
|---|---|---|
true |
Rental terms found |
A pay-now or part-pay car. |
false |
Booking.com has no rental terms page for this request … |
A PAY_LOCAL car, or a countryCode that differs from the search's (Booking.com answers both with the same HTTP 400). |
false |
Booking.com cannot find this car … |
Wrong vehicleId. |
false |
Validation failed |
A parameter is missing or malformed; no quota used. |
64. Cars Price Summary
What it does. The price of one car with the extras chosen (additional driver, child seat, GPS ...): line items and the new total. Nothing is booked, reserved or charged, and this API has no booking step.
Where the inputs come from. The last step of the cars journey in the journey overview: vehicle (pick the extras) -> price summary.
Request
POST /api/v1/cars/price-summary
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Content-Type: application/json
{
"searchKey": "eyJkcml2…",
"vehicleId": "806930766",
"countryCode": "us",
"extras": [{ "id": "14494938411010", "amount": 1 }]
}
Parameters, rules and the answer
| Body field | Required | Rule |
|---|---|---|
searchKey |
yes | data.searchKey of /cars/search. |
vehicleId |
yes | data.cars[].id of the same search. |
countryCode |
yes | The country the search was made with. |
currencyCode |
no | One of 79 codes, default USD. |
languageCode |
no | Default en-us. |
extras |
no | Up to 10 items { id, amount }; id = data.vehicle.optionalExtras[].id of vehicle, amount a whole number 1 to 10. Default [] (the base price). |
What you get back
{
"status": true,
"message": "Price summary found",
"data": {
"summary": {
"title": "Booking summary",
"vehicle": { "title": "Ford Mustang Mach-E AWD", "subtitle": "or similar SUV" },
"supplier": { "name": "Budget" },
"pickUp": { "name": "John F Kennedy International Airport", "dateTime": "Fri, 20 Nov · 10:00" },
"dropOff": { "name": "John F Kennedy International Airport", "dateTime": "Mon, 23 Nov · 10:00" },
"duration": { "text": "3 days" },
"freeCancellation": "Free cancellation at any time",
"priceBreakdown": { "sections": [], "total": { "title": "Total", "subtitle": "(including any taxes, fees & extras)", "price": "$244.08" } },
"footer": { "price": "$244.08", "label": "Total rental price" },
"basketSignature": "eyJhbGciOiJIUzI1NiJ9…"
}
}
}
priceBreakdown.sections[] has one line per item (car price, each extra with its count) and a subtotal such as "Payable today" / "Payable at pick-up". basketSignature is Booking.com's signed token for this exact price.
status |
message |
When |
|---|---|---|
true |
Price summary found |
Normal. |
false |
Validation failed |
A bad id or amount (extras[0].amount must be at least 1); no quota used. |
false |
Booking.com cannot find this car … |
Wrong vehicleId / countryCode. |
Taxi and airport transfers
65. Taxi Autocomplete
What it does. Places for typed text, for the pick-up and drop-off of a taxi: airports, train and underground stations, hotels, landmarks, popular and shopping areas.
Where the inputs come from. Step 1 of the taxi journey in the journey overview: autocomplete -> search -> supplier.
Request
GET /api/v1/taxi/autocomplete?term=JFK
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
term |
required | The text typed, 1 to 100 characters. |
latitude + longitude |
optional | Both together. Puts the places nearest to this point first. |
What you get back
{
"status": true,
"message": "Places found",
"data": {
"places": [
{
"name": "John F. Kennedy International Airport (JFK)",
"type": "airport",
"iata": "JFK",
"city": "New York",
"country": "United States of America",
"countryCode": "us",
"formattedAddress": null,
"latitude": 40.64500045776367,
"longitude": -73.78700256347656,
"googlePlaceId": "ChIJR0lA1VBmwokR8BGfSBOyT-w"
}
]
}
}
googlePlaceId is the pickUpPlaceId / dropOffPlaceId of /taxi/search.
status |
message |
When |
|---|---|---|
true |
Places found |
At least one place. |
false |
No places found |
Nothing matches the text. |
false |
Validation failed |
term missing or empty, or only one of latitude / longitude (no quota used). |
66. Taxi Airports
What it does. A second place search that the taxi screen uses when the traveller types an airport: it finds airports (with their IATA code) and a few other transport places.
Where the inputs come from. Step 1 of the taxi journey in the journey overview, next to autocomplete. Its iata is what /taxi/flights needs; its placeId is a place id for /taxi/search.
Request
GET /api/v1/taxi/airports?term=munich
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
term |
required | The text typed, 1 to 100 characters. |
What you get back
{
"status": true,
"message": "Places found",
"data": {
"places": [
{ "name": "Munich International Airport (MUC)", "iata": "MUC", "city": "Munich", "country": null, "placeId": "ChIJRW3aI1kTnkcRS89WOoV6xeM" },
{ "name": "Munich Central Bus Station(ZOB München)", "iata": null, "city": null, "country": null, "placeId": "ChIJv-RATQd2nkcRUXHA9ng-Haw" }
]
}
}
status |
message |
When |
|---|---|---|
true |
Places found |
At least one place. |
false |
No places found |
Nothing matches. |
false |
Validation failed |
term missing or empty (no quota used). |
67. Taxi Flights
What it does. The flights between two airports on a day, so a traveller can pick their flight and the taxi pick-up time can follow its arrival.
Where the inputs come from. Optional step 2 of the taxi journey in the journey overview, before search (an airport pick-up).
Request
GET /api/v1/taxi/flights?departureIata=LHR&arrivalIata=JFK&date=2026-11-01
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
departureIata |
required | 3-letter airport code the flight leaves from. |
arrivalIata |
required | 3-letter airport code the flight lands at (a taxi airport: /taxi/airports iata). |
date |
required | YYYY-MM-DD, not in the past, at most 364 days ahead. |
time |
optional | HH:mm, default 12:00; only matters when wholeDay is false. |
wholeDay |
optional | true (default) = all flights of the day; false = a window around time. |
What you get back
{
"status": true,
"message": "Flights found",
"data": {
"flights": [
{
"flightNumber": "EI8817",
"airlineName": "Aer Lingus",
"airlineLogoUrl": "https://r-xx.bstatic.com/data/airlines_logo/EI.png",
"departure": { "iata": "LHR", "name": "London Heathrow Airport", "city": "London", "dateTime": "2026-11-01T08:20:00.000" },
"arrival": { "iata": "JFK", "name": "New York John F. Kennedy International Airport", "city": "New York", "dateTime": "2026-11-01T11:20:00.000" }
}
]
}
}
dateTime values are the local times at each airport.
status |
message |
When |
|---|---|---|
true |
Flights found |
At least one flight. |
false |
No flights found |
No flight between these airports that day. |
false |
Validation failed |
A bad code or date (no quota used). |
68. Taxi Search
What it does. The taxis for a trip between two places: every vehicle type with its price, supplier, duration and cancellation rule. One way, or a round trip when a return date is given.
Where the inputs come from. Step 3 of the taxi journey in the journey overview: autocomplete -> (optional flights) -> search -> supplier. The same trip can also be priced as public transport and Uber.
Request
GET /api/v1/taxi/search?pickUpPlaceId=ChIJR0lA1VBmwokR8BGfSBOyT-w&dropOffPlaceId=ChIJq38lzVVYwokRDhgb0tE_sC0&pickUpDate=2026-11-01&pickUpTime=14:30&returnDate=2026-11-08&returnTime=09:00&passengers=3
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
pickUpPlaceId |
required | googlePlaceId of /taxi/autocomplete (or placeId of /taxi/airports). |
dropOffPlaceId |
required | The same kind of id; must differ from the pick-up. |
pickUpDate |
required | YYYY-MM-DD, not in the past, at most 364 days ahead. |
pickUpTime |
optional | HH:mm, local time at the pick-up place. Default 10:00. Booking.com needs the pick-up 2 to 6 hours ahead (depends on the route). |
returnDate |
optional | Give it for a round trip. YYYY-MM-DD, at most 364 days ahead. Leave it out for one way. |
returnTime |
optional | HH:mm. Default 10:00. The return must be at least 60 minutes after the pick-up. |
passengers |
optional | Whole number 1 to 50, default 2. The real limit is the biggest vehicle on the route (6 to 35 seats seen). |
currencyCode |
optional | One of 23 codes (above). Default USD. |
What you get back
{
"status": true,
"message": "Rides found",
"data": {
"search": { "tripType": "ROUND_TRIP", "pickUpPlaceId": "ChIJR0lA1VBmwokR8BGfSBOyT-w", "dropOffPlaceId": "ChIJq38lzVVYwokRDhgb0tE_sC0", "pickUpDateTime": "2026-11-01T14:30", "returnDateTime": "2026-11-08T09:00", "passengers": 3, "currencyCode": "USD" },
"outboundSearchId": "feffa68b-3579-465a-975b-671776d1db4b",
"returnSearchId": "0d6942e3-4593-424c-8fd0-d8826032815e",
"pickUp": { "id": "ChIJR0lA1VBmwokR8BGfSBOyT-w", "name": "John F Kennedy International Airport (JFK), JFK International Airport, NY 11430, USA", "establishment": "John F Kennedy International Airport (JFK)", "locationType": "AIRPORT", "airportCode": "JFK", "country": "US", "postcode": "11430", "latitude": 40.641319, "longitude": -73.778236 },
"dropOff": { "id": "ChIJq38lzVVYwokRDhgb0tE_sC0", "name": "Hotel Edison, 228 W 47th St, New York, NY 10036, USA", "establishment": "Hotel Edison", "locationType": "HOTEL", "airportCode": null, "country": "US", "postcode": "10036", "latitude": 40.7597355, "longitude": -73.9861511 },
"outbound": [
{
"vehicle": { "id": "1", "type": "standard", "description": "Standard", "maxPassengers": 3, "maxLuggage": 2 },
"price": 99.01,
"originalPrice": 99.01,
"priceDiscountPercentage": 0,
"currency": "USD",
"estimatedDuration": 48,
"cancellationLeadTimeMinutes": 1440,
"meetAndGreet": true,
"supplier": { "id": "102621", "locationId": "107560", "name": "Transpovia - NTR 249407" }
}
],
"return": [
{ "vehicle": { "id": "1", "type": "standard", "description": "Standard", "maxPassengers": 3, "maxLuggage": 3 }, "price": 88.08, "currency": "USD", "estimatedDuration": 44, "supplier": { "id": "2548", "locationId": "107527", "name": "Mistertransfer - NTR 27509" } }
],
"totals": [
{ "carTypeId": "1", "price": 187.09, "originalPrice": 187.09, "currency": "USD", "hasDiscount": false, "discountType": [], "discountValue": null, "priceDiscountPercentage": 0 }
]
}
}
| Field | Meaning |
|---|---|
outbound[] |
One entry per vehicle type for the way there. In a one-way search this is everything. |
return[] |
The way back, round trip only (otherwise null). Its supplier and price can differ from the outbound's: the same vehicle type was 99.01 out and 88.08 back. |
totals[] |
The price of the whole trip per vehicle type: carTypeId matches vehicle.id; for a round trip price = outbound + return (99.01 + 88.08 = 187.09). In a one-way search it equals the outbound price. |
vehicle.type |
standard, electric-standard, executive, luxury, electric-luxury, people-carrier, executive-people-carrier, large-people-carrier, minibus (the types seen). |
vehicle.maxPassengers / maxLuggage |
Capacity; varies by route, supplier and party size (a standard held 3 on one route, 4 on another). |
estimatedDuration |
Minutes of driving (48 for JFK to a Manhattan hotel; 1,013 for JFK to Orlando). |
cancellationLeadTimeMinutes |
Free cancellation up to this many minutes before the pick-up (1,440 = 24 h). |
meetAndGreet |
The driver meets the passenger inside. |
price, originalPrice, priceDiscountPercentage |
Price now and before the discount, in currency. |
supplier.id / locationId |
Inputs of /taxi/supplier. |
outboundSearchId, returnSearchId |
Booking.com's ids of the two searches (returnSearchId is null one way). Information only: nothing in this API takes them. |
pickUp, dropOff |
The two places as Booking.com resolved them. |
status |
message |
When |
|---|---|---|
true |
Rides found |
At least one vehicle type. |
false |
No rides found for this trip |
An answer with no vehicle (not seen in the tests; errors came instead). |
false |
Booking.com has no taxi for this request. Possible reasons: … |
Pick-up too soon or too far ahead, return too close to the pick-up, a place id Booking.com cannot resolve, no supplier on the route, or more passengers than the biggest vehicle. |
false |
Validation failed |
A bad parameter (named in message); no quota used. |
69. Taxi Supplier
What it does. The legal and contact details of the taxi company behind a ride (name, address, e-mail, telephone, registration).
Where the inputs come from. After search: supplier.id and supplier.locationId of a ride.
Request
GET /api/v1/taxi/supplier?supplierId=2550&locationId=107600
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
supplierId |
required | supplier.id of a ride in /taxi/search. |
locationId |
required | supplier.locationId of the same ride. |
What you get back
{
"status": true,
"message": "Supplier found",
"data": {
"supplier": {
"name": "Transporte Coyoacan - NTR 182458",
"legalEntityName": "Transporte Coyoacan LLC",
"address1": "440 North Barranca Avenue",
"address2": "New York",
"city": "Covina",
"zipCode": "91723",
"customerFacingEmailAddress": "booking.usa@servicioscoyoacan.com",
"customerFacingTelephone": "+12018855098",
"businessRegistrationNumber": "230301000423",
"nameOfTradingRegister": "New York Department of State - Division of Corporations"
}
}
}
status |
message |
When |
|---|---|---|
true |
Supplier found |
Normal. |
false |
Taxi provider returned INTERNAL_SERVER_ERROR |
The two ids do not belong together. |
false |
Validation failed |
An id is missing or not a number (no quota used). |
70. Taxi Public Transport
What it does. Public-transport options (bus, train) for the same trip, with ticket prices: the "or go by train" row of the taxi screen.
Where the inputs come from. An alternative to search for the same trip, in step 5 of the taxi journey in the journey overview.
Request
GET /api/v1/taxi/public-transport?departureLatitude=51.47&departureLongitude=-0.4543&arrivalLatitude=51.5154&arrivalLongitude=-0.1755&date=2026-11-01
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
departureLatitude + departureLongitude |
required | Where the trip starts (take them from /taxi/autocomplete). |
arrivalLatitude + arrivalLongitude |
required | Where it ends. |
date |
required | YYYY-MM-DD, not in the past, at most 364 days ahead. |
What you get back
{
"status": true,
"message": "Public transport found",
"data": {
"searchRequestId": "415b4b37-34df-405e-9443-251b3023a003",
"results": [
{
"transportType": "train",
"duration": 900,
"walkingDuration": null,
"tickets": [
{ "ticketType": "single", "amount": 26, "currencyCode": "GBP" },
{ "ticketType": "return", "amount": 42, "currencyCode": "GBP" }
],
"url": "https://public-transport.booking.com/result?retailerPartnerNumber=690801&departureArea=GBLONHA&arrivalArea=GBLONLM&departureDate=2026-11-01&locale=en-gb¤cy=GBP&…"
}
]
}
}
status |
message |
When |
|---|---|---|
true |
Public transport found |
At least one option. |
false |
No public transport found for this trip |
None sold for this pair of places. |
false |
Validation failed |
A bad coordinate or date (no quota used). |
71. Taxi Uber Rates
What it does. Uber fares for the same trip: each Uber product with its price and a link that opens the booking in Uber.
Where the inputs come from. An alternative to search for the same trip, in step 5 of the taxi journey in the journey overview.
Request
GET /api/v1/taxi/uber-rates?pickUpLatitude=40.6413&pickUpLongitude=-73.7781&dropOffLatitude=40.758&dropOffLongitude=-73.9855&pickUpDate=2026-11-01
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Parameters, rules and the answer
| Parameter | Required | Rule |
|---|---|---|
pickUpLatitude + pickUpLongitude |
required | The start. |
dropOffLatitude + dropOffLongitude |
required | The end. |
pickUpDate |
required | YYYY-MM-DD, not in the past. |
pickUpTime |
optional | HH:mm, default 10:00. |
passengers |
optional | 1 to 6. |
pickUpName, dropOffName |
optional | Text shown in the Uber link. |
What you get back
{
"status": true,
"message": "Rides found",
"data": {
"products": [
{
"name": "UberX",
"capacity": 4,
"freeCancellationThresholdMinutes": 60,
"fare": { "amount": 131.61, "currencyCode": "USD" },
"highEstimate": null,
"deepLink": "https://m.uber.com/reserve?app_id=…&pickup=…&drop%5B0%5D=…"
}
]
}
}
highEstimate was null in every answer seen.
status |
message |
When |
|---|---|---|
true |
Rides found |
At least one product. |
false |
No rides found for this trip |
Uber does not serve this pair. |
false |
Validation failed |
A bad coordinate or date (no quota used). |
Reference: Where every ID comes from
Every endpoint returns Booking.com's own IDs. This page says, for each kind of ID, where you get it and which endpoint takes it next, so nobody has to guess. IDs marked no lookup have no endpoint that turns them into a name; where Booking.com sends the name next to the ID, the response already carries it.
Checked 2026-10-19 against live responses (hotel 6966158 and others). The open items are listed in section 2.
1. IDs you can follow
| ID | Where you get it | Where you use it | Notes |
|---|---|---|---|
hotelId (property) |
/stays/search data.properties[].id |
Every property endpoint: property-details, rooms, property-facilities, facilities, description, highlights, photos, review-photos, important-info, review-scores, featured-reviews, review-filters, reviews, policies, questions, house-rules, photo-list, food-and-drink, description-sections, surroundings, badges |
The same number everywhere (hotel_id in Booking.com's own calls). |
destination (type:id) |
/stays/autocomplete or /stays/suggestions, the destination field |
search, search-filters, search-sort-options; city: and latlong: also things-to-do; city: also attractions/search |
The hotel's own city id is in every search result (location.cityId) and in property-details (location.destinationId): the same number (15 of 15 hotels, found by airport, landmark, district and city searches). Use city:<that id> for review-score-comparison and attractions/search; a search by airport or landmark does NOT give the hotel's city, the result's location.cityId does. |
roomId |
rooms[].roomId of /stays/rooms; roomTypes[].id of /stays/room-types; rooms[].id of property-details and property-facilities |
roomId of featured-reviews; matches roomId of the room photos in photos and the room a review was written for in reviews |
One number for the same room in all of them (checked on hotel 6966158: 7 rooms). |
blockId (a rate) |
rates[].blockId of /stays/rooms and of property-details |
The keys of policies.cancellation / prepayment and recommendation.rooms[] in rooms |
See the anatomy below. No endpoint takes it as input yet. |
Facility id |
facilities[].id and highlights[].id of /stays/rooms; the facility ids of /stays/property-facilities; facilities[].id and highlights.entities[].id of /stays/facilities |
Look the name up in property-facilities or facilities |
facilities and property-facilities have the same 76 facilities (same ids, groups, titles) on hotel 6966158. Same ids and names: 21 of the 22 room facilities of hotel 6966158 are in property-facilities with the same name. One is not: id 4 "Shower" (property-facilities has "Bath or shower", 69). |
| Facility group id | altFacilitytypeId (and altFacilitytypeName) on a room facility; facilityGroups[].id of property-facilities and facilities (groupId there comes with its groupTitle) |
The group title: 1 General, 4 Room amenities, 5 Bathroom, 6 Media & Technology, 12 Kitchen, 14 View, 17 Bedroom, 19 Accessibility ... | altFacilitytypeId equals the group id with the same title (checked on all 8 groups used). |
questionId |
questionsAndAnswers.questionIds of /stays/property-facilities; questions[].questionId of /stays/questions |
The question and answer text in /stays/questions |
Same ids: the 20 ids of property-facilities are the 20 most-voted of the 199 questions of hotel 6966158. questions[].roomId is a roomId of /stays/rooms (an old room may no longer be listed). |
Credit card id |
paymentMethods.acceptedCreditCards[].id of /stays/house-rules |
The name is in the same object (name, nameEn) |
No separate lookup. Seen: 1 American Express, 2 Visa, 3 Mastercard, 5 Diners Club, 7 JCB, 11 Discover, 44 UnionPay credit card. |
Map pin id / destination |
markers.<type>[] of /stays/map-markers: destination = city:20088325, district:10728, landmark:11045, airport:39 |
The destination of /stays/search, /stays/map and /stays/page-metadata |
The same ids as /stays/autocomplete (checked: Empire State Building 11045, LaGuardia 39, New York 20088325, each searched). Beach and ski ids have no destination form. |
destination for page metadata |
destination of a /stays/autocomplete suggestion (hotel:, city:, district:, airport:, landmark:, region:, country:) |
/stays/page-metadata |
The same token that search takes. |
Facility slug |
facilities[].slug of /stays/facilities |
A stable text name for the facility id (e.g. airconditioning) |
No lookup needed. |
Photo photoId |
photos[].photoId of a room in /stays/rooms |
The same photo in /stays/photos (all 20 room photos of hotel 6966158 are there) |
A guest photo of review-photos is a different set of ids. |
Review reviewId |
photos[].reviewId of /stays/review-photos |
id of a review in /stays/reviews |
Same id space (5 of 13 photos found on the first 300-600 reviews of two hotels; the others belong to older reviews: page deeper). |
| Review category | categories[].id of /stays/review-scores (overall.categories and each guest type) |
The same categories in /stays/review-score-comparison, matched by id |
Same ids except wifi: hotel_wifi in review-scores, hotel_free_wifi in review-score-comparison (both "WiFi"). The city for the comparison is the hotel's location.destinationId (destination=city:<id>). |
| Review filters | options[].id of /stays/review-filters |
topicIds, reviewLanguages, sortBy, customerType, timeOfYear of reviews |
|
| Search filter and sort | filter strings of search-filters; sorters of search-sort-options |
filters and sortBy of search |
|
Attraction id (PR...) |
attractions[].id of /attractions/search (and of the five cards in things-to-do); products[].productId of attractions/autocomplete |
productIds of attractions/search; productId of attractions/reviews, review-snippets, availability-calendar |
The same id is part of the slug. |
Attraction slug |
attractions[].slug of attractions/search; productSlug of attractions/autocomplete |
slug of attractions/product, comparison, availability |
The WHOLE slug (id + name, lowercase); the bare id is "not found". |
Attraction city destination (city:<id>) |
destination of attractions/destinations / autocomplete (landmarks too: their city) |
destination of attractions/suggestions, search, search-filters |
The number is the city id (ufi, may be negative). A landmark's id goes in filters as landmark::<id>. |
Attraction ticket id (ATO-...) + price |
...items[].id and price of attractions/availability |
items[] of attractions/live-availability |
One ticket type in one time slot. |
| Attraction filter | filterGroups[].options[].filter of attractions/search or attractions/search-filters |
filters of the same endpoints |
|
countryCode (cars) |
countries[].code of /cars/countries |
Every cars call | Changes the inventory and prices. A searchKey only works with the country it was made with. |
Cars searchKey |
data.searchKey of /cars/search |
vehicle, supplier, supplier-reviews, supplier-location, terms, price-summary |
Signed; pass it exactly as returned. |
Car vehicleId |
data.cars[].id of /cars/search |
The same six follow-up calls | Only valid with the searchKey of the same search. |
Car depot locationId |
data.cars[].pickUp.locationId of /cars/search |
Information only | Search takes coordinates, not this id. |
Car extra id |
data.vehicle.optionalExtras[].id of /cars/vehicle |
extras[].id of /cars/price-summary |
An id not of that car is silently ignored. |
| Cars filter and sort | data.filters.families[].options[].filter and data.sort[].identifier of /cars/search |
filters and sortBy of the same endpoint |
Menu differs per search. |
Taxi place id (googlePlaceId) |
places[].googlePlaceId of /taxi/autocomplete; places[].placeId of /taxi/airports |
pickUpPlaceId / dropOffPlaceId of /taxi/search |
Google's place id; the same airport has the same id in both. |
Airport iata (taxi) |
places[].iata of /taxi/autocomplete / /taxi/airports |
departureIata / arrivalIata of /taxi/flights |
|
Taxi supplier.id + supplier.locationId |
outbound[] / return[] of /taxi/search |
supplierId + locationId of /taxi/supplier |
Must be the pair from the same ride. |
Taxi vehicle.id / carTypeId |
outbound[].vehicle.id of /taxi/search |
Matches totals[].carTypeId (the whole-trip price of that vehicle type) |
|
Taxi outboundSearchId / returnSearchId |
/taxi/search |
Information only | Booking.com's ids of the two searches; the app uses them to start a booking, which this API does not cover. |
Anatomy of a blockId (a rate)
696615802_287466585_4_0_0_1457283 = roomId _ terms _ guests _ breakfast _ packageId _ bundleId. Checked on all 50 rates of hotel 6966158:
| Part | Example | Equals |
|---|---|---|
| 1 | 696615802 |
roomId |
| 2 | 287466585 |
the payment/deposit terms group of the rate: 287466585 goes with paymenttermsId 1 + deposittermsId 1, 404808573 with 33 + 152 (one-to-one in this sample) |
| 3 | 4 |
nrAdults and maxOccupancy of the rate |
| 4 | 0 |
breakfastIncluded (0 or 1) |
| 5 | 0 |
packageId |
| 6 | 1457283 |
bundleExtras.bundleId |
Flights place token (BOM.CITY, DEL.AIRPORT) |
/flights/autocomplete data.places[].token |
from / to of /flights/search, from / to of /flights/fly-anytime |
Flight offer id |
/flights/search data.offers[].id and data.deals[].offerId |
offerToken of /flights/details and POST /flights/fare-quote |
Fare id (otherFares[].id) |
/flights/details data.otherFares[].id |
offerToken of POST /flights/fare-quote |
Flights quote.token |
POST /flights/fare-quote data.quote.token |
quoteToken of /flights/fare-quote/extras and /flights/seat-map |
Airline code (6E, AI) |
/flights/search data.filters.airlines.options[].code, legs[].marketingCarrier.code |
airlines of /flights/search |
Airport code (BOM, NMI) |
/flights/search data.filters.airports.byCity[].airports[].code |
airports of /flights/search |
2. Open: IDs without a lookup
These are in the responses but nothing in the API explains them yet. Names that Booking.com sends next to them are already in the response.
| ID | Where | What we know | Status |
|---|---|---|---|
roomtypeId |
rates[] of rooms / property-details |
A category per room: in hotel 6966158 9 = the King rooms, 4 = Queen/two-bed room, 5 = the suites, 13 = the family rooms |
No lookup. The room's own name is in rooms[].roomName. |
paymenttermsId, deposittermsId, policygroup_instance_id (33/152/-) |
rates[] of rooms |
Identify the payment and deposit terms of a rate; two groups in the sample (1/1 and 33/152) | No lookup. The terms themselves (prepayment and cancellation timelines with dates and amounts) are inside each rate's paymentterms. They are not the policy-group ids of /stays/policies. |
packageId, bundleExtras.bundleId, benefits[].catalogItemId |
rates[] of rooms |
A rate package (0 = none) and a bundle of extras ("Late check-in + high-speed internet"); catalogItemId 14 = Late check-in |
No lookup. Titles and details are inline in bundleExtras. |
Room facility 4 ("Shower") |
rooms[].facilities[] |
Not in property-facilities |
One-off gap; the name is inline. |
facilitytypeId |
rooms[].facilities[] |
An older facility-type id (4, 5, 6, 7, 8, 9, 19) next to altFacilitytypeId (the group id) |
No lookup; use altFacilitytypeId. |
bedType / bedtypeId |
rooms[].bedConfigurations, apartment layouts |
3 = extra-large double bed, 5 = sofa bed | No lookup; names are inline (name, nameWithCount). |
Surroundings id |
landmarks.top[].id, airports[].id ... of /stays/surroundings |
Booking.com's own id of the place | No lookup. Not the same ids as /stays/autocomplete (LaGuardia is 65884 in surroundings and airport:39 in autocomplete); name and coordinates are inline. |
Attraction offers[].id, itemIds |
attractions/search |
Offer and item ids of an attraction | Not an input of any endpoint; the tickets to check are the ATO- ids of attractions/availability. |
Reference: Dates and guests
Some data depends on the stay (dates, guests), some does not. This page says, for every endpoint, whether you must send dates, what changes with them, and what the response tells you when you leave them out.
1. By endpoint
| Endpoint | Dates | Guests | What depends on them |
|---|---|---|---|
GET /stays/autocomplete, /stays/suggestions |
not accepted | not accepted | Nothing. |
GET /stays/search, /stays/search-filters, /stays/search-sort-options, /stays/map |
required (/stays/search and /stays/map can use flexible dates instead: a stay length, a check-in weekday and up to 3 months, or ± 1, 2, 3 or 7 days around exact dates; then every property shows its own cheapest window in stay) |
adults, rooms, childrenAges |
Which properties are available, their prices, the filter counts and the sort options. |
GET /stays/property-details |
optional, both or neither | adults, rooms, childrenAges |
Only availability, pricing, recommendation, rooms and rates. The property itself (name, address, policies) is the same on every date. Left out: tomorrow and the day after, with availability.datesAreDefault: true. |
GET /stays/rooms, /stays/room-types |
required | adults, rooms, childrenAges |
Which room types and rates can be booked, and their prices. |
GET /stays/things-to-do |
optional, both or neither | not accepted | The prices and links of the five attractions. Left out: tomorrow and the day after, with datesAreDefault: true. |
GET /attractions/search |
optional, both or neither | not accepted | With dates: only attractions bookable in that window, priced for it. Without: the whole list, not filtered by availability. |
/stays/property-facilities, /stays/facilities, /stays/questions, /stays/house-rules, /stays/surroundings, /stays/map-markers, /stays/food-and-drink, /stays/description-sections, /stays/photo-list, /stays/badges, /stays/page-metadata, /stays/description, /stays/highlights, /stays/photos, /stays/review-photos, /stays/important-info, /stays/policies, /stays/review-scores, /stays/featured-reviews, /stays/review-filters, /stays/reviews |
not accepted | not accepted | Nothing: they describe the property, not a stay. (Measured: dates and guests changed none of them.) |
2. When you leave the dates out
Where the dates are optional (property-details, things-to-do), Booking.com itself needs dates, so we use tomorrow and the day after. The response says so:
property-details:data.availability.datesAreDefaultistrue.things-to-do:data.datesAreDefaultistrue.
Then read the stay-dependent parts as "for that one night". A hotel can show sold out, no rooms, no rates for tomorrow and be bookable a week later (hotel 6966158: 0 rooms tomorrow, 1 room and rate on later dates at different prices). So send checkin and checkout whenever you show prices, rooms or availability, and only rely on a date-free call for what the property is.
Only one of the two dates is rejected with "checkin" and "checkout" must be given together (or both left out).
3. Rules that apply wherever dates are accepted
YYYY-MM-DD,checkoutaftercheckin.- Not in the past (yesterday is accepted), at most 90 nights, at most 500 days ahead for stays. The attraction supplier only answers from about 3 days back to 180 days ahead (an empty list outside).
roomscannot be more thanadults;childrenAgesis a comma list of ages,0= under 1 year.
4. "Sold out" means "not bookable for this search"
/stays/room-types marks a room type sold out when it is not bookable for your dates and your guests. Booking.com does not say whether the type is sold out or just does not fit the party (for example too many adults for it). Change the dates or the guests and the answer can change.
Reference: Rules for every endpoint
Authentication
Every /stays and /common request needs your API key in a header:
X-RapidAPI-Key: YOUR_KEY
X-RapidAPI-Host: booking-com30.p.rapidapi.com
Without it you get "X-RapidAPI-Key header required"; a wrong or revoked key gives "Invalid or revoked API key".
Response format
Every response is HTTP 200 with a JSON body, including errors. Read status to know whether the call worked:
{ "status": true, "message": "Properties found", "data": { } }
| Field | Meaning |
|---|---|
status |
true when the call worked and returned something; false otherwise. |
message |
A short sentence saying why. Always present. |
data |
The result. Absent on errors. |
status: false with an empty result (for example "No reviews found for this property") is a normal answer, not a failure - the request was fine, there is just nothing to show. Each endpoint page has a table of its status/message cases.
Errors
| Situation | message |
|---|---|
| Missing or invalid API key | X-RapidAPI-Key header required / Invalid or revoked API key |
| No active subscription | An active subscription is required |
| Monthly quota used up | Monthly request quota exceeded (data has monthlyRequestLimit and period) |
| Too many requests in a short time | Too many requests. Please try again later. |
| A parameter is wrong | Validation failed, plus errors[] with the field and what is wrong. No quota is used. |
| Booking.com did not answer | The endpoint's own ...provider is unreachable / ...returned HTTP <n> message |
| Unknown route | Route not found |
Quota and limits
Calls that fetch data count against your monthly quota. Calls that fail validation, and the /common lists, do not. Responses carry:
X-RateLimit-LimitandX-RateLimit-Remaining- your monthly limit and what is left.X-Usage-Warning- appears once you are close to the limit.
Every call counts as one use.
Names and shapes
- Field names are camelCase (
reviewCount,hotelId).GET /stays/important-infokeeps Booking.com's own field names instead. - No field name depends on the data. Maps keyed by an id or a price are returned as lists of objects.
- A missing value is
null(Booking.com's empty strings are turned intonullin the fields we name). Lists that have nothing are[]. - Scores and counts are numbers (
8.7, not"8.7") and 0/1 flags aretrue/false. Prices Booking.com sends already formatted ("US$35") stay text; where a plain number is also available, the endpoint page says so. - Every object that carries Booking.com data has an
extrasfield: anything Booking.com sends that has no named field here, so nothing is silently dropped. It isnullwhen there is nothing extra. - Dates are
YYYY-MM-DD. A review'sdatealso carries the time (YYYY-MM-DD HH:MM:SS) and has no time zone.
Language and currency
languageCode(defaulten-us) translates the text of the response. Valid codes:GET /common/languages. OnGET /stays/reviewsit chooses which review language is shown first; it does not filter.currencyCode(defaultUSD) sets the currency of prices where an endpoint has prices. Valid codes:GET /common/currencies. Prices that belong to the property itself (cot and extra-bed prices inGET /stays/policies) stay in the property's own currency.
Identifiers
| You have | You get it from | You pass it to |
|---|---|---|
destination (city:-2092174, latlong:18.93,72.82, ...) |
autocomplete / suggestions |
search, search-filters, search-sort-options |
hotelId |
a search result's id |
every property endpoint |
filters values (class::5, ...) |
search-filters |
search |
sortBy values |
search-sort-options |
search |
| Review sort and filter ids | review-filters |
reviews |
Paging
| Endpoint | Parameters | Notes |
|---|---|---|
search |
page (1-50) |
20 properties per page; pagination tells you the total and whether there is a next page. |
reviews |
page, pageSize (1-100, default 25) |
hasNextPage is true when a page is full; a page past the end is empty. |