---
title: "Query Session"
method: POST
path: "/hotel-search/sessions/{session_id}/query"
tags: ["hotel-search"]
---

# Query Session

`POST /hotel-search/sessions/{session_id}/query`

Query hotels within a session.

## Path parameters

- `session_id` string, uuid, required

## Request body

- HotelSearchQueryRequest — Query hotels within a viewport or radius. Idempotent — client polls this same endpoint to pick up live prices as they resolve from providers. Provide either viewport (map pan/zoom) or location (initial search), not both.
  - `viewport` Viewport — Map viewport defined by SW and NE corners of the visible area. Sent by the client whenever the user pans or zooms the map.
    - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
      - `latitude` number, required
      - `longitude` number, required
    - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
      - `latitude` number, required
      - `longitude` number, required
  - `location` LocationRadius — Center point with radius — used for the initial search before the user has a map viewport (e.g. "hotels in Tokyo" resolves to a lat/lng + radius).
    - `latitude` number, required
    - `longitude` number, required
    - `radius_km` number, required
  - `zoom_level` integer, nullable — Density hint for clustering. When provided, the server groups nearby hotels into clusters at a resolution derived from this value. When absent, no clustering — returns a flat ranked list.
  - `cluster_threshold` integer, nullable — Minimum hotels in an H3 cell to form a cluster (default 9). Hotels in cells with fewer are returned as individual pins.
  - `filters` SearchFilters — Quality and price filters for hotel search. Used by both pricing and discovery APIs. The discovery API adds hotel_chains and name_search on top.
    - `min_star_rating` number, nullable — Minimum hotel star rating (0-5)
    - `max_star_rating` number, nullable — Maximum hotel star rating (0-5)
    - `min_review_score` number, nullable — Minimum review score (0-10)
    - `min_price_per_night` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
      - `amount` integer, required
      - `currency` string, required
    - `max_price_per_night` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
      - `amount` integer, required
      - `currency` string, required
    - `amenities` string[] — Required amenities
    - `refundable_only` boolean — Only return refundable options
    - `hotel_chains` string[]
    - `name_search` string, nullable
  - `sort` 'relevance' | 'price' | 'star_rating' | 'review_score' | 'distance' — How to order hotel results in the list/map view.
  - `sort_reference_point` LatLng — Geographic coordinate pair. Used by both pricing and discovery APIs.
    - `latitude` number, required
    - `longitude` number, required

## Response `200`

Successful Response

- HotelSearchQueryResponse — Response from the query endpoint. Client polls this to get progressive updates. First call returns Phase 1 (hotel pins + cached prices, pricing_status=pending). Subsequent polls return the same structure with live prices filled in and pricing_status progressing to in_progress then complete. Includes session metadata so the client never needs a separate GET endpoint. REST map surfaces should use this response directly; HotelMapToken is reserved for chat-embedded map tokens.
  - `query_id` string, required
  - `session_id` string, uuid, required
  - `check_in` string, date, required
  - `check_out` string, date, required
  - `nights` integer, required
  - `guests` HotelSearchGuestConfig, required — Wraps a list of GuestRoom into a typed config object for the discovery API. Reuses the shared GuestRoom model — just adds a container with validation.
    - `rooms` GuestRoomOutput[], required
      - `adults` integer, required — Number of adults
      - `children` object[] — List of children with ages
  - `filters` SearchFilters — Quality and price filters for hotel search. Used by both pricing and discovery APIs. The discovery API adds hotel_chains and name_search on top.
    - `min_star_rating` number, nullable — Minimum hotel star rating (0-5)
    - `max_star_rating` number, nullable — Maximum hotel star rating (0-5)
    - `min_review_score` number, nullable — Minimum review score (0-10)
    - `min_price_per_night` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
      - `amount` integer, required
      - `currency` string, required
    - `max_price_per_night` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
      - `amount` integer, required
      - `currency` string, required
    - `amenities` string[] — Required amenities
    - `refundable_only` boolean — Only return refundable options
    - `hotel_chains` string[]
    - `name_search` string, nullable
  - `criteria` HotelSearchCriteria, required — Criteria snapshot for a hotel search session/map token. Criteria changes create a new hotel search session; FE should reject stale updates whose criteria_hash does not match the active map instance.
    - `check_in` string, date, required
    - `check_out` string, date, required
    - `guests` HotelSearchGuestConfig, required — Wraps a list of GuestRoom into a typed config object for the discovery API. Reuses the shared GuestRoom model — just adds a container with validation.
      - `rooms` GuestRoomOutput[], required
        - `adults` integer, required — Number of adults
        - `children` object[] — List of children with ages
    - `anchor` HotelSearchAnchor, required — Canonical search anchor for a hotel map session. Extends LocationRadius to keep the existing flat latitude/longitude/radius_km shape while adding the label/type metadata FE needs. This prevents map-first hotel search from falling back to a vague destination code or implicit city centroid.
      - `latitude` number, required
      - `longitude` number, required
      - `radius_km` number, required
      - `label` string, required
      - `source` 'city' | 'neighborhood' | 'hotel' | 'airport' | 'user_phrase' | 'map', required — Source/type of the canonical hotel map search anchor.
      - `place_code` string, nullable
  - `criteria_hash` string, required
  - `anchor` HotelSearchAnchor, required — Canonical search anchor for a hotel map session. Extends LocationRadius to keep the existing flat latitude/longitude/radius_km shape while adding the label/type metadata FE needs. This prevents map-first hotel search from falling back to a vague destination code or implicit city centroid.
    - `latitude` number, required
    - `longitude` number, required
    - `radius_km` number, required
    - `label` string, required
    - `source` 'city' | 'neighborhood' | 'hotel' | 'airport' | 'user_phrase' | 'map', required — Source/type of the canonical hotel map search anchor.
    - `place_code` string, nullable
  - `loaded_bounds` Viewport, required — Map viewport defined by SW and NE corners of the visible area. Sent by the client whenever the user pans or zooms the map.
    - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
      - `latitude` number, required
      - `longitude` number, required
    - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
      - `latitude` number, required
      - `longitude` number, required
  - `hotels` HotelSearchResult[], required
    - `hotel_id` integer, required
    - `name` string, required
    - `latitude` number, required
    - `longitude` number, required
    - `star_rating` number, nullable
    - `review_rating` number, nullable
    - `review_rating_source` string, nullable
    - `hotel_chain` string, nullable
    - `address` string, required
    - `city` string, nullable
    - `country_code` string, nullable
    - `amenities` string[]
    - `image_url` string, nullable
    - `image_urls` string[]
    - `price` HotelPrice — Best known price for a hotel. Starts approximate (from cache), then gets replaced with live data from the provider once pricing resolves. Phase 1 (cached): is_approximate=True, only nightly_rate + total populated. Phase 2 (live): is_approximate=False, all fields populated from provider. Client rendering: always read price.nightly_rate. If is_approximate, show with "~" prefix. No field branching needed.
      - `nightly_rate` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `total` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `member_nightly_rate` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `member_total` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `is_approximate` boolean, required
      - `cached_at` string, date-time, required
      - `room_name` string, nullable
      - `provider` string, nullable
      - `is_refundable` boolean, nullable
      - `free_cancellation_until` string, date-time, nullable
      - `meal_plan` string, nullable
      - `bed_type` string, nullable
      - `mandatory_fees` MandatoryFee[]
        - `name` string, required
        - `fee_type` string, nullable
        - `unit_amount` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `pricing_unit` string, nullable
        - `total` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `retail_comparison_total` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `retail_comparison_nightly` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `exact_public_rate_comparison` ExactPublicRateComparison — Fee-normalized proof for the exact public version of this stay.
        - `source` string, required
        - `public_total` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `customer_total` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `savings_bucket_percent` integer, required
      - `all_in_total` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `all_in_nightly` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `member_all_in_total` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `member_all_in_nightly` Money — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
    - `compare_price` ComparePrice — Expedia retail benchmark price for comparison display. Display-only — not bookable. Used to show "Save X% vs Expedia".
      - `nightly_rate` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `total` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `savings_percent` number, required — Fraction saved vs Expedia, e.g. 0.22 = 22%. Negative means ETG is more expensive.
      - `confidence` 'estimated' | 'cached' | 'live' | 'detail', required — Quality tier of compare price data.
      - `source` string
      - `provider` string, nullable — Displayed retail provider from the compare source, e.g. Expedia.com.
      - `fetched_at` string, date-time, nullable
    - `price_proof` HotelPriceProof — Completed fresh price check; claims remain optional and independent.
      - `checked_at` string, date-time, required
      - `expires_at` string, date-time, required
      - `public` HotelPriceProofPublic — A fresh, checkable public-OTA comparison that Axel wins.
        - `provider` 'Expedia' | 'Booking.com', required
        - `axel_total` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `public_total` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `savings_percent` integer, required
        - `link` string, nullable
      - `timing` HotelPriceProofTiming — Google's independent historical booking-time signal.
        - `percent_below_usual` integer, required
    - `score` number, nullable
    - `cluster_id` string, nullable
    - `cluster_below_zoom` integer, nullable
    - `debug` object, nullable
  - `clusters` HotelCluster[]
    - `cluster_id` string, required
    - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
    - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
      - `latitude` number, required
      - `longitude` number, required
    - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
      - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
    - `hotel_count` integer, required
    - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
      - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
      - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
        - `amount` integer, required
        - `currency` string, required
    - `avg_star_rating` number, nullable
  - `clusters_by_zoom` ClustersByZoom — Precomputed clusters for each zoom band so the FE can switch instantly.
    - `xlow` HotelCluster[]
      - `cluster_id` string, required
      - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
      - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
        - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
        - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
      - `hotel_count` integer, required
      - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
        - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `avg_star_rating` number, nullable
    - `low` HotelCluster[]
      - `cluster_id` string, required
      - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
      - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
        - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
        - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
      - `hotel_count` integer, required
      - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
        - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `avg_star_rating` number, nullable
    - `mid` HotelCluster[]
      - `cluster_id` string, required
      - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
      - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
        - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
        - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
      - `hotel_count` integer, required
      - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
        - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `avg_star_rating` number, nullable
    - `high` HotelCluster[]
      - `cluster_id` string, required
      - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
      - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
        - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
        - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
      - `hotel_count` integer, required
      - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
        - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `avg_star_rating` number, nullable
    - `xhigh` HotelCluster[]
      - `cluster_id` string, required
      - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
      - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
        - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
        - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
      - `hotel_count` integer, required
      - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
        - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `avg_star_rating` number, nullable
    - `xxhigh` HotelCluster[]
      - `cluster_id` string, required
      - `cluster_type` 'loading' | 'grouped' — Why this cluster exists — informs how the front end renders it.
      - `center` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
        - `latitude` number, required
        - `longitude` number, required
      - `bounds` ClusterBounds, required — Bounding box of a hotel cluster — client zooms into this area on click.
        - `sw` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
        - `ne` LatLng, required — Geographic coordinate pair. Used by both pricing and discovery APIs.
          - `latitude` number, required
          - `longitude` number, required
      - `hotel_count` integer, required
      - `price_range` PriceRange — Min/max price range shown on cluster pins (e.g. "$120 - $280").
        - `min` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
        - `max` Money, required — Immutable money value stored as integer minor units. Amount is always stored in the smallest currency unit (cents, yen, pesos, etc). This avoids floating-point precision issues and matches payment processor standards. Examples: $19.99 USD -> Money(amount=1999, currency="USD") ¥1000 JPY -> Money(amount=1000, currency="JPY") $1000.00 CLP -> Money(amount=1000, currency="CLP") Serializes to {"amount": 1999, "currency": "USD"}. IMPORTANT: Use Money.from_decimal() for user-facing amounts like "$19.99". The constructor expects integer minor units (cents).
          - `amount` integer, required
          - `currency` string, required
      - `avg_star_rating` number, nullable
  - `total_in_area` integer, required
  - `pricing_status` 'pending' | 'in_progress' | 'complete', required — Tracks where we are in the live pricing lifecycle for a query. Client polls the query endpoint and checks this to know when to stop.
  - `hotels_priced` integer
  - `hotels_unavailable` integer
  - `pricing_pool_size` integer
  - `pricing_requested_count` integer
  - `hotels_with_compare_price` integer
  - `retry_after_ms` integer, nullable
  - `unavailable_hotel_ids` integer[]

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/helloaxel/apis/client-api-gateway.md) · [All operations](https://skmtc.dev/helloaxel/apis/client-api-gateway/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/helloaxel/client-api-gateway/revisions/d3c4c29fede7/schema)
