Hotel Rooms API
Extract comprehensive room details and bookable rates from Booking.com hotels by hotel ID.
Overview
Fast & Reliable
Returns normalized live room inventory and rate data. Typical response time: 2–4 seconds.
The Hotel Rooms endpoint returns static per-room information (descriptions, photos, bed configurations, facilities, highlights) alongside the bookable rates available for a specific date range (prices, refund policies, meal plans, availability). You can use the same endpoint for both a visual room catalogue and a booking-intent quote.
Endpoint URL
Need a hotel ID?
Use /v1/booking/hotel/url-to-id to convert a Booking.com URL or slug to a numeric hotel ID.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| hotel_id | integer (> 0) | Required |
Numeric Booking.com hotel ID (for example, 346648).
|
| checkin | string (YYYY-MM-DD) | Optional | Arrival date. Defaults to today + 14 days. |
| checkout | string (YYYY-MM-DD) | Optional | Departure date. Defaults to today + 15 days. |
| adults | integer | Optional | Number of adults (1–30, default: 2). |
| children | integer | Optional | Number of children (0–10, default: 0). |
| rooms | integer | Optional | Number of rooms (1–8, default: 1). |
| currency | string (ISO 4217) | Optional |
Display currency for rate prices (default: USD). Examples: EUR, GBP, THB.
|
| country_market | string (ISO-3166) | Optional |
Two-letter market country (default: US). Booking.com prices by the visitor's country, so the same stay can cost different amounts per market. Use the same value across search, rooms, and prices for matching numbers; the value used is echoed in the response.
|
Response Structure
Top-level fields
success— boolean, alwaystruefor 2xx responses.data.hotel_info— basic property info (id,currency_code).data.rooms— array of room types with static data (see below).data.rates— array of bookable blocks for the requested dates (see below).data.availability_summary— deduplicated inventory totals acrossdata.rates:availability_status—availablewhen at least one bookable rate was returned, otherwiseno_inventory.total_available_rooms— sum of the maximumroom_count_availableperroom_id, so a room type sold under several rate plans is counted once.nullwhen there are no bookable rates.available_rate_blocks— number of entries indata.rates.available_room_types_counted— number of distinctroom_ids that contributed a count.room_counts_by_room_id— the per-room-type counts that were summed.rates_without_room_count_available— rate blocks returned without a usable count.calculation_method— human-readable formula string.
data.search_config— echoes the guest/date configuration you requested.data.metadata—hotel_id,total_rooms,total_blocks,arrival_date,departure_date,scraped_at.retrieved_at— ISO-8601 UTC timestamp.
Per-room fields (data.rooms[])
id— stable room-type identifier.name— human-readable room-type name (derived from the first associated rate).description— full room description (may contain HTML formatting).ai_description— short AI-generated comparative description (may contain<b>tags).room_size_m2,room_size_ft2— room size in metric and imperial units.is_smoking,is_dormitory— booleans.bathroom_count— number of bathrooms;nullwhen Booking.com doesn't list a count (common for hotel rooms).private_bathroom—truefor a private bathroom,falsefor a shared one,nullwhen unknown.photos[]— array withid,url_original,url_max300,url_square60,url_640x200, andratio.bed_configurations[]— each has abedsarray withbed_type,name,name_with_count,count,description,description_imperial.facilities[]— each hasid,name,category,category_id.highlights[]— each hasid,name,icon.
Per-rate fields (data.rates[])
Each entry represents one bookable "block" — a specific combination of a room type, a cancellation/refund policy, and a meal plan. A single room type can appear multiple times (for example, refundable vs non-refundable).
block_id— unique identifier for this bookable option.room_id— links this rate to an entry indata.rooms[].name— full rate name, e.g. "Laguna Twin Room - Non-refundable".room_name— the room-type name without the policy suffix.max_occupancy,nr_adults,nr_children.refundable,refundable_until— cancellation policy.breakfast_included,half_board,full_board,all_inclusive,mealplan— meal configuration.room_count_available— how many rooms of this type Booking.com will sell for the requested dates. It is bounded by the property’s allotment on Booking.com, not its physical inventory, and is typically identical across rate blocks sharing the sameroom_id, so do not sum it across rate blocks. Usedata.availability_summary.total_available_roomsfor a deduplicated total, and compare values only within one property across dates.genius_discount_percentage— Booking.com Genius loyalty discount if applicable.price— object withtotal,per_night,currency,formatted, plusbefore_discount(Booking.com's struck-through price, e.g."$642") anddiscount_name(e.g."Bonus savings") when the property offers a discount, otherwisenull. Booking.com occasionally returns a rate without the discount, so a higher price with a nullbefore_discountis an undiscounted quote.
Usage Tips
Static vs. dynamic data
rooms[] changes rarely (new photos, re-categorisation) — safe to cache for hours or days. rates[] is dynamic (availability, pricing) — refresh per user query.
Best Practices
- Join
rates[].room_idback torooms[].idto display photos and facilities next to each bookable rate. - The hotel name is not returned here — call /v1/booking/hotel/details if you need it.
- Empty
roomsandratesarrays with a 200 status mean the property has no availability for the requested dates — try different dates rather than retrying. - If you only have a URL, call
/v1/booking/hotel/url-to-idonce and cache the resultinghotel_id. - For a currency other than USD, always pass the
currencyparameter —hotel_info.currency_codereflects the hotel's native currency, not the price display currency.
Error handling and status codes
Status codes: 200 on success; errors use non-2xx responses with RFC 7807 Problem Details.
- 422: Missing or invalid
hotel_id(not a positive integer). - 404
NOT_FOUND: Upstream reports the hotel does not exist. - 502
UPSTREAM_ERROR: Upstream non-2xx or protocol error. - 503
SERVICE_UNAVAILABLE: Upstream WAF challenge or maintenance. - 504
GATEWAY_TIMEOUT: Upstream response timed out. - 500
INTERNAL_ERROR: Unexpected processing error.
Error responses (Problem Details)
All Booking.com hotel endpoints return errors using RFC 7807 Problem Details.
{
"type": "https://api.stayapi.com/errors/invalid-url",
"title": "Invalid URL",
"status": 400,
"detail": "Parameter 'url' must be a full Booking.com hotel URL of the form https://www.booking.com/hotel/{cc}/{slug}.html.",
"error_code": "INVALID_URL",
"provided": "baan-coconut"
}
Media type: application/problem+json
Standard fields: type, title, status, detail
Extensions: error_code and any endpoint-specific fields
2xx policy: 2xx is returned only when data extraction succeeds.