Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Do not scrape Booking.com pages with Selenium, requests, or another bot unless Booking.com has given you prior, express written permission. Its current customer terms prohibit automated access, monitoring, copying, downloading, or reproduction for any purpose without that permission. For a production hotel-data product, apply for an approved Booking.com Demand or Connectivity integration, define exactly which fields you need, authenticate with issued credentials, cache narrowly, and implement deletion and privacy controls. This guide shows that workflow, a safe Python normalization pattern, the browser-automation limits, and a practical way to capture authorized pages without maintaining a browser stack.

What Booking.com’s terms allow—and prohibit

Booking.com’s current customer terms say: “Whether or not you have a commercial purpose, you’re not allowed to access, monitor, copy, scrape/crawl, download, reproduce, or otherwise use anything on our Platform using any robot, spider, scraper, other automated means, or automated assistants … for any purpose without the prior, express written permission of Booking.com.” Public visibility does not create an exception.

The terms also describe monitoring and blocking for systems that make an unreasonable number of searches, gather prices or other information automatically, place undue stress on the platform, or use automated assistants without express permission. Separate general terms restrict commercial scraping or copying and describe similar controls. A script that works today can therefore stop working, trigger blocks, or put your organization in breach even if it only reads pages visible in a normal browser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not evade a CAPTCHA, rotate proxies to defeat a block, reverse-engineer private endpoints, or copy page data while an API application is pending. Those techniques do not turn an unapproved collection into an authorized integration.

Pick an approved source before writing code

Booking.com Demand API

The Demand API is the documented route for access to Booking.com accommodation inventory and identifier mappings. Partner documentation describes hotel and availability responses that can include a hotel_url, and the commercial model generally sends the booker to Booking.com. Eligibility, contracts, credentials, allowed fields, rate limits, and redistribution rights must be confirmed during onboarding; public documentation does not promise that every applicant will be accepted or publish one universal fee schedule.

Booking.com Connectivity API

Connectivity integrations use credentialed machine accounts and onboarding through the Connectivity Portal. This is the relevant path when your system is connecting inventory or availability under a commercial agreement rather than copying consumer pages.

Data Portability

Data Portability is a different flow: it requires application registration, OAuth, and explicit authorization from the user whose data is being accessed. Do not treat a user-authorized portability connection as permission to collect general public hotel prices.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Licensed third-party feeds

A licensed feed can be appropriate when its contract grants the destinations, fields, refresh frequency, retention, and redistribution rights your product needs. Ask for written terms and compare them with an official integration instead of assuming that a feed provider’s access automatically covers your use.

Option Authentication and onboarding Questions to settle in writing
Demand API Partner registration, contract review, issued credentials Inventory coverage, availability fields, limits, booking-link rules, storage and redistribution
Connectivity API Machine account and Connectivity Portal onboarding Connected inventory scope, change feeds, operational support and deletion duties
Data Portability Application registration plus user OAuth consent Which user-authorized records are available and how long consent remains valid
Licensed feed Supplier account and commercial license Geography, freshness, identifiers, retention, onward sharing and support

Define the data contract first

Write a field-level specification that an approved provider can review. A price is not a permanent hotel attribute: it depends on dates, occupancy, room, rate plan, currency, taxes, cancellation terms, and availability at the observation time.

  • Search context: destination or property ID, check-in and check-out dates, adults, children and room count.
  • Property identity: stable property ID, name, address, coordinates if licensed, and the source URL or hotel_url where permitted.
  • Offer identity: room ID, rate-plan ID, meal plan, bed configuration, occupancy, refundable status and cancellation deadline.
  • Money: amount, currency, tax and fee treatment, display precision, and whether the amount is per night or total stay.
  • Freshness: request timestamp, response timestamp, source, locale, and timezone.
  • Quality: review score and count only if your agreement permits those fields, plus an explicit missing-value policy.

Keep raw provider responses unchanged in restricted storage and write a separate normalized table. That separation lets you audit a mapping when a provider changes a field without silently rewriting historical records.

Apply, authenticate, and query narrowly

  1. Submit the partner application. Describe your product, destinations, expected request volume, users, booking handoff, and every field you intend to retain or display.
  2. Read the contract before production. Confirm whether you may cache prices, expose them to another company, store historical observations, or forward users to Booking.com. Unauthorized forwarding is identified as a usage issue in the usage documentation.
  3. Store credentials outside source control. Use the machine-account credentials supplied for Connectivity, or the OAuth token lifecycle supplied for Data Portability. Never put secrets in browser JavaScript or logs.
  4. Request only what you need. Limit destinations, properties, dates, occupancy and fields; follow the documented rate limits and retry guidance in your agreement.
  5. Record provenance on every observation. Save endpoint name, retrieval time, geography, currency, occupancy, stay dates and permission scope beside the normalized record.

Use a queue to smooth bursts rather than issuing thousands of simultaneous searches. Cache according to the contract and show downstream users when a price was observed; do not present an old quote as live availability.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Normalize an authorized response in Python

The following script deliberately does not call a Booking.com page or an undocumented endpoint. It reads a response you obtained through your approved integration, preserves the raw file, and emits one CSV row per offer. Adjust the input paths to the schema in your contract.

import csv
import json
from datetime import datetime, timezone
from pathlib import Path

RAW = Path("authorized-response.json")
OUT = Path("hotel-offers.csv")

with RAW.open(encoding="utf-8") as f:
    payload = json.load(f)

observed_at = datetime.now(timezone.utc).isoformat()
rows = []
for hotel in payload.get("hotels", []):
    property_id = hotel.get("id")
    property_name = hotel.get("name")
    hotel_url = hotel.get("hotel_url")
    for room in hotel.get("rooms", []):
        for offer in room.get("offers", []):
            rows.append({
                "observed_at": observed_at,
                "property_id": property_id,
                "property_name": property_name,
                "hotel_url": hotel_url,
                "room_id": room.get("id"),
                "rate_plan_id": offer.get("rate_plan_id"),
                "check_in": offer.get("check_in"),
                "check_out": offer.get("check_out"),
                "occupancy": offer.get("occupancy"),
                "amount": offer.get("amount"),
                "currency": offer.get("currency"),
                "taxes_included": offer.get("taxes_included"),
                "cancellation": offer.get("cancellation"),
            })

fields = [
    "observed_at", "property_id", "property_name", "hotel_url", "room_id",
    "rate_plan_id", "check_in", "check_out", "occupancy", "amount",
    "currency", "taxes_included", "cancellation"
]
with OUT.open("w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fields)
    writer.writeheader()
    writer.writerows(rows)

print(f"Wrote {len(rows)} offers to {OUT}")

This is a normalization pattern, not a claim about a universal response schema. Map the provider’s documented field names, validate currency and date formats, and reject an offer when a required identifier is missing instead of inventing one.

Handle change, deletion, and sensitive data

Build lifecycle jobs from the beginning. Booking.com usage documentation describes change feeds and says data for closed properties must be removed from websites, apps and databases. A daily or event-driven deletion process should therefore mark a property closed, remove prohibited records from indexes and caches, and record the deletion event for audit.

Do not collect guest credentials. Booking flows that collect customer details and card information require PCI DSS compliance and an approved payment flow. If your product only sends a user to Booking.com, keep your system out of the card-data path and confirm that the contract permits the handoff.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Restrict raw-response access, encrypt credentials, redact tokens from logs, and set retention periods that match the agreement. Do not forward records to another company unless the permission explicitly allows it.

Why Selenium is usually the wrong implementation

Selenium or Playwright can render a page, but rendering does not solve the permission problem. For Booking.com, browser automation also creates brittle selectors, consent and localization branches, bot checks, timing races, and high resource use. It can return a page that looks complete while prices, taxes, occupancy, or room availability are still loading.

Use browser automation only for a site you own or a property for which you have explicit written permission. In that permitted setting, pin the browser version, wait for a documented readiness selector, capture network and console errors, limit concurrency, and test each locale and viewport you support. Never use those controls to bypass a Booking.com block or CAPTCHA.

Reliability, freshness, and cost controls

  • Freshness: store an observation timestamp and make the timestamp visible to consumers; availability can change between retrieval and booking.
  • Rate limits: schedule requests, apply bounded exponential backoff for transient provider errors, and stop retrying authentication or contract errors.
  • Idempotency: key a record by property, room, rate plan, dates, occupancy, currency and observation window so retries do not duplicate offers.
  • Schema drift: retain raw responses, validate required fields, and alert when a field disappears or changes type.
  • Cost: estimate calls from destinations × date windows × occupancy combinations, then compare that volume with the provider’s contracted limits and fees before launch.
  • Fallbacks: if the API is unavailable, show the last permitted observation with its age or fail clearly; do not silently switch to page scraping.

Troubleshooting common failures

“My script receives a CAPTCHA or 403”

Stop automated requests. This is a blocking signal, not an invitation to rotate IPs or change user agents. Check that you are using an approved API credential and contact the provider through the contracted support channel.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“The API application has no credentials yet”

Do not probe private endpoints while waiting. Finish registration and contract review, request the correct Demand or Connectivity product, and confirm whether your use case is eligible.

“Prices differ from the page”

Compare the exact stay dates, occupancy, currency, taxes, cancellation terms, room and rate-plan identifiers, locale, and observation times. A page view and an API response are not necessarily the same search context.

“A property disappeared”

Treat it as a lifecycle event until the provider confirms otherwise. Run the documented change or deletion process and remove closed-property data from active indexes, caches and downstream exports when required.

“A payment field is required”

Do not store card details in a general data pipeline. Use the approved booking flow and meet PCI DSS obligations, or redesign the product to hand the customer to Booking.com without handling payment data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“My normalized CSV has duplicate offers”

Check your idempotency key and preserve the provider’s stable property, room and rate-plan identifiers. Keep observation time separate from offer identity so a legitimate price change is a new observation, not an accidental duplicate.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture an authorized hotel page for QA, documentation, or a visual record—not to extract Booking.com data without permission—ScreenshotNeo provides a single screenshot request. It accepts the cookie or consent banner like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn each cleanup step off. Only clean shots are billed; bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with the result identified by X-Page-Verdict and X-Billed headers.

Use it only for a URL you are allowed to access. The API supports PNG, JPEG, WebP and PDF, full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or a custom viewport, retina scale, PDF paper size/margins/landscape/page ranges, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for a selector/delay/network idle, request and resource blocking, headers/cookies/user agents/Authorization, timezone and geolocation, transparent backgrounds, resizing, caller-selected cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can reduce migration effort.

See the ScreenshotNeo API documentation for request options. cURL:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-authorized-site.example/hotels -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://your-authorized-site.example/hotels"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://your-authorized-site.example/hotels' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots each month with no card; paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account.

FAQ

Is there one standard Booking.com API price?

No single public fee schedule applies to every integration. Eligibility, commercial terms, limits and any charges depend on the approved product and contract, so confirm them during onboarding.

Can an OAuth token from Data Portability be reused for hotel search?

No. Data Portability authorization is for the user-authorized portability flow. General accommodation search requires the appropriate approved Demand or Connectivity access.

Should I keep the original provider JSON?

Keep it when your contract and retention policy permit, with restricted access. It provides an audit trail when a normalized field mapping or provider schema changes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Is there one standard Booking.com API price?

No. Eligibility, limits and charges depend on the approved product and contract; confirm commercial terms during onboarding.

Can a Data Portability OAuth token be reused for hotel search?

No. Data Portability covers user-authorized portability data, while accommodation search requires approved Demand or Connectivity access.

Should the original provider response be retained?

Retain it only when your contract and retention policy allow it, with restricted access so mappings and schema changes can be audited.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.