openapi: 3.0.0
info:
  title: Booking.com API
  description: |
    The Booking.com API returns real-time property search results for a destination and stay. Each result includes the property title, address parts, star rating, guest review score, price and per-night rate, bed configuration, availability, and boolean flags such as free cancellation. The response also exposes grouped, response-derived filters, pagination, and total-result metadata.

    **Cross-linking**: Obtain `dest_id` and `dest_type` from the Booking.com Autocomplete API for precise destination targeting. Each result's `link` can be passed as the `url` parameter to the Booking.com Property API to fetch full property details.
  version: 1.0.0
servers:
  - url: https://www.searchapi.io/api/v1
paths:
  /search:
    get:
      summary: Booking.com Search
      security:
        - ApiKeyAuth: []
        - ApiKeyQuery: []
      parameters:
        - name: engine
          in: query
          required: true
          description: Search engine to use
          schema:
            type: string
            enum: ["booking"]
        - name: q
          in: query
          required: false
          description: >-
            The destination to search for. Accepts a city, region, district, landmark, or
            property name. Required unless both dest_id and dest_type are supplied, which
            identify the destination on their own.
          schema:
            type: string
        - name: dest_id
          in: query
          required: false
          description: >-
            Booking destination id from the Booking.com Autocomplete API. Identifies a
            destination only as a pair with dest_type, so either both are sent or neither
            is; one on its own is rejected with a 400.
          schema:
            type: string
            pattern: '^-?\d+$'
        - name: dest_type
          in: query
          required: false
          description: >-
            The type of the dest_id destination, returned alongside it by the Autocomplete
            API. Must be sent together with dest_id; one without the other is a 400.
          schema:
            type: string
            enum: ["city", "region", "country", "district", "hotel", "airport", "landmark"]
        - name: check_in_date
          in: query
          required: false
          description: >-
            The check-in date, format YYYY-MM-DD. Rejected with a 400 unless it is sent
            together with check_out_date, is a real calendar date, and is not already past
            in Etc/GMT+12, the last zone on earth to roll a date over. Prices are quoted for
            a specific stay, so price, extracted_price, nightly_price and
            extracted_nightly_price are returned only when a date range (or the
            flexible-date parameters) is supplied. A dateless search returns property
            metadata without pricing.
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
        - name: check_out_date
          in: query
          required: false
          description: >-
            The check-out date, format YYYY-MM-DD. Rejected with a 400 unless it is sent
            together with check_in_date, is a real calendar date that is not already past in
            Etc/GMT+12, falls strictly later than check_in_date, and leaves a stay of no
            more than 90 nights.
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
        - name: flex_window
          in: query
          required: false
          description: Widens the stay by the given number of days around the check-in and check-out dates.
          schema:
            type: string
            enum: ["1", "2", "3", "7"]
        - name: flex_months
          in: query
          required: false
          description: >-
            Search whole months instead of fixed dates. A comma-separated list of up to 3
            months in YYYY-MM format. Must be used with flex_stay_length; cannot be combined
            with check_in_date, check_out_date or flex_window.
          schema:
            type: string
            pattern: '^\d{4}-(0[1-9]|1[0-2])(,\d{4}-(0[1-9]|1[0-2])){0,2}$'
          example: '2026-09,2026-10,2026-11'
        - name: flex_stay_length
          in: query
          required: false
          description: >-
            How long the stay should be: weekend, week, month, or a number of nights
            between 1 and 30. Required when flex_months is set.
          schema:
            type: string
            pattern: '^(weekend|week|month|[1-9]|[12]\d|30)$'
          example: weekend
        - name: flex_start_day
          in: query
          required: false
          description: >-
            The weekday a flexible stay starts on. Booking pins flexible searches to a single
            start weekday; defaults to friday for weekend and monday otherwise.
          schema:
            type: string
            enum: ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
        - name: adults
          in: query
          required: false
          description: The number of adult guests.
          schema:
            type: integer
            minimum: 1
            maximum: 30
            default: 2
        - name: children_ages
          in: query
          required: false
          description: >-
            A comma-separated list of the children's ages, each between 0 and 17. The number
            of values sets the number of children; an age outside that range is a 400.
          schema:
            type: string
        - name: rooms
          in: query
          required: false
          description: The number of rooms to search for.
          schema:
            type: integer
            minimum: 1
            maximum: 30
            default: 1
        - name: sort_by
          in: query
          required: false
          description: >-
            The ordering of the property results. Unset by default: with no sort_by, no
            ordering parameter is sent and none is echoed back in search_parameters, and
            Booking applies its own ordering, which is by popularity.
          schema:
            type: string
            enum: ["popularity", "price_low_to_high", "review_score", "stars_high_to_low", "stars_low_to_high", "distance"]
        - name: filters
          in: query
          required: false
          description: A comma-separated list of facet tokens from the response's filters block (e.g. class=5), used to refine the results.
          schema:
            type: string
        - name: currency
          in: query
          required: false
          description: >-
            The ISO currency code the prices are returned in. When omitted, Booking
            prices the results in its own default for the request, which is not
            guaranteed to be stable between calls.
          schema:
            type: string
            enum: ["AED", "ARS", "AUD", "AZN", "BHD", "BRL", "BGN", "CAD", "XOF", "CLP", "CNY", "COP", "CZK", "DKK", "EGP", "EUR", "FJD", "GEL", "HKD", "HUF", "INR", "IDR", "ILS", "JPY", "JOD", "KZT", "KRW", "KWD", "KGS", "LAK", "MYR", "MXN", "MDL", "NAD", "TWD", "NZD", "NOK", "OMR", "PLN", "GBP", "QAR", "RON", "RUB", "SAR", "RSD", "SGD", "ZAR", "SEK", "CHF", "THB", "TRY", "UAH", "USD", "UZS", "VND"]
        - name: language
          in: query
          required: false
          description: >-
            The language of the returned search content: property names, filter labels,
            distances and review wording. Defaults to en-us, Booking's own default English,
            rather than being left to Booking, so the same request returns the same language
            every time. en is accepted as an alias for en-us.
          schema:
            type: string
            enum: ["en-gb", "en-us", "de", "nl", "fr", "es", "es-ar", "ca", "it", "pt-pt", "pt-br", "no", "fi", "sv", "da", "cs", "hu", "ro", "ja", "zh-cn", "zh-tw", "pl", "el", "ru", "tr", "bg", "ar", "ko", "he", "lv", "uk", "id", "ms", "th", "et", "hr", "sk", "sr", "sl", "vi", "tl", "is", "lt", "en"]
            default: "en-us"
        - name: page
          in: query
          required: false
          description: >-
            The results page to retrieve. Booking pages in blocks of 25, though a page may
            render a few more or fewer; follow
            pagination.next_page to walk the result set. A page past the last one returns
            an empty properties array alongside search_information.total_results. Not
            supported together with flex_months and flex_stay_length.
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: api_key
          in: query
          required: false
          description: Pass API key as query parameter
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Validation Error. There is an issue with query parameters, such as missing required parameters or invalid values.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication Error. The API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate Limit Exceeded. The number of allowed requests has been exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Server Error. Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Timeout, or Booking answered but returned nothing usable (an unknown property,
            a delisted one redirected to a search page, or a page that never carried
            results). The body is a bare {"error": ...} rather than a search response, and
            the search is not billed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Use Bearer authentication. Format: "Bearer YOUR_API_KEY"'
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: Pass API key as query parameter
  schemas:
    SearchResponse:
      type: object
      properties:
        search_metadata:
          $ref: '#/components/schemas/SearchMetadata'
        search_parameters:
          $ref: '#/components/schemas/SearchParameters'
        search_information:
          $ref: '#/components/schemas/SearchInformation'
        properties:
          type: array
          items:
            $ref: '#/components/schemas/Property'
        filters:
          type: array
          items:
            $ref: '#/components/schemas/FilterGroup'
        pagination:
          $ref: '#/components/schemas/Pagination'
    SearchInformation:
      type: object
      properties:
        applied_filters:
          type: array
          description: >-
            The filter tokens Booking actually applied. An unrecognised token is dropped
            silently and answered with a full page of unfiltered results, so comparing this
            against what was sent is the only way to detect it.
          items:
            type: string
        destination:
          type: object
          description: The destination Booking resolved the query to.
          properties:
            name:
              type: string
            country_code:
              type: string
            dest_id:
              type: string
              description: >-
                Same id space as the booking_autocomplete engine's dest_id. Returned with
                dest_type, so the pair can be sent straight back as the next request's
                destination.
            dest_type:
              type: string
              description: The kind of place dest_id names, in the same vocabulary as the dest_type parameter.
        total_results:
          type: integer
          description: The total number of properties matching the search.
        flexible_dates:
          type: object
          description: >-
            The flexible date range Booking actually applied, echoed back in the same
            vocabulary as the request. Present only when flex_months / flex_stay_length
            were used and accepted; absent for searches with exact dates.
          properties:
            months:
              type: array
              description: The months searched, in YYYY-MM format.
              items:
                type: string
            nights:
              type: integer
              description: The length of the stay in nights.
            start_day:
              type: string
              description: The weekday the stay starts on.
    Property:
      type: object
      properties:
        position:
          type: integer
          description: The position of the property in the results.
        title:
          type: string
          description: The property name.
        link:
          type: string
          description: The clean property page URL, usable as the url parameter of the Booking.com Property API.
        neighborhood:
          type: string
          description: >-
            The area label Booking prints on the card, e.g. "Babin Kuk". The city it repeats
            is dropped, since `city` ships on its own.
        distance:
          type: string
          description: The distance from the searched location.
        hotel_class:
          type: number
          description: >-
            The property's rating out of 5. Booking rates most properties in official
            stars, but some carry a self-assigned rating shown as squares or dots; check
            is_self_rated to tell them apart.
        is_self_rated:
          type: boolean
          description: >-
            Present and true when hotel_class is the property's own claim rather than an
            official star rating. Omitted on officially rated properties.
        property_id:
          type: string
          description: Booking's own numeric id for the property, stable across searches and locales.
        city_id:
          type: string
          description: >-
            The destination id of the city the property is in. Same id space as the
            booking_autocomplete engine's dest_id, so a property can be pivoted back to a city search.
        gps_coordinates:
          type: object
          description: The property's exact coordinates.
          properties:
            latitude:
              type: number
            longitude:
              type: number
        street:
          type: string
          description: The street line of the property address.
        city:
          type: string
        country_code:
          type: string
          description: Two-letter country code.
        currency:
          type: string
          description: >-
            The ISO code the prices on this result are quoted in. Returned whether or not the
            request set the currency parameter.
        original_price:
          type: string
          description: The stay price before the discount that produced `price`. Present only on discounted results.
        extracted_original_price:
          type: number
          description: The numeric pre-discount price.
        taxes_and_charges:
          type: string
          description: Taxes and fees Booking excludes from the headline price.
        extracted_taxes_and_charges:
          type: number
          description: The numeric taxes and charges.
        thumbnail_hd:
          type: string
          description: The same photo as `thumbnail` at 600px rather than 240px.
        is_sponsored:
          type: boolean
          description: >-
            Present and true when the result is a paid native-ad placement sitting in the organic
            list. Omitted otherwise.
        is_featured:
          type: boolean
          description: Present and true when Booking applied a paid visibility boost. A different product to is_sponsored.
        is_new:
          type: boolean
          description: Present and true when Booking marks the property as newly listed.
        is_autoextended:
          type: boolean
          description: >-
            Present and true when Booking widened the requested stay to fill the page, so the
            card is not priced for the dates that were asked for. Omitted otherwise.
        is_sold_out:
          type: boolean
          description: >-
            Present and true when the property has no availability left for the requested
            stay. Such a card is still ranked and still carries a title and a link, but no
            price; this flag is what tells the two cases apart. Omitted otherwise.
        check_in_date:
          type: string
          description: >-
            The check-in date this result is priced for. Returned only on a flexible search
            (flex_months + flex_stay_length), where Booking picks a different range per property.
        check_out_date:
          type: string
          description: The check-out date this result is priced for. Flexible searches only.
        nights:
          type: integer
          description: The length of the stay these prices cover. Flexible searches only.
        bedrooms:
          type: integer
        bathrooms:
          type: integer
        beds:
          type: integer
        living_rooms:
          type: integer
        kitchens:
          type: integer
        meal_plan:
          type: string
          description: The meal plan included in the recommended unit, e.g. "Breakfast included".
        beach_distance:
          type: string
          description: Distance to the nearest beach, on coastal destinations.
        nearby_beaches:
          type: array
          description: Names of the beaches near the property.
          items:
            type: string
        is_sustainable:
          type: boolean
          description: Present and true when the property holds a recognised sustainability certification.
        sustainability_certifications:
          type: array
          description: The certification names behind is_sustainable.
          items:
            type: string
        external_rating:
          type: number
          description: >-
            A partner review score on the same 0-10 scale, for properties with no Booking-native
            reviews. Kept separate from rating so the two are never conflated.
        external_reviews:
          type: integer
          description: The number of partner reviews behind external_rating.
        extracted_distance:
          type: number
          description: >-
            The numeric part of `distance`. The label's wording and its decimal separator both
            change with language, so this is parsed locale-aware.
        distance_unit:
          type: string
          enum: ["km", "m", "mi", "ft", "yd"]
          description: >-
            The unit `extracted_distance` is expressed in, normalized so the value can be
            compared across languages. Booking writes the label in the market's own script
            ("0,6 км", "2.1 กม.", "离中心地区0.6千米", "0.1 miles"); every one of those is
            reported here as one of km, m, mi, ft or yd.
        rooms_left:
          type: integer
          description: The count stated in `availability`, e.g. 5 for "We have 5 left at this price".
        free_cancellation_until:
          type: string
          description: The deadline for free cancellation on the rate shown, as an ISO 8601 timestamp.
        has_no_prepayment:
          type: boolean
          description: Present and true when the rate shown requires no prepayment.
        area:
          type: string
          description: The unit's floor area with its unit, e.g. "269 ft²".
        extracted_area:
          type: number
          description: The numeric floor area.
        area_unit:
          type: string
          description: The unit `extracted_area` is expressed in, e.g. ft² or m².
        deal:
          type: string
          description: >-
            Booking's promotion chip, e.g. "Limited-time Deal". Server-rendered pages only:
            Booking's paginated payload carries no deal name, so this is absent from page 2 onward.
        deal_description:
          type: string
          description: The full explanation behind `deal`. Server-rendered pages only.
        rating:
          type: number
          description: The guest review score, on Booking's 0-10 scale.
        max_rating:
          type: integer
          description: The top of the rating scale. Always 10 on Booking.
        rating_word:
          type: string
          description: The qualitative review label (e.g. Superb).
        reviews:
          type: integer
          description: The number of guest reviews.
        price:
          type: string
          description: The headline total price for the stay. Returned only when the request supplies dates.
        extracted_price:
          type: number
          description: The numeric total price. Returned only when the request supplies dates.
        nightly_price:
          type: string
          description: >-
            The per-night price. Present whenever the card renders a per-night breakdown,
            which includes one-night stays where it equals price, so its presence is not a
            signal that the stay spans several nights. Read stay_summary for that.
        extracted_nightly_price:
          type: number
          description: The numeric per-night price. See nightly_price.
        stay_summary:
          type: string
          description: >-
            A summary of what the total price covers (e.g. "3 nights, 2 adults"). Server-rendered
            pages only: Booking's paginated payload has no counterpart for it, so this is absent
            from page 2 onward even on a dated search.
        top_review_category:
          type: object
          description: The property's standout guest review category.
          properties:
            name:
              type: string
            score:
              type: number
        room_type:
          type: string
          description: The recommended room type name.
        bed_configuration:
          type: string
          description: >-
            The bed setup of the recommended room. Server-rendered pages only: Booking's
            paginated payload has no counterpart for it, so this is absent from page 2 onward.
        availability:
          type: string
          description: A scarcity/urgency line (e.g. "We have 5 left at this price").
        is_guest_favorite:
          type: boolean
          description: >-
            Present and true when the property carries a guest-favorite badge. Omitted
            otherwise. The badge is drawn on the card and Booking's paginated payload has no
            counterpart for it, so this is absent from page 2 onward.
        is_preferred:
          type: boolean
          description: Present and true when the property is a Booking preferred partner. Omitted otherwise.
        has_free_cancellation:
          type: boolean
          description: Present and true when the recommended rate offers free cancellation. Omitted otherwise.
        thumbnail:
          type: string
          description: The property thumbnail image URL.
    FilterGroup:
      type: object
      properties:
        category:
          type: string
          description: >-
            The filter group's field key (e.g. class, fc, review_score). This is Booking's own
            token, preserved verbatim so it round trips; `label` is the human-readable name.
        label:
          type: string
          description: The group's display name in the requested language, e.g. "Property type".
        options:
          type: array
          items:
            type: object
            properties:
              value:
                type: string
                description: >-
                  The nflt token to pass back in the filters parameter (e.g. class=5). On
                  the price group this is the full-range token; substitute your own bounds
                  as price=CURRENCY-min-max-1.
              name:
                type: string
                description: The human-readable option label.
              count:
                type: integer
                description: The number of properties matching this option.
              is_selected:
                type: boolean
                description: Present and true when Booking currently has this option applied.
              min:
                type: number
                description: Price group only. The lowest selectable price per night.
              max:
                type: number
                description: Price group only. The highest selectable price per night.
              currency:
                type: string
                description: Price group only. The ISO code the bounds are expressed in.
    Pagination:
      type: object
      properties:
        current_page:
          type: integer
          description: The current results page.
        next_page:
          type: integer
          description: The next results page. Omitted when there are no more pages.
    SearchMetadata:
      type: object
      required: [id, status, created_at]
      properties:
        id:
          type: string
          description: "Unique identifier for the search request"
        status:
          type: string
          description: "Status of the search request"
        created_at:
          type: string
          format: date-time
          description: "Timestamp when the search was created"
        request_time_taken:
          type: number
          description: "Time taken to make the request in seconds"
        parsing_time_taken:
          type: number
          description: "Time taken to parse the results in seconds"
        total_time_taken:
          type: number
          description: "Total time taken for the search in seconds"
        request_url:
          type: string
          description: "Booking.com URL for this search"
        html_url:
          type: string
          description: "URL to view HTML results"
        json_url:
          type: string
          description: "URL to view JSON results"
    SearchParameters:
      type: object
      properties:
        engine:
          type: string
        q:
          type: string
        dest_id:
          type: string
        dest_type:
          type: string
        check_in_date:
          type: string
        check_out_date:
          type: string
        flex_window:
          type: string
        flex_months:
          type: string
        flex_stay_length:
          type: string
        flex_start_day:
          type: string
        adults:
          type: integer
        children_ages:
          type: string
        rooms:
          type: integer
        sort_by:
          type: string
        filters:
          type: string
        currency:
          type: string
        language:
          type: string
        page:
          type: integer
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Error message describing what went wrong
