Booking.com API Alternative: Get Hotel Data Without Partner Approval
The official Booking.com API is only open to approved partners. Here's how to get search results, hotel details, room prices and ratings as JSON anyway — with curl, Python and Node examples.
Why most developers can't use the Booking.com API
Booking.com does have APIs, but they're built for its business partners — connectivity providers, affiliates and accommodation managers — and access goes through an application and approval process. If you're a developer building a price tracker, a market study or a travel side project, you'll usually find the door closed, or open only to endpoints that don't return what you need.
So people search for "Booking.com API" and end up scraping. Scraping Booking yourself means a JavaScript-rendered results page, lazy-loaded cards, frequently changing markup and bot protection that turns away datacenter IPs. It works until it doesn't, usually on the day you need the data.
What you actually need from Booking.com
Most projects need two things: the list of properties in a destination for a stay, and the details of a single property. Irmu has a ready-made endpoint for each, so you don't write or maintain selectors.
- `GET /booking/search` — a destination plus optional `checkin`, `checkout`, `adults`, `rooms`, `currency`. Returns the first page of results, one row per property card.
- `GET /booking/hotel` — a `booking.com/hotel/...` URL plus optional dates. Returns one object: price and room prices, rating, facilities, points of interest, review subscores, featured reviews and questions.
- Both cost a flat 30 credits. `premium`, `country` and `city` change where the request comes from, not the price.
Search a destination
Pass the destination the way you'd type it into Booking's search box. Add dates if you want prices — without dates, many cards show no price. Every field comes back as text, exactly as Booking prints it, and a field the card doesn't show is left out of that row.
curl -G "https://app.irmu.com/api/booking/search" \
-H "Authorization: Bearer $IRMU_API_KEY" \
--data-urlencode "destination=Lisbon" \
-d checkin=2026-12-04 -d checkout=2026-12-06 \
-d adults=2 -d rooms=1 -d currency=EUR{
"destination": "Lisbon",
"checkin": "2026-12-04",
"checkout": "2026-12-06",
"adults": 2,
"rooms": 1,
"hotels": [
{
"name": "…",
"url": "https://www.booking.com/hotel/pt/….en-gb.html",
"price": "€ 318",
"priceInfo": "2 nights, 2 adults",
"address": "Baixa, Lisbon",
"reviewScore": "8.9",
"reviewWord": "Fabulous",
"reviewCount": "2,105 reviews"
}
],
"credits_charged": 30,
"status": "done"
}A search that returns no properties is still a served request and is still charged. Check your destination spelling before running a big batch.
Read a single hotel
Feed any property URL from the search into `/booking/hotel`. Here the data is structured: price and each room price as `{ amount, currency, original, discount }`, rating as `{ score, word, count }`, and facilities grouped the way the page groups them.
If the page can't be read, `hotel` comes back `null` and the request is refunded (`credits_charged: 0`) — queue it for a retry instead of treating it as an empty hotel.
import os, time, requests
API = "https://app.irmu.com/api"
HEADERS = {"Authorization": f"Bearer {os.environ['IRMU_API_KEY']}"}
def get_hotel(url, checkin=None, checkout=None, adults=2, currency="EUR"):
params = {"url": url, "adults": adults, "currency": currency}
if checkin: params |= {"checkin": checkin, "checkout": checkout}
res = requests.get(f"{API}/booking/hotel", headers=HEADERS, params=params, timeout=200)
body = res.json()
while res.status_code == 202: # paid, still running — collecting is free
time.sleep(5)
res = requests.get(f"{API}/crawl/{body['job_id']}", headers=HEADERS, timeout=60)
body = res.json()
return body
h = get_hotel("https://www.booking.com/hotel/pt/example.en-gb.html", "2026-12-04", "2026-12-06")
if h.get("hotel") is None:
print("unreadable, refunded — retry later")
else:
print(h["hotel"]["rating"], h["hotel"]["price"])From search to dataset in Node
The usual pipeline: search a destination for a stay, deduplicate the property URLs, then read each hotel. Keep concurrency within your plan's limit and back off on `429`.
const API = "https://app.irmu.com/api";
const headers = { Authorization: `Bearer ${process.env.IRMU_API_KEY}` };
const stay = { checkin: "2026-12-04", checkout: "2026-12-06", adults: "2", currency: "EUR" };
async function call(path, params, tries = 0) {
const res = await fetch(`${API}${path}?${new URLSearchParams(params)}`, { headers });
if (res.status === 429 && tries < 5) {
await new Promise((r) => setTimeout(r, 2 ** tries * 1000));
return call(path, params, tries + 1);
}
return res.json();
}
const search = await call("/booking/search", { destination: "Lisbon", ...stay });
const urls = [...new Set(search.hotels.map((h) => h.url.split("?")[0]))];
for (const url of urls) {
const { hotel } = await call("/booking/hotel", { url, ...stay });
if (!hotel) continue; // refunded; retry later
console.log(hotel.name, hotel.price?.amount, hotel.rating?.score);
}Seeing prices like a local
Booking shows different prices, taxes and sometimes availability depending on where the visitor appears to be. Use `country` (and optionally `city`) to pin the request to the market you care about, and set `currency` explicitly so your numbers are comparable. If the standard pool gets turned away, `premium=true` uses residential IPs at no extra cost on these endpoints.
Cost and billing
Every search and every hotel read is 30 credits. A destination search plus 25 hotel reads is 780 credits. Tracking that set daily for a month is about 23,400 credits — within the Lite plan's monthly volume.
- Charged: any served request, including a search with no results.
- Refunded: a hotel page that couldn't be read (`hotel: null`, `credits_charged: 0`).
- Free: collecting a `202` job from `GET /crawl/{job}`.
Official API or Irmu?
If you're an approved Booking.com partner and the partner API returns what you need, use it — it's the supported route. If you're not, or you need what the public site shows a traveller (the displayed price, reviews, facilities, the ranking in search), the endpoints above get you there in a few lines without maintaining a scraper.
For a full walkthrough of building a hotel database and storing rate history over time, read our guide on scraping hotel prices.
Keep reading
ChatGPT Brand Monitoring: Track What AI Tells Your Customers (2026)
Build your own LLM visibility tracker: run a fixed set of buyer questions through ChatGPT on a schedule, record whether your brand is mentioned, where, and which sources are cited — with Python, Node and SQL.
AIAI Web Scraping: Extract Data Without Writing Selectors
When to ask a question about a page instead of writing CSS selectors, when to combine both in a recipe, and what each approach costs — with curl, Python and recipe JSON.
GuidesHow to Scrape Hotel Prices and Build a Hotel Database (2026)
Build a hotel database and track nightly rates over time: search a destination, read each property, store rate snapshots and monitor changes — with working Python, Node, curl and SQL.
Start building with Irmu today
200 free credits every month, no card required. Every API, every integration, one key.