360 Secure SkillHub
360 安全技能中心

Booking.com Hotel Data API - Search, Live Prices, Reviews

封装 Booking.com 三个接口(各 1 积分),基于目的地与入住日期搜索酒店,返回每晚实时价格、评分、星级、取消与早餐政策;可按价格、星级、评分、房型筛选并分页,每页 25 条。也可用搜索结果中的链接拉取单个酒店的房型、设施、入住规则与图片,以及含分项评分和优缺点摘要的客人点评。输入含日期、人数、儿童年龄、房间数与货币,输出统一 JSON 信封,适合比价、竞品监测与旅行数据管道。

scavio-ai
scavio-ai
热度 51.37
最近更新 2026-10-11 21:51:44
分类:生活依赖:第三方 API应用场景:旅行 / 推荐 / 研究

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add booking-com-hotel-data
Metadata
name
booking-com-hotel-data
description
Search Booking.com for a destination and stay with live nightly prices, pull one property in full with rooms and rate plans, and read guest reviews with the category breakdown. 3 endpoints, 1 credit each, structured JSON.
version
1.0.0
tags
booking, booking-com, hotels, travel, hotel-prices, accommodation, hospitality, rate-shopping, revenue-management, guest-reviews, otas, travel-data, price-comparison, agents, structured-data, json, ai-agents, scraping-api
metadata
{"openclaw":{"requires":{"env":["SCAVIO_API_KEY"]},"primaryEnv":"SCAVIO_API_KEY","timeout":120,"throttle":1,"emoji":"🏨","homepage":"https://scavio.dev/docs/booking-search?utm_source=agent-skills&utm_medium=skill&utm_campaign=booking-com-hotel-data"}}

Booking.com via Scavio

Search Booking.com for a destination and a stay, read one property in full with its rooms and rate plans, and pull guest reviews with the score breakdown. All endpoints return structured JSON.

When to trigger

Use this skill when the user asks to:

  • Find hotels, apartments or hostels in a city for specific dates
  • Compare live nightly prices, review scores and star ratings across properties
  • Filter by price per night, star rating, review score, property type, free cancellation, no prepayment or breakfast
  • Pull one property in full - rooms and rate plans, facilities, house rules, check-in windows, policies, images
  • Read guest reviews with the per-category subscores and Booking's own praise and complaint summary
  • Build rate-shopping, competitive-set or travel-research pipelines

Setup

Get a free API key at scavio.dev (50 free credits to get started, no card required):

export SCAVIO_API_KEY=sk_live_your_key

If you do not have a key yet

An agent running this skill without SCAVIO_API_KEY set will get 401 on every call below. The whole path from nothing to a working key is self-serve:

  1. Sign up at dashboard.scavio.dev - email or Google, no card required.
  2. A key is created for the account automatically at signup. It is on the dashboard under API Keys, ready to copy.
  3. A new account starts with 50 credits. Endpoints in this skill cost 1 credit each unless the table below says otherwise.

When the balance runs out the API answers 402 with a JSON body carrying billing_url. Topping up needs no code change - the same key keeps working. The smallest purchase is 2,500 credits for $25, and monthly plans work out cheaper per credit if the usage is steady rather than one-off.

Every request is a POST with a JSON body and:

Authorization: Bearer $SCAVIO_API_KEY

Endpoints

Base URL: https://api.scavio.dev. Every Booking.com endpoint costs 1 credit.

Endpoint Credits What it returns
POST /api/v1/booking/search 1 Properties for a destination and stay: live nightly price, review score, star rating, location, room type, deal badges
POST /api/v1/booking/hotel 1 One property in full: rooms and rate plans, facilities, house rules, check-in windows, policies, images, location, review scores
POST /api/v1/booking/reviews 1 Guest reviews with the score breakdown by category and Booking's own praise/complaint summary

Workflow

  1. Search: call /booking/search with destination (or a numeric dest_id) and both checkin and checkout. Read properties[].url.
  2. One property: call /booking/hotel with that url as hotel. Chaining the URL a search row already returned is always the cheapest and safest path - a bare page slug needs the right country_code, and a wrong one is a real, billed 404.
  3. Reviews: call /booking/reviews with the same hotel value.

Booking prices a stay, not a property, so all three endpoints take dates.

Dates, currency and the two ways to waste a credit

  • checkin and checkout must be sent together. Booking ignores a lone checkin and prices its own default range, so you get real prices for dates nobody asked for. The API rejects an unpaired or out-of-order date.
  • Omitting dates entirely on /hotel or /reviews returns prices for a two-night range Booking chose. The response echoes whichever dates were actually used - read checkin, checkout and nights back before quoting a price.
  • A search with neither destination nor dest_id would return Booking's homepage - a credit spent for nothing - so the API rejects it up front.
  • Always send currency. It defaults to USD in the transport; without one Booking picks the currency itself and two identical requests can disagree.

Pagination

Only /search pages, with a 1-based page — 25 properties per page. count is what this page returned and total_results is Booking's headline count. /hotel and /reviews return a single response and take no page parameter; on reviews, total_count is the whole history and count is what this response holds.

Parameters

Search (/search)

Parameter Type Default Description
destination string one of Free-text destination (1-200 chars)
dest_id string one of Numeric Booking destination id
dest_type string -- city, region, country, district, landmark, airport, hotel. Requires dest_id
page integer -- 1-based, 25 properties per page
sort_by string popularity popularity, price_low, price_high, stars_high, stars_low, stars_and_price, distance, review_score
min_price / max_price number -- Per night, in currency
stars integer[] -- 1-5 stars, 1-5 items, OR'd
min_review_score string -- 6, 7, 8, 9 only
property_type string or integer -- apartments, hostels, hotels, motels, resorts, bed_and_breakfasts, villas, campgrounds, vacation_homes, lodges, homestays, or a raw numeric Booking accommodation-type id
free_cancellation boolean -- Free-cancellation rates only
no_prepayment boolean -- No-prepayment rates only
breakfast_included boolean -- Breakfast-included rates only
checkin / checkout string -- YYYY-MM-DD, sent together and in order
adults integer 2 Adult guests
children_ages integer[] -- Ages (0-17, max 10 entries), not a count
rooms integer 1 Rooms requested
currency string USD ISO 4217, 3 letters

destination or dest_id is required. min_review_score is an enum - an arbitrary threshold such as 8.4 is silently dropped upstream and the results come back unfiltered. dest_type on its own is ignored by Booking, so the API rejects it without dest_id.

Hotel (/hotel) and reviews (/reviews)

Parameter Type Default Description
hotel string required Booking.com property URL or the bare page slug (1-500 chars); query params are discarded
country_code string us 2 letters. Only consulted for a bare slug
checkin / checkout string -- YYYY-MM-DD, sent together and in order
adults integer 2 Adult guests
children_ages integer[] -- Ages, max 10
rooms integer 1 Rooms requested
currency string USD ISO 4217

Examples

import requests

BASE = "https://api.scavio.dev"
# Your key from https://scavio.dev. Load it from your environment or secret
# store in real code - keep it out of source control.
API_KEY = "sk_your_key_here"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

STAY = {"checkin": "2026-09-08", "checkout": "2026-09-10", "currency": "USD"}

# 1. Search a destination for a real stay - dates always in pairs
found = requests.post(f"{BASE}/api/v1/booking/search", headers=HEADERS,
    json={"destination": "Austin", "adults": 2, "rooms": 1,
          "sort_by": "review_score", "min_review_score": "8",
          "max_price": 300, **STAY}).json()

row = found["data"]["properties"][0]

# 2. Chain the URL the row already gave you - no country_code guessing
hotel = requests.post(f"{BASE}/api/v1/booking/hotel", headers=HEADERS,
    json={"hotel": row["url"], **STAY}).json()

# The response echoes the dates it actually priced
print(hotel["data"]["checkin"], hotel["data"]["checkout"], hotel["data"]["nights"])

# 3. Guest reviews for the same property
reviews = requests.post(f"{BASE}/api/v1/booking/reviews", headers=HEADERS,
    json={"hotel": row["url"], **STAY}).json()

# 4. A family stay: children_ages are AGES, not a headcount
family = requests.post(f"{BASE}/api/v1/booking/search", headers=HEADERS,
    json={"destination": "Lisbon", "adults": 2, "children_ages": [4, 9],
          "rooms": 1, **STAY}).json()

Response shapes

Every response uses the envelope { data, response_time, credits_used, credits_remaining }. Key data fields:

  • search — destination, url, page, checkin, checkout, nights, adults, children_ages, rooms, currency, dest_id, dest_type, destination_name, destination_country, total_results, count, properties[], bounding_box, sort, sort_options, applied_filters, available_filters, breadcrumbs. A property row: pos, hotel_id, name, page_name, url, country_code, city, address, latitude, longitude, display_location, district, distance_from_center, accommodation_type_id, star_rating, review_score, review_score_word, review_count, image, price, price_formatted, currency, price_per_night, original_price, charges_info, discounts, deal_badges, room_name, beds, bedrooms, bathrooms, unit_area, free_cancellation, free_cancellation_until, no_prepayment, meal_plan, rooms_left_message, is_sold_out, sponsored, preferred, genius_rate_available, is_sustainable, badges.
  • hotel — hotel_id, name, page_name, url, description, country_code, city, address, postal_code, region, latitude, longitude, dest_id, accommodation_type, star_rating, chain_ids, brand, review_score, review_count, review_subscores[], languages_spoken, currency, checkin, checkout, nights, adults, children_ages, rooms_requested, price_from, is_sold_out, image, images, facilities[], highlights, meals, checkin_from, checkin_until, checkout_from, checkout_until, min_checkin_age.
  • reviews — hotel_id, name, page_name, url, score, total_count, count, subscores[] (name, label, score, review_count), summary (review_count, pros, cons), topics[], reviews[] (review_id, title, positive, negative, score, reviewed_at, guest_name, guest_country, guest_review_count, is_anonymous, customer_type, trip_purpose, room_name, language).
{
  "data": {
    "destination": "Austin",
    "dest_type": "CITY",
    "checkin": "2026-09-08",
    "checkout": "2026-09-10",
    "nights": 2,
    "currency": "USD",
    "total_results": 955,
    "page": 1,
    "count": 25,
    "properties": [
      {
        "pos": 1,
        "hotel_id": 1234567,
        "name": "Hotel Example Austin",
        "url": "https://www.booking.com/hotel/us/example-austin.html",
        "star_rating": 4,
        "review_score": 8.5,
        "review_count": 2122,
        "price": 405.76,
        "price_per_night": 202.88,
        "currency": "USD",
        "free_cancellation": true
      }
    ]
  },
  "credits_used": 1,
  "credits_remaining": 999
}

Guardrails

  • Every call is 1 credit, including one that comes back empty.
  • Never send checkin without checkout. If the user gives one date, ask for the other or pick an explicit range and say which one you used.
  • If you did not send dates, read checkin / checkout / nights off the response and tell the user which stay the prices refer to. Never present a defaulted range as the dates they asked for.
  • Always pass currency. A price with no stated currency is not a usable answer.
  • min_price / max_price are per night, while a property row also carries the stay total in price. Say which figure you are quoting.
  • min_review_score accepts only 6, 7, 8 or 9. Round the user's threshold to one of those and tell them, rather than sending a value Booking will drop.
  • Prices and availability are live and move. Timestamp any quote and always include the property url so the user can verify and book.
  • Never fabricate property names, prices, review scores or review text. Only return what the API returned.

Failure handling

  • 400 means an invalid or missing parameter - no destination and no dest_id, dest_type without dest_id, an unpaired or out-of-order date, or min_price above max_price. Fix and retry.
  • 401 means the API key is invalid or missing. Check SCAVIO_API_KEY.
  • 404 on /hotel or /reviews usually means a bare slug was resolved against the wrong country_code. It is a real, billed 404 - do not brute-force country codes. Run a search and chain the url it returns instead.
  • 429 means rate or usage limit exceeded. Wait before retrying. See rate limits.
  • 502 / 503 mean upstream is temporarily unavailable - wait a few seconds and retry, up to a few times.
  • A search that returns no properties is usually a filter problem: widen max_price, drop min_review_score, or loosen stars.
  • If SCAVIO_API_KEY is not set, prompt the user to export it before continuing.

SDKs

pip install scavio==0.15.0
from scavio import ScavioClient

client = ScavioClient()  # reads SCAVIO_API_KEY

found = client.booking.search(destination="Austin", checkin="2026-09-08",
                              checkout="2026-09-10", adults=2, currency="USD")
url = found["data"]["properties"][0]["url"]
hotel = client.booking.hotel(url, checkin="2026-09-08", checkout="2026-09-10", currency="USD")
reviews = client.booking.reviews(url, checkin="2026-09-08", checkout="2026-09-10")
npm install scavio@0.15.0
import { Scavio } from "scavio";

const client = new Scavio(); // reads SCAVIO_API_KEY
const found = await client.booking.search({
  destination: "Austin", checkin: "2026-09-08", checkout: "2026-09-10", currency: "USD",
});
const hotel = await client.booking.hotel({ hotel: found.data.properties[0].url, currency: "USD" });