Skip to main content
POST
Hotel search is the shopping entry point for your enabled suppliers. Start with a destination returned by Destination Autocomplete and use the guest nationality iso_code returned by Nationalities.
Sandbox/staging has a deliberately limited place and hotel dataset. Search with a destination returned by the same environment’s autocomplete endpoint. An ID copied from production or another environment may return no hotels even when the request is otherwise valid.

Request Example

Destination and Guest Inputs

Pricing Modes

When using instant, retain data.search_id and poll Get Search Price Updates every two seconds while results are visible.

Search Price Currency

price.amount and each supplier_prices[].amount are integer cents in their accompanying currency. USD is the default. Accounts with a EUR hotel-list override receive EUR for these prices in POST /hotels/search, including live quotes and similar hotels. Conversion uses the stored active exchange rate; an unavailable rate returns HTTP 503 rather than an incorrectly labelled price. This override applies only to the hotel-list response. Price polling, room options, prebooking, and booking keep their existing currencies. Fields explicitly named in USD, including typical_price_usd_cents and USD price filters, remain USD cents. Always read each price’s currency when displaying or comparing it.

Tenant-Specific Availability

Search results are evaluated against the suppliers enabled for your OTA account. A hotel returned in the current search is not removed later when the background refresh reports no price; use no_price_hotel_ids from the price updates endpoint to decide how that hotel should appear in your UI. Future searches may omit hotels with recent or repeated no-price results for your account and current supplier set. An exact no-price result is remembered for 30 minutes. A hotel is treated as chronically unavailable after no-price results on three distinct check-in dates in 14 days. A later live supplier price resets that history. This history is isolated by OTA account, environment, and enabled supplier set, and supplier errors or timeouts do not count as no-price evidence.

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.
Search prices are shopping data, not a booking confirmation. Request fresh room options for the chosen hotel and prebook immediately before booking.
The OpenAPI section below documents every search filter, occupancy constraint, sort option, response field, and error response.

Authorizations

x-api-key
string
header
required

Environment-specific API key created in the Unifystays portal

Headers

X-Unifystays-Contract-Version
enum<string>
default:1

Hotel API contract version. Missing defaults to v1.

Available options:
1

Body

application/json
destination
object
required

Selected destination from the autocomplete widget. Supply the type and id exactly as returned by GET /destinations/autocomplete.

check_in
string
required

Check-in date in YYYY-MM-DD format. Must be today or a future date.

Example:

"2026-07-01"

check_out
string
required

Check-out date in YYYY-MM-DD format. Must be after check_in.

Example:

"2026-07-04"

rooms
object[]
required

Room configurations. Minimum 1 room, maximum 8 rooms. Each room supports up to 5 total occupants (adults + children).

Required array length: 1 - 8 elements
star_ratings
number[][]

Filter results by star ratings. Pass one or more values from 1–5.

Example:
price_min_usd_cents
number

Minimum TOTAL price filter in USD cents (across all nights/rooms). Server converts to nightly unit range using computed stay multiplier.

Required range: x >= 0
Example:

5000

price_max_usd_cents
number

Maximum TOTAL price filter in USD cents.

Required range: x >= 1
Example:

500000

property_types
string[][]

Filter by property type. Values come from GET /hotels/filters → property_types.

Example:
chain_ids
number[][]

Filter by hotel chain IDs. Values come from GET /hotels/filters → chains.

Example:
facility_ids
number[][]

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:
hotel_name
string

Free-text hotel name filter. Server runs ILIKE "%name%".

Example:

"marriott"

hotel_ids
number[][]

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:
nationality
string
default:IN

Nationality of the guest in ISO alpha-2 format (e.g. IN for Indian, US for United States).

Example:

"IN"

language
string

Requested response language. Forwarded to suppliers such as Leamigo.

Example:

"en"

limit
number
default:20

Requested hotels per page. If omitted, default page size is used.

Required range: 1 <= x <= 100
Example:

20

cursor
string

Cursor token for next-page fetch in format "sortKey_hotelId". Pass the next_cursor returned in previous response.

Example:

"1037.5_1892345"

price_sort
enum<string>
default:recommended

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).

Available options:
low_to_high,
high_to_low
Example:

"low_to_high"

pricing_mode
enum<string>
default:instant

'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 all supplier quotes collected in supplier_prices in this single call. The server does not choose the lowest quote.

Available options:
instant,
live
Example:

"instant"

sort
enum<string>
default:recommended

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 searched place centre first; value = best value_pct deals first.

Available options:
recommended,
price_low_to_high,
price_high_to_low,
stars,
distance_from_center,
value
Example:

"distance_from_center"

fields
string[]

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:

Response

contract_version
string
required
Example:

"1"

success
boolean
required
Example:

true

message
string
required
Example:

"Hotels fetched successfully"

data
object
required