API Reference
Read a Booking.com property
GET /booking/hotel — bearer auth, JSON responses, billed per successful request.
GET/booking/hotel
Read a Booking.com property
Reads a single Booking.com property page into a structured object. Resolved values include price and per-room prices as { amount, currency, original, discount }, rating as { score, word, count }, and facilities grouped as the page displays them. Also returns text lists: points of interest, review subscores, featured reviews, questions, and sections.
When to use it. Use this endpoint when you need structured hotel data from a known Booking.com URL and do not want to manage crawl collection yourself. For bulk extraction or periodic refresh, use /crawl instead.
- Dates are paired:
checkinandcheckoutare both required or both omitted; omitting them yields no room prices. - URL query string ignored: Pass stay parameters to this endpoint, not in the Booking.com URL; the page is always read in English regardless of the URL language.
- Cost is flat 30 credits: Failed reads due to Booking's challenge page are not charged; 500 errors refund credits.
| Parameter | In | Type | Description |
|---|---|---|---|
| url * | query | string<uri> | A Booking.com property page, `https://www.booking.com/hotel/<country>/<name>.html`, in any language. Anything else is refused. |
| checkin | query | string<date> | The first night, as `YYYY-MM-DD`, today or later. **Requires `checkout`.** Optional: without dates Booking still shows the page, it just prices nothing. |
| checkout | query | string<date> | The day you leave, as `YYYY-MM-DD`, after `checkin`. **Requires `checkin`.** |
| adults | query | integer | How many adults are staying. |
| rooms | query | integer | How many rooms they need. |
| currency | query | string | The currency to price in, as a three-letter ISO 4217 code. Left to Booking when absent, which usually means the currency of the country the crawl exits from. |
| premium | query | string | Go through the premium proxy pool instead of the standard one. Free here, unlike on `/crawl` -- the price is flat -- but worth trying if the standard pool is being turned away. `true`, `false`, `1`, `0`, `yes`, `no`, `on`, `off`, in any case. Anything else is refused rather than read as `false`. |
| country | query | string | The country to appear to be browsing from, as a two-letter ISO 3166-1 alpha-2 code. Free. Booking prices and ranks by where you are, so this can change the answer. Required to use `city`. |
| city | query | string | The city inside that country, as the pool spells it. **Requires `country`.** Free here, where on `/crawl` it doubles the price. |
| key | query | string | The API key, as an alternative to the `Authorization` header. Ignored when a header is present. |
request.sh
curl -X GET "https://app.irmu.com/api/booking/hotel?url=&checkin=&checkout=&adults=&rooms=¤cy=&premium=&country=&city=&key=" \
-H "Authorization: Bearer $IRMU_API_KEY"200.json
{
"url": "https://www.booking.com/hotel/it/relais-la-maison-de-luxe-b-b.en-gb.html?checkin=2026-11-11&checkout=2026-11-12&group_adults=2&no_rooms=1&group_children=0",
"checkin": "2026-11-11",
"checkout": "2026-11-12",
"adults": 2,
"rooms": 1,
"currency": null,
"hotel": {
"name": "Relais La Maison de Luxe B&B",
"address": {
"@type": "PostalAddress",
"streetAddress": "Via Nazionale 10",
"addressLocality": "Rome",
"addressCountry": "IT"
},
"description": "Set in Rome, 600 metres from Termini...",
"rating": {
"score": 8.7,
"word": "Fabulous",
"count": 426
},
"price": {
"amount": 112,
"currency": "EUR",
"original": 140,
"discount": 28
},
"rooms": [
{
"name": "Double Room",
"prices": [
{
"amount": 112,
"currency": "EUR",
"original": 140,
"discount": 28
}
]
}
],
"facilities": [
{
"group": "Internet",
"items": [
"Free WiFi"
]
}
],
"images": [
"https://cf.bstatic.com/xdata/images/hotel/max1024x768/1.jpg"
],
"pointsOfInterest": [
"Termini 600 m"
],
"reviewSubscores": [
"Staff 9.2"
],
"reviews": [
"Great location and very clean."
],
"questions": [
"Is breakfast included?"
],
"sections": [
"Property surroundings..."
],
"url": "https://www.booking.com/hotel/it/relais-la-maison-de-luxe-b-b.en-gb.html?checkin=2026-11-11&checkout=2026-11-12&group_adults=2&no_rooms=1&group_children=0"
},
"credits_charged": 30,
"credits_remaining": 970,
"job_id": "0198a9b6-1f4c-7c3e-9a2b-5d8e6f0a1b23_0198a9b6-2a71-7f0d-8c44-9e1b3c5d7f02",
"status": "done",
"position": null,
"debug": null,
"error": null
}request.js
const res = await fetch("https://app.irmu.com/api/booking/hotel", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.IRMU_API_KEY}`,
"Content-Type": "application/json",
}
});
const data = await res.json();request.py
import os, requests
res = requests.get(
"https://app.irmu.com/api/booking/hotel",
headers={"Authorization": f"Bearer {os.environ['IRMU_API_KEY']}"}
)
print(res.json())| Status | Meaning |
|---|---|
| 200 | The property. |
| 202 | Paid for and still going. Collect it from `/crawl/{job}`, free, as a slow crawl is collected. That endpoint answers the crawl envelope, so what is lifted into `hotel` here arrives under `data` there. |
| 401 | No key, an unknown key, or a caller that is not an organization. |
| 402 | Not enough credits, or the daily limit is reached. Nothing is charged and no attempt is recorded. |
| 422 | A malformed request -- no url, a url that is not a Booking.com property page, one date without the other, dates in the past, or a flag that is not a yes or a no. |
| 500 | Nothing came back: the crawl failed outright, or every block ran and found nothing -- Booking's challenge page, or a layout the recipe no longer matches. **The credits are refunded either way**, so `credits_charged` is `0`. The attempt is still recorded against `www.booking.com`. |
| 503 | The crawl could not be routed through a proxy pool. Nothing is charged. |
Start building with Irmu today
200 free credits every month, no card required. Every API, every integration, one key.