START
Markdown ↗

Filters & sorting

Combine hotel conditions with live rate conditions. Hotel conditions apply before supplier pricing and before the 1,000-candidate search cap. Rate conditions apply to returned offers before minimum prices and room groups are selected. All supplied conditions must hold; arrays of star ratings or property types accept any listed value. All requested amenities are required.

Where filters work

Operationhotel_filtersrate_filtersOther controls
search_hotelsYesYesproviders, sort, page_size
get_room_ratesNo; one identified hotelYesproviders, page_size
get_hotelNo; one identified hotelNo live priceshotel_id

Developer HTTP and developer MCP use the same nested request. Consumer MCP search uses flat destination/dates/occupancy arguments, with the same hotel_filters and rate_filters objects. Every filter is optional. Unsupported fields and invalid ranges return 400; no credits are charged. Changing filters starts a new quote call.

Hotel filters

FieldTypeMeaning
amenitiesarrayAll requested amenities must match. Broad wifi, parking, pool and fitness include feed variants. pet_friendly / pet-friendly accepts pet-allowed themes; free-wifi means wifi::free.
star_rating_minnumberMinimum hotel star classification, distinct from guest reviews.
star_rating_maxnumberMaximum hotel star classification, 0–5.
star_ratingsarrayAccepted exact star classifications; intersects with any min/max range.
review_score_minnumberMinimum guest score normalized to 10, using the displayed review_summary provider. Unknown scores/scales do not qualify.
review_count_minintegerMinimum review count from that same review_summary provider. Counts are not added across providers.
property_typestringOne exact source property type; use instead of property_types.
property_typesarrayAccept any of these source property types. Use instead of property_type.
name_containsstringCase-insensitive text in the hotel name; treated as literal text, not a regular expression.
max_distance_kmnumberMaximum straight-line distance from the resolved destination center, up to 20 km. Requires a city/destination or latitude/longitude.

HotelUse uses Expedia’s star classification when one unambiguous Expedia mapping is available; other properties retain the catalog classification. star_classification identifies the source, verification status and check time. Missing or ambiguous mapped classifications stay unknown. Classification facts refresh within seven days, independently of live prices. HotelUse does not overwrite B2B source records. Provider classifications can differ.

Star classification and guest-review score are different. A four-star hotel does not imply a guest score of 8/10. star_ratings accepts 1–5 distinct whole-star values; min/max ranges use 0–5 and intersect with an exact list. property_types accepts 1–12 distinct source values, such as hotel or resort; use either property_type or property_types. Amenities accepts up to 20 canonical source codes. Unknown source metadata does not establish that a condition is satisfied.

Guest-review rules

review_score_min is a 0–10 threshold against review_summary.score_out_of_10. The displayed review_summary selects the provider with the largest valid review count among records with a usable score and known scale. Source order breaks count ties. A 4.5/5 source score becomes 9/10; an ambiguous 4.5 with no scale does not qualify. Scores above 5 and at most 10 use a 10-point scale when no explicit scale exists. Invalid explicit scales stay unknown. Star ratings are never substituted.

review_count_min applies to that same provider. Counts are not added across Booking, Expedia, Agoda or other sources. A high score from a small provider sample cannot bypass the lower score displayed from the selected larger sample. Missing review summaries are excluded whenever a review condition is requested. These are source catalog facts, not independent certification of review quality or hotel star classification.

Live rate filters

FieldTypeMeaning
refundable_onlybooleanRequire known refundable terms; unknown terms do not qualify.
breakfast_includedbooleanRequire an offer explicitly marked breakfast included.
stay_total_minnumberMinimum full-stay amount in context.currency for all requested rooms, including mandatory taxes and fees. Not a nightly price.
stay_total_maxnumberMaximum full-stay amount in context.currency for all requested rooms, including mandatory taxes and fees. Applies to each returned offer before minima.

Budget amounts are in context.currency (flat currency on consumer MCP). They include every requested night and every requested room, plus mandatory taxes and fees. They are not nightly or per-room budgets. Bounds are inclusive, from 0 to 100,000,000; minimum cannot exceed maximum. A 2-night, 2-room stay_total_max of 600 means a combined stay total of at most 600, not 600 per room or per night. Expedia, Booking and Agoda return native quotes in the requested currency. Brek settles in USD and uses a fresh FX snapshot for other display currencies and mandatory local-currency fees. Inspect currency_conversion and mandatory_fees; converted totals are estimates and include the listed local fees once. Offers with unconfirmed mandatory fees do not qualify for budget filters.

Refundability must be explicitly true to pass refundable_only. Unknown terms do not qualify. Breakfast must be explicitly included to pass breakfast_included. These filters choose among the plans suppliers actually return; they cannot retrieve plans omitted by supplier response caps. A provider can have no matching offer while the hotel still has other available rooms. Search provider status no_matching_offer means filters removed otherwise returned confirmed-fee offers; no_availability means no offer was returned. Incomplete prices and failed calls retain their own statuses. Detailed room calls contain only matching offers and groups; provider_results still records the underlying call outcome.

Distance and result order

City destinations resolve through Auto Suggest. Explicit latitude/longitude uses the supplied center without Auto Suggest. Destination search starts at 20 km and expands to 40 km then 60 km only below 50 static candidates. An explicit max_distance_km disables expansion and can narrow the area to more than 0 and at most 20 km. It requires a city/destination or latitude/longitude pair and measures straight-line distance from its center, not route distance. It does not mutate the shared destination cache.

The default distance_brek_savings_desc sorts priced hotels into 0–5, 5–10, 10–15 and 15–20 km bands, then by greatest Brek price advantage inside each band: cheapest other eligible provider total minus Brek total, in the display currency. A positive amount is a saving; a negative amount means a competitor is cheaper. Missing comparisons go last within the band. Price, distance and hotel ID break ties. Exact boundaries belong to the nearer band. distance_price_asc retains price ascending within bands. stay_total_asc sorts all matched hotels globally by price. Unpriced hotels remain last. Claude and ChatGPT display provider rows in price order. Raw API provider arrays do not guarantee price order; use lowest_provider or sort eligible returned totals in your code. data.ranking, distance_meters and distance_bucket explain the order.

Duplicate catalog identities

Live destination searches consolidate records only when GIATA and exact provider IDs establish one property, or when the entire namespaced provider-ID set is identical. Both paths also require matching full names, country, nearby coordinates and non-conflicting GIATA IDs. Names or addresses alone are insufficient. Distinct GIATA properties, including separate club-level or residence listings, stay separate. Inactive GIATA provider IDs are never transferred into a canonical quote mapping.

Hotel information retains source timestamps and hotel record versions. Room results use the same hotel identity returned by search. HotelUse consolidates verified aliases when comparing provider quotes; preserve the exact returned hotel_id for follow-up questions.

catalog_quality reports duplicate_records_collapsed, inactive_duplicate_mappings_ignored and identity_verification. Verification reads the existing GIATA catalog within a bounded sub-second budget and caches successful facts for up to five minutes. Missing, contradictory or unavailable identity evidence leaves the records separate and preserves valid supplier shopping. No B2B inventory or supplier mapping is rewritten. A known inactive Booking mapping may be restored only in the HotelUse live overlay when Booking’s current details API confirms the same provider ID, hotel name, country and coordinates. Verification and room-name/photo caches are stored separately in HotelUse and expire after one day. A differently named sub-property is never substituted.

Facility names, property aliases and coverage

Broad facility requests include canonical variants: kitchen includes kitchenette/shared kitchens, hot-tub includes recorded spa/jacuzzi variants, and family-friendly, kids-friendly, accessibility and laundry use their recorded subtypes. TV excludes security cameras. free-wifi remains restricted to wifi::free. Static free-breakfast is a property facility; rate_filters.breakfast_included requires the actual quoted rate to include breakfast. Use rate_filters.refundable_only for cancellation terms, not a static facility code. Pet-friendly filtering excludes explicit pet bans; service-animal access alone does not imply pet access.

Property aliases such as condo, guesthouse, farm-house, campground, rv, mobile-home and house-boat map to source feed spellings. Raw records retain original property_type and facility codes.

A returned lowest_offer is an actual supplier quote with its reported fee status. coverage_incomplete means other branches or options could not be checked; it does not invalidate that returned quote. rates.availability_status distinguishes available, no_matching_offer, no_availability and unknown. Unmapped, unsupported and failed lookups are not evidence of a sold-out hotel. Supplier date restrictions (unsupported_dates) and occupancy restrictions (unsupported_occupancy) are permanent for the submitted request and are not retried. Other providers can still quote the same hotel and stay.

HTTP and developer MCP example

This is a combined request shape, not a promised result count. Replace the dates with future dates for your trip. Restrictive combinations can return no matching rates. All three endpoint pages also link to this filter guide.

json
{
  "location": {
    "country": "US",
    "city": "Bellevue",
    "region": "WA"
  },
  "context": {
    "check_in": "2026-11-12",
    "check_out": "2026-11-14",
    "rooms": [
      {
        "adults": 2,
        "children_ages": []
      }
    ],
    "currency": "USD",
    "market": {
      "residency_country": "US"
    }
  },
  "hotel_filters": {
    "star_ratings": [
      4,
      5
    ],
    "review_score_min": 8,
    "review_count_min": 100,
    "amenities": [
      "wifi",
      "pool"
    ],
    "property_types": [
      "hotel",
      "resort"
    ],
    "max_distance_km": 5
  },
  "rate_filters": {
    "stay_total_max": 600,
    "refundable_only": true,
    "breakfast_included": true
  },
  "sort": "distance_brek_savings_desc",
  "page_size": 25
}

POST this body to /v1/hotels/search or pass it as arguments to the developer MCP search_hotels tool.

Consumer MCP example

json
{
  "name": "search_hotels",
  "arguments": {
    "destination": "Bellevue, Washington",
    "country": "US",
    "check_in": "2026-11-12",
    "check_out": "2026-11-14",
    "rooms": [
      {
        "adults": 2,
        "children_ages": []
      }
    ],
    "currency": "USD",
    "hotel_filters": {
      "star_ratings": [
        4,
        5
      ],
      "review_score_min": 8,
      "review_count_min": 100,
      "amenities": [
        "wifi",
        "pool"
      ],
      "property_types": [
        "hotel",
        "resort"
      ],
      "max_distance_km": 5
    },
    "rate_filters": {
      "stay_total_max": 600,
      "refundable_only": true,
      "breakfast_included": true
    },
    "sort": "distance_brek_savings_desc"
  }
}

For a room follow-up, copy the hotel_id, original dates/rooms/currency and search_session_id as search_quote_session_id. The search reference inherits omitted dates, rooms, currency, language, residency, providers and rate_filters. Explicit arguments override inherited values except device; send rate_filters: {} to clear inherited rate constraints. Hotel filters describe the search candidate set and are not room-tool arguments.

Pagination and coverage

Search ranking is computed across the returned candidate set before pagination. Copy the exact quote_session_id and next_cursor into a page-only request; do not calculate a cursor or mix destination/filters into it. Pages reuse the original filtered quote. A search can still reach the 1,000-candidate cap; check coverage before describing it as exhaustive. page_size controls output pages, not candidate pricing.

Search API reference · Room API reference · OpenAPI.