GET
# Hotel Search API

Search for available hotels in any destination with flexible date and guest configurations.

## Point of sale and display settings

Pass `market=ES` for Spain (Spanish and EUR defaults) or `market=US` for the United States (English and USD). The optional `language` and `currency` parameters override these defaults. Market is an ISO 3166-1 two-letter country code; unknown codes and conflicting `market`/`country_market` values return 400.

Legacy `country_market` remains supported and keeps English/USD defaults. Omitting both retains US targeting and English/USD. For search by URL, explicit language/currency query parameters override values embedded in the URL; explicit URL values override market defaults.

Defaults: ES es/EUR, US en-us/USD, GB en-gb/GBP, DE de/EUR, FR fr/EUR, IT it/EUR, PT pt-pt/EUR, NL nl/EUR, IE en-gb/EUR, CA en-us/CAD, AU en-gb/AUD, JP ja/JPY. Other valid countries use en-us/USD unless overridden.

`data.effective_market` reports `requested_country`, nullable `targeted_country`, `language`, and `currency`. Targeting is best-effort: `country_verified` is false and `verified_country` is null because the response does not independently verify geography. A null target means country targeting was not applied. MCP returns the same object as `effective_market`.

```
{"requested_country":"ES","targeted_country":"ES","country_verified":false,"verified_country":null,"language":"es","currency":"EUR"}
```

For prices, `total_price_value` follows the displayed gross basis and is not guaranteed to include every charge. `taxes_and_charges_value` is the included portion (gross minus net); inspect `tax_breakdown[].included` for excluded taxes.

Compare the same stay, occupancy, room, rate conditions and currency. Market can change tax inclusion and displayed totals without changing the all-in price; it does not guarantee a discount or availability. In the verified Spain/US comparison, the same rate displayed US$455 including taxes in Spain and $341 excluding taxes in the US, with the same $455.46 all-in amount.

## Overview

#### Availability Search

Search for hotels with real-time availability and pricing information based on dates and guest requirements.

#### Need a Destination ID?

Don't know the dest\_id for your location? Use the [Destinations Lookup endpoint](/docs/endpoints/booking/destinations-lookup) to convert any location name (e.g., "Barcelona", "Paris") into a Booking.com destination ID.

The Hotel Search endpoint allows you to search for available hotels in any destination with specific check-in/check-out dates, number of guests, and rooms. Returns real-time availability and pricing data.

### Endpoint URL

GET https://api.stayapi.com/v1/booking/search 

## Query Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| dest\_id | string | Required | Destination ID from Booking.com (e.g., "-2167973" for Lisbon). Get it from Destinations Lookup |
| dest\_type | string | Optional | Destination type (default: "CITY") |
| checkin | string | Optional | Check-in date in YYYY-MM-DD format |
| checkout | string | Optional | Check-out date in YYYY-MM-DD format |
| adults | integer | Optional | Number of adults (default: 2) |
| rooms | integer | Optional | Number of rooms (default: 1) |
| children | integer | Optional | Number of children, 0–10 (default: 0). Supply one age per child. |
| children\_ages | string | Optional | Comma-separated integer ages 0–17. The count must equal children; omit or leave empty with zero children. Missing, malformed or mismatched ages return HTTP 400 Problem Details with error\_code INVALID\_OCCUPANCY. |
| rows\_per\_page | integer | Optional | Results per page (default: 25, max: 100) |
| offset | integer | Optional | Starting offset for pagination (default: 0). Booking.com serves results up to offset 1000 — `data.pagination.total_results` is the real match count, and `has_next_page` turns false at that limit. |
| language | string | Optional | Language override (market default, otherwise "en-us") |
| currency | string | Optional | Currency override (market default, otherwise "USD") |
| country\_market | string (ISO-3166) | Optional | Legacy two-letter country target (default: `US`), preserving English/USD defaults. It must match `market` if both are supplied. The echo is a request value, not verified geography. |

## Rate labels

`each data.hotels[].price object` includes `labels` (an array of readable strings), `genius_discount_pct` (a number or null), and `is_mobile_rate` (a boolean). Labels describe the quoted rate, for example `Mobile rate` or `Bonus savings`. Unlabelled rates return `[]`. A hotel without a quoted price retains `price: null`.

These are anonymous public quotes. A property Genius badge alone does not prove a Genius discount on this rate. A null percentage means no rate-specific percentage was observed; `is_mobile_rate: false` means no explicit mobile-rate marker was observed. Labels can vary by market and occupancy and do not guarantee eligibility for logged-in member prices. Existing discount fields remain available.

Request

```curl
curl -X GET "https://api.stayapi.com/v1/booking/search?dest_id=-2167973&checkin=2026-12-01&checkout=2026-12-04&adults=2&rooms=1&rows_per_page=2" \
  -H "x-api-key: YOUR_API_KEY"
```

Response

```json
{
  "success": true,
  "url": "https://www.booking.com/searchresults.html?dest_id=-2167973&dest_type=city&group_adults=2&no_rooms=1&group_children=0&offset=0&checkin=2026-12-01&checkout=2026-12-04&lang=en-us&sb=1&src_elem=sb&aid=304142",
  "hotel_id": null,
  "data": {
    "hotels": [
      {
        "hotel_id": "4045490",
        "name": "Maxime Boutique Hotel Avenida da Liberdade",
        "address": "58 Praça da Alegria",
        "city": "Lisboa",
        "display_location": "Lisboa",
        "distance": "0.4 miles",
        "latitude": 38.71833447459589,
        "longitude": -9.145319386577626,
        "star_rating": 3,
        "price": {
          "amount": 376.0343526281907,
          "currency": "USD",
          "display": "$376",
          "before_discount": "$470",
          "labels": [],
          "genius_discount_pct": null,
          "is_mobile_rate": false
        },
        "rating": {
          "score": 8.8,
          "review_count": 3617,
          "display": "Excellent"
        },
        "image_url": "https://cf.bstatic.com/xdata/images/hotel/square200/646162366.jpg?k=...&o=",
        "free_cancellation": true,
        "no_prepayment": false,
        "is_sold_out": false,
        "room_name": "Deluxe Twin Room"
      },
      {
        "hotel_id": "10131840",
        "name": "MASA Hotel & Spa Campo Grande Collection",
        "address": "Campo Grande 56",
        "city": "Lisboa",
        "display_location": "Lisboa",
        "distance": "2.6 miles",
        "latitude": 38.750851,
        "longitude": -9.148746,
        "star_rating": 4,
        "price": {
          "amount": 258.1471755326366,
          "currency": "USD",
          "display": "$258",
          "before_discount": "$323",
          "labels": [],
          "genius_discount_pct": null,
          "is_mobile_rate": false
        },
        "rating": {
          "score": 8.5,
          "review_count": 11888,
          "display": "Very Good"
        },
        "image_url": "https://cf.bstatic.com/xdata/images/hotel/square200/535564893.jpg?k=...&o=",
        "free_cancellation": true,
        "no_prepayment": false,
        "is_sold_out": false,
        "room_name": "Standard Double Room"
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 2,
      "total_results": 5036,
      "total_pages": 501,
      "has_next_page": true,
      "has_previous_page": false,
      "offset": 0
    },
    "hotels_found": 2,
    "search_url": "https://www.booking.com/searchresults.html?dest_id=-2167973&dest_type=city&group_adults=2&no_rooms=1&group_children=0&offset=0&checkin=2026-12-01&checkout=2026-12-04&lang=en-us&sb=1&src_elem=sb&aid=304142",
    "metadata": {
      "dest_id": -2167973,
      "dest_type": "CITY",
      "checkin": "2026-12-01",
      "checkout": "2026-12-04",
      "adults": 2,
      "children": 0,
      "rooms": 1,
      "children_ages": [],
      "highlighted_hotels": [],
      "rows_per_page": 2,
      "offset": 0,
      "travel_purpose": 2,
      "language": "en-us",
      "currency": "USD",
      "country_market": "US"
    }
  },
  "message": "Found 2 hotels",
  "retrieved_at": "2026-09-24T17:06:47.365477Z"
}
```

```json
{
  "errors": [
    {
      "type": "missing",
      "loc": [
        "query",
        "dest_id"
      ],
      "msg": "Field required",
      "input": null,
      "url": "https://errors.pydantic.dev/2.13/v/missing"
    }
  ],
  "error": "Validation Error",
  "status_code": 422,
  "type": "https://api.stayapi.com/errors/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "Request validation failed",
  "error_code": "VALIDATION_ERROR",
  "instance": "/v1/booking/search",
  "provider": "booking",
  "correlation_id": "1f74d994-53f6-43b7-aa75-359845d3c6f4"
}
```
