> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unifystays.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Hotels

> Search the unified hotel catalogue by destination, stay dates, room occupancy, filters, and pricing mode.

Hotel search is the shopping entry point for your enabled suppliers. Start with
a destination returned by
[Destination Autocomplete](/api-reference/destination-autocomplete) and use the
guest nationality `iso_code` returned by
[Nationalities](/api-reference/nationalities).

## Request Example

<RequestExample>
  ```bash theme={null}
  curl "$UNIFYSTAYS_BASE_URL/hotels/search" \
    -X POST \
    -H "content-type: application/json" \
    -H "x-api-key: $UNIFYSTAYS_API_KEY" \
    -H "language: en" \
    -d '{
      "destination": {
        "type": "city",
        "id": 101
      },
      "check_in": "2026-09-12",
      "check_out": "2026-09-15",
      "nationality": "IN",
      "rooms": [
        {
          "adults": 2,
          "child_ages": []
        }
      ],
      "star_ratings": [4, 5],
      "limit": 20,
      "pricing_mode": "instant",
      "sort": "recommended"
    }'
  ```
</RequestExample>

## Destination and Guest Inputs

| Input                                   | Source                   | Integration rule                                                                  |
| --------------------------------------- | ------------------------ | --------------------------------------------------------------------------------- |
| `destination.type` and `destination.id` | Destination autocomplete | Keep the selected type and send its matching city, hotel, or place ID.            |
| `nationality`                           | Nationalities            | Send the selected ISO alpha-2 `iso_code`.                                         |
| `rooms`                                 | Your guest form          | Send each room's adults and child ages; keep the same occupancy for room options. |
| Stay dates                              | Your guest form          | Send dates in `YYYY-MM-DD` format.                                                |

## Pricing Modes

| Mode      | Behavior                                                                                      | Recommended use                                 |
| --------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `instant` | Returns cached or estimated prices quickly, then refreshes supplier prices in the background. | Customer-facing result pages.                   |
| `live`    | Waits up to roughly 15 seconds for supplier refresh in the search response.                   | Low-volume or machine-to-machine rate shopping. |

When using `instant`, retain `data.search_id` and poll
[Get Search Price Updates](/api-reference/search-price-updates) every two
seconds while results are visible.

## Pagination and Rendering

* Use `data.next_cursor` as `cursor` in the next request. Keep the original
  search inputs when paging.
* Use the requested `sort` consistently across cursor pages.
* Merge live updates by `hotel_id` and re-sort when price changes arrive.
* Render `similar_hotels` as a separate nearby-properties section rather than
  mixing it into the main result list.
* Use `fields` only when a smaller payload is intentional; `hotel_id` remains
  available for merging and selection.

<Info>
  Search prices are shopping data, not a booking confirmation. Request fresh
  room options for the chosen hotel and prebook immediately before booking.
</Info>

The OpenAPI section below documents every search filter, occupancy constraint,
sort option, response field, and error response.


## OpenAPI

````yaml reference/openapi.json POST /hotels/search
openapi: 3.0.0
info:
  title: Unifystays API
  description: >-
    One unified hotel API across suppliers. Integrate once, then enable and
    manage suppliers from the Unifystays portal.
  version: '1.0'
  contact: {}
servers:
  - url: https://api-sandbox.unifystays.com
    description: Sandbox
  - url: https://api.unifystays.com
    description: Production
security:
  - x-api-key: []
tags: []
paths:
  /hotels/search:
    post:
      tags:
        - Hotels
      summary: Search hotels (cursor-based, cache-first pricing)
      description: >-
        Fetches hotels with provider mappings and returns cursor-based results
        with price sort support. pricing_mode='instant' (default):
        cached/estimated prices immediately — poll GET
        /hotels/search/:searchId/prices every 2s for live supplier prices.
        pricing_mode='live': this call waits (up to ~15s) for the supplier
        refresh and returns live prices in one round-trip.
      operationId: HotelSearchController_searchHotels
      parameters:
        - name: language
          description: Enter language code(ex. en)
          in: header
          schema: {}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelSearchRequestDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotelSearchResponseDto'
        '400':
          description: Bad request
        '404':
          description: Entity not found
components:
  schemas:
    HotelSearchRequestDto:
      type: object
      properties:
        destination:
          description: >-
            Selected destination from the autocomplete widget. Supply the `type`
            and `id` exactly as returned by `GET /destinations/autocomplete`.
          allOf:
            - $ref: '#/components/schemas/DestinationDto'
        check_in:
          type: string
          description: Check-in date in YYYY-MM-DD format. Must be today or a future date.
          example: '2026-07-01'
        check_out:
          type: string
          description: Check-out date in YYYY-MM-DD format. Must be after check_in.
          example: '2026-07-04'
        star_ratings:
          description: Filter results by star ratings. Pass one or more values from 1–5.
          example:
            - 4
            - 5
          items:
            type: array
          type: array
        price_min_usd_cents:
          type: number
          description: >-
            Minimum TOTAL price filter in USD cents (across all nights/rooms).
            Server converts to nightly unit range using computed stay
            multiplier.
          example: 5000
          minimum: 0
        price_max_usd_cents:
          type: number
          description: Maximum TOTAL price filter in USD cents.
          example: 500000
          minimum: 1
        property_types:
          description: >-
            Filter by property type. Values come from GET /hotels/filters →
            property_types.
          example:
            - Hotel
            - Resort
          items:
            type: array
          type: array
        chain_ids:
          description: >-
            Filter by hotel chain IDs. Values come from GET /hotels/filters →
            chains.
          example:
            - 42
            - 99
          items:
            type: array
          type: array
        facility_ids:
          description: >-
            Filter by facility IDs (matches hotels.facilities[].facility_id).
            Multiple ids are ANDed — hotel must have all selected facilities.
            Values come from GET /hotels/filters → facilities.
          example:
            - 107
            - 25
          items:
            type: array
          type: array
        hotel_name:
          type: string
          description: Free-text hotel name filter. Server runs ILIKE "%name%".
          example: marriott
        hotel_ids:
          description: >-
            Filter by specific hotel IDs. Useful when user wants to narrow the
            result set to one or more particular hotels (e.g. after picking from
            autocomplete). Matches hotels.hotel_id.
          example:
            - 1892345
            - 2031122
          items:
            type: array
          type: array
        rooms:
          description: >-
            Room configurations. Minimum 1 room, maximum 5 rooms. Each room
            supports up to 5 total occupants (adults + children).
          minItems: 1
          maxItems: 5
          type: array
          items:
            $ref: '#/components/schemas/RoomConfigDto'
        nationality:
          type: string
          description: >-
            Nationality of the guest in ISO alpha-2 format (e.g. IN for Indian,
            US for United States).
          example: IN
          default: IN
        limit:
          type: number
          description: Requested hotels per page. If omitted, default page size is used.
          example: 20
          default: 20
          minimum: 1
          maximum: 100
        cursor:
          type: string
          description: >-
            Cursor token for next-page fetch in format "sortKey_hotelId". Pass
            the `next_cursor` returned in previous response.
          example: '1037.5_1892345'
        price_sort:
          type: string
          description: >-
            Price sort direction for listing page. Uses precomputed
            `sort_price_usd_cents` for stable cursor pagination. If omitted, API
            uses recommended ranking (tier/cache/reliability first).
          enum:
            - low_to_high
            - high_to_low
          default: recommended
          example: low_to_high
        pricing_mode:
          type: string
          description: >-
            'instant' (default): returns cached/estimated prices immediately;
            poll GET /hotels/search/:searchId/prices for live supplier prices.
            'live': the request waits (up to ~15s) for the live supplier refresh
            and returns fresh prices in this single call — one-call integration
            for machine-to-machine rate shopping.
          enum:
            - instant
            - live
          default: instant
          example: instant
        sort:
          type: string
          description: >-
            Sort order. Supersedes price_sort when both are sent. recommended
            (default) = neutral relevance ranking; price_low_to_high /
            price_high_to_low = by total price; stars = star rating high→low;
            distance_from_center = closest to the city centre first; value =
            best value_pct deals first.
          enum:
            - recommended
            - price_low_to_high
            - price_high_to_low
            - stars
            - distance_from_center
            - value
          default: recommended
          example: distance_from_center
        fields:
          description: >-
            Sparse fieldset: return only these hotel-item fields (hotel_id is
            always included). Unknown names are ignored. Trims payloads for
            mobile / high-volume callers. Example:
            ["hotel_name","price","stars"].
          example:
            - hotel_name
            - price
            - stars
          type: array
          items:
            type: string
      required:
        - destination
        - check_in
        - check_out
        - rooms
    HotelSearchResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: Hotels fetched successfully
        data:
          $ref: '#/components/schemas/HotelSearchDataDto'
      required:
        - success
        - message
        - data
    DestinationDto:
      type: object
      properties:
        type:
          type: string
          description: >-
            Type of the selected destination. Use "city" when the user picks a
            city from autocomplete, "hotel" when the user picks a specific
            hotel, "place" when the user picks a geographic place
            (region/island/locality/neighborhood, e.g. "Bali") — returns hotels
            of the whole subtree.
          enum:
            - city
            - hotel
            - place
          example: city
        id:
          type: number
          description: >-
            The ID of the selected destination. When type = "city": pass the
            city_id returned by autocomplete. When type = "hotel": pass the
            hotel_id returned by autocomplete. The search service resolves the
            city automatically for hotel destinations.
          example: 101
      required:
        - type
        - id
    RoomConfigDto:
      type: object
      properties:
        adults:
          type: number
          description: Number of adults in this room (min 1, max 5)
          example: 2
          minimum: 1
          maximum: 5
        child_ages:
          description: >-
            Age of each child in this room (0–17). Total occupants (adults +
            children) must not exceed 5.
          example:
            - 5
            - 8
          type: array
          items:
            type: number
      required:
        - adults
    HotelSearchDataDto:
      type: object
      properties:
        search_info:
          $ref: '#/components/schemas/HotelSearchInfoDto'
        total_results:
          type: number
          example: 42
          description: >-
            Total eligible hotels in DB for this destination (with at least one
            provider mapping)
        requested_results:
          type: number
          example: 20
          description: Target hotels per cursor page.
        returned_results:
          type: number
          example: 20
          description: Actual number of hotels returned in this page.
        next_cursor:
          type: object
          example: '1012.4_1283771'
          description: >-
            Pass this as request.cursor (`sortKey_hotelId`) to fetch next page.
            Null means end reached.
        hotels:
          type: array
          items:
            $ref: '#/components/schemas/HotelSearchItemDto'
        search_id:
          type: string
          example: srch_a1b2c3d4e5f6g7h8
          description: >-
            Unique search session ID. Poll GET /hotels/search/:searchId/prices
            for fresh price updates.
        refresh_status:
          type: string
          example: PENDING
          description: >-
            PENDING = background refresh in flight, poll for updates. NA = all
            prices already fresh.
          enum:
            - PENDING
            - NA
        similar_hotels:
          description: >-
            Similar/nearby properties. Present for single-hotel searches and
            when a city search returns 2 or fewer hotels: same city, stars ±1,
            comparable price, ordered by distance. Render as a separate "similar
            properties" section — never mixed into the main list.
          type: array
          items:
            $ref: '#/components/schemas/SimilarHotelItemDto'
      required:
        - search_info
        - total_results
        - requested_results
        - returned_results
        - hotels
        - search_id
        - refresh_status
    HotelSearchInfoDto:
      type: object
      properties:
        place_id:
          type: number
          example: 2930267
          description: Searched place id — only present for place-destination searches.
        place:
          type: string
          example: Bali
          description: Searched place name — only present for place-destination searches.
        place_type:
          type: string
          example: region
          description: Searched place level — only present for place-destination searches.
        city_id:
          type: number
          example: 1
          description: >-
            For city searches: the searched city. For place searches: the
            context city (the city with the most hotels inside the place).
        city:
          type: string
          example: Mumbai
        country_code:
          type: string
          example: IN
        check_in:
          type: string
          example: '2026-07-01'
        check_out:
          type: string
          example: '2026-07-04'
        nights:
          type: number
          example: 3
        total_rooms:
          type: number
          example: 2
        total_guests:
          type: number
          example: 5
        price_sort:
          type: string
          example: recommended
          description: 'Applied sort mode: recommended, low_to_high, or high_to_low.'
      required:
        - city_id
        - city
        - country_code
        - check_in
        - check_out
        - nights
        - total_rooms
        - total_guests
        - price_sort
    HotelSearchItemDto:
      type: object
      properties:
        hotel_id:
          type: string
          example: '123456'
        hotel_name:
          type: string
          example: The Taj Mahal Palace
        stars:
          type: object
          example: 5
        address:
          type: object
          example: Apollo Bunder, Colaba
        city:
          type: string
          example: Mumbai
        country:
          type: string
          example: India
        latitude:
          type: object
          example: 18.9217
        longitude:
          type: object
          example: 72.8332
        main_image_url:
          type: object
          example: https://cdn.example.com/hotels/taj.jpg
        chain:
          type: object
          example: Marriott
          description: Hotel chain/brand name. Null for independents.
        facilities:
          example:
            - Free WiFi
            - Swimming pool
            - Breakfast
          description: >-
            Top facility highlights for the card (max 5). Full list in the
            content endpoint.
          type: array
          items:
            type: string
        distance_from_center_km:
          type: object
          example: 2.1
          description: >-
            Distance from the city centre in km (centre = median of hotel
            coordinates). Null when unavailable.
        value_pct:
          type: object
          example: 18
          description: >-
            Value badge: percent below the median price of similar hotels (same
            city + star). Present only when the hotel is at least 10% cheaper;
            render as e.g. "18% below similar hotels".
        typical_price_usd_cents:
          type: object
          example: 168000
          description: >-
            This hotel's TYPICAL total for the same stay (USD cents), derived
            from its learned price history adjusted for season/weekday/lead
            time. Only present together with vs_typical_pct.
        vs_typical_pct:
          type: object
          example: 22
          description: >-
            How the shown price compares to this hotel's typical price for these
            dates: positive = above usual ("22% above usual"), negative = below
            usual ("15% below usual — good dates"). Present only when the
            deviation is >=10% and the hotel has enough price history.
            Time-comparison — distinct from value_pct (which compares against
            OTHER similar hotels).
        availability_band:
          type: number
          example: 0
          description: >-
            0 = available; 1 = sold out for the searched dates; 2 = chronically
            unavailable from suppliers. Bands 1-2 are demoted server-side;
            clients may badge or grey out.
        price:
          $ref: '#/components/schemas/HotelPriceDto'
      required:
        - hotel_id
        - hotel_name
        - city
        - country
        - facilities
        - availability_band
        - price
    SimilarHotelItemDto:
      type: object
      properties:
        hotel_id:
          type: string
          example: '123456'
        hotel_name:
          type: string
          example: The Taj Mahal Palace
        stars:
          type: object
          example: 5
        address:
          type: object
          example: Apollo Bunder, Colaba
        city:
          type: string
          example: Mumbai
        country:
          type: string
          example: India
        latitude:
          type: object
          example: 18.9217
        longitude:
          type: object
          example: 72.8332
        main_image_url:
          type: object
          example: https://cdn.example.com/hotels/taj.jpg
        chain:
          type: object
          example: Marriott
          description: Hotel chain/brand name. Null for independents.
        facilities:
          example:
            - Free WiFi
            - Swimming pool
            - Breakfast
          description: >-
            Top facility highlights for the card (max 5). Full list in the
            content endpoint.
          type: array
          items:
            type: string
        distance_from_center_km:
          type: object
          example: 2.1
          description: >-
            Distance from the city centre in km (centre = median of hotel
            coordinates). Null when unavailable.
        value_pct:
          type: object
          example: 18
          description: >-
            Value badge: percent below the median price of similar hotels (same
            city + star). Present only when the hotel is at least 10% cheaper;
            render as e.g. "18% below similar hotels".
        typical_price_usd_cents:
          type: object
          example: 168000
          description: >-
            This hotel's TYPICAL total for the same stay (USD cents), derived
            from its learned price history adjusted for season/weekday/lead
            time. Only present together with vs_typical_pct.
        vs_typical_pct:
          type: object
          example: 22
          description: >-
            How the shown price compares to this hotel's typical price for these
            dates: positive = above usual ("22% above usual"), negative = below
            usual ("15% below usual — good dates"). Present only when the
            deviation is >=10% and the hotel has enough price history.
            Time-comparison — distinct from value_pct (which compares against
            OTHER similar hotels).
        availability_band:
          type: number
          example: 0
          description: >-
            0 = available; 1 = sold out for the searched dates; 2 = chronically
            unavailable from suppliers. Bands 1-2 are demoted server-side;
            clients may badge or grey out.
        price:
          $ref: '#/components/schemas/HotelPriceDto'
        distance_km:
          type: object
          example: 1.2
          description: >-
            Distance from the searched hotel in km. Null when either side lacks
            coordinates.
      required:
        - hotel_id
        - hotel_name
        - city
        - country
        - facilities
        - availability_band
        - price
    HotelPriceDto:
      type: object
      properties:
        amount:
          type: number
          example: 275000
          description: Total price for the whole stay, in USD cents.
        currency:
          type: string
          example: USD
        rate_type:
          type: string
          example: live
          enum:
            - live
            - estimated
          description: >-
            'live' = real supplier rate. 'estimated' = model estimate shown for
            speed; call the rooms endpoint (or search with pricing_mode=live)
            for a bookable rate.
        is_refundable:
          type: object
          example: true
          description: >-
            Whether the cheapest rate is refundable. Only known for
            rate_type='live' (supplier-provided); null for estimated prices.
        free_cancellation_until:
          type: object
          example: '2026-08-25T23:59:59.000Z'
          description: >-
            Free-cancellation deadline (ISO) for the cheapest rate. Render as
            "Free cancellation until Aug 25". Null when unknown or
            non-refundable.
      required:
        - amount
        - currency
        - rate_type
  securitySchemes:
    x-api-key:
      type: apiKey
      in: header
      name: x-api-key
      description: Environment-specific API key created in the Unifystays portal

````