Skip to main content
Glama

Booking.com Hotel Search (Live Prices)

FlightPowers: search hotels

search_hotels
Read-only

FlightPowers hotel search: live Booking.com availability and nightly prices for a destination and date range. Input: a free-text destination the way a person would write it ("Rome", "Tokyo Shibuya"), plus check-in and check-out dates. Returns each property's price, review score, room type, location, latitude/longitude and a booking link: 10 properties by default, the cheapest always among them; limit asks for more or fewer, and verbose: true returns the source's full rows.

price_as_seen_from, a two-letter country code, prices the same stay the way a shopper resident in that country would see it. Gaps are real but usually modest and property-dependent, and rates move between calls, so one call per country is not evidence of a gap; a parity check holds one named property fixed and calls each country a few times.

A date range and a nights value price several stays in one call: checkin_date_from, checkin_date_to and nights (a number, or a list like [2, 3, 7]) replace a fixed checkin_date/checkout_date, and every check-in date is priced separately. The answer is stays -- one entry per stay with its cheapest property, per-night price and median -- plus cheapest_overall, and the full property list for the cheapest stay only. Each stay is one search; max_searches caps it, and a request that expands past the cap is sampled evenly across the range and says so in search_coverage. With the caller's own key the cap rises by itself to cover a month-sized range. On the free sign-in allowance (10 searches a day, one per stay) a range larger than what is left today is refused before anything runs; a range within what is left runs, and a wider range needs the caller's own key.

Rates go stale within minutes: a current price comes from a new search, not from an earlier result.

Input Schema

NameRequiredDescriptionDefault
limitNoHow many properties to return (default 10; a stay has about 25). They come in the order Booking.com returned them, and the cheapest is always included. results_total says how many there were.
adultsNoNumber of adult guests. Defaults to the upstream default when omitted.
nightsNoHow many nights to stay, as a number (3) or a list ([2, 3, 7]) to price several lengths. Derives the check-out date from each check-in date, so it replaces checkout_date rather than joining it.
filtersNoProperty filters to apply, e.g. ["free_cancellation", "breakfast_included"]. An unknown name is rejected with the list of valid ones rather than being ignored.
verboseNoReturns each property exactly as the source sent it, image URLs and the full tracking link included, and every property unless limit is set. Off by default: rows leave out image URLs, the booking link keeps only its stay parameters, and price_per_night is added.
childrenNoNumber of children sharing the room.
currencyNoISO currency code for the prices returned, e.g. "usd".
destinationYesWhere to stay, in free text the way a person would write it, e.g. "Rome" or "Tokyo Shibuya". A city, district, landmark or region all work; no internal location ID is needed.
checkin_dateNoFirst night of the stay, "YYYY-MM-DD". With checkout_date it prices one stay; checkin_date_from plus checkin_date_to price a range of check-in dates instead.
max_searchesNoThe searches this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- with the caller's own key the cap rises to cover a request that size by itself. A lower value spends less and a higher one (hard maximum 200) covers a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front.
checkout_dateNoDeparture morning, "YYYY-MM-DD". Must be after checkin_date. Mutually exclusive with `nights`.
checkin_date_toNoLast check-in date of the range, "YYYY-MM-DD".
budget_per_nightNoOnly properties at or below this nightly price, in `currency`, are returned.
checkin_date_fromNoFirst check-in date of a range, "YYYY-MM-DD". Needs checkin_date_to and nights, and prices one stay per check-in date in the range.
price_as_seen_fromNoTwo-letter country code, e.g. "de". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. A rate-parity check holds one named property fixed and calls each country a few times, because rates move between calls and one call per country can show a gap that is not there. Without it the price is neutral.

Output Schema

NameRequiredDescriptionDefault
staysNoOne entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it. Coverage comes from here, not from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that.
messageNo
partialNoPresent when some stays failed but others were priced. Plain text saying how much of the request the answer covers.
resultsYesThe properties found, in the order Booking.com returned them. An empty array is only meaningful when search_status is 'empty'. By default at most `limit` rows (10), the cheapest always included, each the source's own object without image URLs, with the booking link cut to its stay parameters and price_per_night (the stay total divided by its nights) added; `verbose: true` returns the source's rows untouched. latitude and longitude are the property's WGS84 coordinates in decimal degrees, from Booking.com, null when it publishes none.
api_usageNoWith the caller's own key: what this call cost their RapidAPI plan, and what remains on it. On a free signed-in search (`trial` present): the day's free-search counter instead, and no plan figures -- the search ran on FlightPowers' key and nothing is billed to the user. Present on every response that reached the upstream, including a degraded one.
signup_urlNoWhere the caller subscribes or changes plan.
result_countNo
results_noteNoPresent when `limit` left properties out: how many were found and how to see more.
needs_api_keyNoTrue when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message describe the fix.
results_totalNoHow many properties the source returned for the stay in `results`, before `limit`. Absent with `verbose: true` and no `limit`, where every row is in `results`.
search_statusNoDate-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and the caller's own RapidAPI key, once connected, removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help; a request with fewer dates or nights, or a larger plan, does.
applied_filtersNoWhich of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through.
quota_exhaustedNoTrue when the caller's RapidAPI plan has no requests left for the current period.
search_coverageNoWhat was actually priced on a date-range search. Present whether or not the request was truncated, so the answer's basis is on the record either way.
cheapest_overallNoThe cheapest stay across everything priced, or null when nothing was. `results` holds this stay's full property list.
results_for_stayNoWhich stay `results` belongs to on a date-range search, or null when nothing was priced. `results` holds this stay's properties only, not the whole range's.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed22 schema fields changed
    • changedInput schema / properties / budget_per_night / description
      Previous value: -"Only return properties at or below this nightly price, in `currency`."New value: +"Only properties at or below this nightly price, in `currency`, are returned."
    • changedInput schema / properties / checkin_date / description
      Previous value: -"First night of the stay, \"YYYY-MM-DD\". Give this with checkout_date for one stay, or use checkin_date_from plus checkin_date_to for a range of check-in dates."New value: +"First night of the stay, \"YYYY-MM-DD\". With checkout_date it prices one stay; checkin_date_from plus checkin_date_to price a range of check-in dates instead."
    • changedInput schema / properties / checkin_date_from / description
      Previous value: -"First check-in date of a range, \"YYYY-MM-DD\". Needs checkin_date_to and nights, and prices one stay per check-in date in the range -- the hotel equivalent of the flights date range."New value: +"First check-in date of a range, \"YYYY-MM-DD\". Needs checkin_date_to and nights, and prices one stay per check-in date in the range."
    • changedInput schema / properties / checkout_date / description
      Previous value: -"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date. Give either this or nights, not both."New value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date. Mutually exclusive with `nights`."
    • changedInput schema / properties / destination / description
      Previous value: -"Where to stay, in free text the way a person would say it, e.g. \"Rome\" or \"Tokyo Shibuya\". A city, district, landmark or region all work; no internal location ID is needed."New value: +"Where to stay, in free text the way a person would write it, e.g. \"Rome\" or \"Tokyo Shibuya\". A city, district, landmark or region all work; no internal location ID is needed."
    • addedInput schema / properties / limit
      Added value: +{
      +  "anyOf": [
      +    {
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "How many properties to return (default 10; a stay has about 25). They come in the order Booking.com returned them, and the cheapest is always included. results_total says how many there were."
      +}
    • changedInput schema / properties / max_searches / description
      Previous value: -"The searches this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- with the caller's own key the cap rises to cover a request that size by itself. Set it lower to spend less, or higher (hard maximum 200) for a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front."New value: +"The searches this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- with the caller's own key the cap rises to cover a request that size by itself. A lower value spends less and a higher one (hard maximum 200) covers a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front."
    • changedInput schema / properties / price_as_seen_from / description
      Previous value: -"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. For a rate-parity check hold one named property fixed and call each country a few times, because rates move between calls and one call per country can show a gap that is not there. Omit it for a neutral price."New value: +"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. A rate-parity check holds one named property fixed and calls each country a few times, because rates move between calls and one call per country can show a gap that is not there. Without it the price is neutral."
    • addedInput schema / properties / verbose
      Added value: +{
      +  "default": false,
      +  "description": "Returns each property exactly as the source sent it, image URLs and the full tracking link included, and every property unless limit is set. Off by default: rows leave out image URLs, the booking link keeps only its stay parameters, and price_per_night is added.",
      +  "type": "boolean"
      +}
    • changedOutput schema / properties / api_usage / properties / note / description
      Previous value: -"The same figures as a sentence, for the model to relay."New value: +"The same figures as one plain sentence."
    • changedOutput schema / properties / cheapest_overall / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": true,
      -    "properties": {
      -      "checkin_date": {
      -        "type": "string"
      -      },
      -      "checkout_date": {
      -        "type": "string"
      -      },
      -      "currency": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "nights": {
      -        "anyOf": [
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "price_per_night": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "property": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": true,
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
      -      },
      -      "total": {
      -        "type": "number"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "properties": {
      +      "checkin_date": {
      +        "type": "string"
      +      },
      +      "checkout_date": {
      +        "type": "string"
      +      },
      +      "currency": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "nights": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "price_per_night": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "property": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": true,
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, so image URLs are dropped to keep the payload small. The booking link is kept."
      +      },
      +      "total": {
      +        "type": "number"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / needs_api_key / description
      Previous value: -"True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it."New value: +"True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message describe the fix."
    • changedOutput schema / properties / results / description
      Previous value: -"The properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. Each row is the source's own object, passed through. latitude and longitude are the property's WGS84 coordinates in decimal degrees, from Booking.com, null when it publishes none."New value: +"The properties found, in the order Booking.com returned them. An empty array is only meaningful when search_status is 'empty'. By default at most `limit` rows (10), the cheapest always included, each the source's own object without image URLs, with the booking link cut to its stay parameters and price_per_night (the stay total divided by its nights) added; `verbose: true` returns the source's rows untouched. latitude and longitude are the property's WGS84 coordinates in decimal degrees, from Booking.com, null when it publishes none."
    • addedOutput schema / properties / results / items / properties / price_per_night
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / results_for_stay / description
      Previous value: -"Which stay `results` belongs to on a date-range search, or null when nothing was priced. Without it the rows read as 'the search's results' and get quoted against the wrong dates."New value: +"Which stay `results` belongs to on a date-range search, or null when nothing was priced. `results` holds this stay's properties only, not the whole range's."
    • addedOutput schema / properties / results_note
      Added value: +{
      +  "description": "Present when `limit` left properties out: how many were found and how to see more.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / results_total
      Added value: +{
      +  "description": "How many properties the source returned for the stay in `results`, before `limit`. Absent with `verbose: true` and no `limit`, where every row is in `results`.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / search_coverage / description
      Previous value: -"What was actually priced on a date-range search. Present whether or not the request was truncated, so a model can state honestly what its answer rests on."New value: +"What was actually priced on a date-range search. Present whether or not the request was truncated, so the answer's basis is on the record either way."
    • changedOutput schema / properties / search_coverage / properties / stopped_early / description
      Previous value: -"Present when something other than the cap ended the fan-out. 'deadline': the call reached its time limit and the remaining combinations were never sent or billed, so the results are real but do not cover the whole range."New value: +"Present when something other than the cap ended the fan-out. 'deadline': the call reached its time limit and the remaining combinations were never sent or billed, so the results are real but cover only part of the range."
    • changedOutput schema / properties / search_status / description
      Previous value: -"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help -- ask for fewer dates or nights, or move to a larger plan."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and the caller's own RapidAPI key, once connected, removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help; a request with fewer dates or nights, or a larger plan, does."
    • changedOutput schema / properties / stays / description
      Previous value: -"One entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it.\n\nRead this rather than inferring coverage from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that."New value: +"One entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it.\n\nCoverage comes from here, not from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that."
    • changedOutput schema / properties / stays / items / properties / cheapest / description
      Previous value: -"The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."New value: +"The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, so image URLs are dropped to keep the payload small. The booking link is kept."
  2. Changed11 schema fields changed
    • changedInput schema / properties / max_searches / description
      Previous value: -"The billed requests this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- the cap rises to cover a request that size by itself. Set it lower to spend less, or higher (hard maximum 200) for a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front."New value: +"The searches this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- with the caller's own key the cap rises to cover a request that size by itself. Set it lower to spend less, or higher (hard maximum 200) for a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front."
    • removedInput schema / properties / providers
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "type": "string"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Which sources to price this stay on, e.g. [\"booking\"], [\"airbnb\"] or [\"booking\", \"airbnb\"]. Defaults to [\"booking\"]. Each source is a separate RapidAPI subscription, so a source you have no key for is not called; it comes back named in providers_skipped with the reason and where to subscribe, rather than silently missing. filters and price_as_seen_from apply to booking only; airbnb takes price_min, price_max and room_types instead, and rows from it carry rating_scale 5 where booking's carry 10."
      -}
    • changedOutput schema / properties / api_usage / description
      Previous value: -"What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed."New value: +"With the caller's own key: what this call cost their RapidAPI plan, and what remains on it. On a free signed-in search (`trial` present): the day's free-search counter instead, and no plan figures -- the search ran on FlightPowers' key and nothing is billed to the user. Present on every response that reached the upstream, including a degraded one."
    • addedOutput schema / properties / api_usage / properties / free_searches_day_cap
      Added value: +{
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / api_usage / properties / free_searches_remaining_today
      Added value: +{
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / api_usage / properties / free_searches_used_today
      Added value: +{
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / api_usage / properties / hub_requests_billed / description
      Previous value: -"How many HTTP requests RapidAPI actually billed. Larger than requests_used_by_this_call when a search failed with a server error and was retried, because the retry is billed too. This is the figure the invoice will show."New value: +"How many HTTP requests RapidAPI actually billed. Larger than requests_used_by_this_call when a search failed with a server error and was retried, because the retry is billed too. With the caller's own key this is the figure their RapidAPI plan is charged. Absent on a free search."
    • removedOutput schema / properties / caveats
      Removed value: -{
      -  "description": "Sentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.",
      -  "items": {
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • removedOutput schema / properties / providers
      Removed value: -{
      -  "description": "One entry per source that was called, in the order they were requested. Only present when `providers` named more than the default source.",
      -  "items": {
      -    "additionalProperties": true,
      -    "description": "What one accommodation source answered. Present for every source that was CALLED, whether or not it answered: a source with search_status 'degraded' carries a reason, a null count and no prices, which is not the same answer as a source that found nothing.",
      -    "properties": {
      -      "cheapest_link": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "cheapest_name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "cheapest_total": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "count": {
      -        "anyOf": [
      -          {
      -            "minimum": 0,
      -            "type": "integer"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "How many properties from this source carried a price. Null when the source did not answer -- zero would read as 'nothing there', which a failed search does not know."
      -      },
      -      "currency": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "The currency THIS row's totals are in. Rows in different currencies are not comparable and nothing is converted."
      -      },
      -      "detail": {
      -        "description": "Plain text for the model to relay to a human.",
      -        "type": "string"
      -      },
      -      "median_total": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "provider": {
      -        "description": "Which source this row is about, e.g. 'booking'.",
      -        "type": "string"
      -      },
      -      "rating_scale": {
      -        "anyOf": [
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "What a review score from this source is out of: 10 on Booking, 5 on Airbnb. Read it before comparing two scores."
      -      },
      -      "retrieved_at": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When these rows were read, taken from the rows themselves rather than from when this answer was assembled."
      -      },
      -      "search_reason": {
      -        "type": "string"
      -      },
      -      "search_status": {
      -        "description": "'ok': the source answered with priced results. 'empty': it answered and had nothing for that stay -- a real answer. 'degraded': it was asked and could not answer, so count is null and an empty list from it means nothing.",
      -        "enum": [
      -          "ok",
      -          "empty",
      -          "degraded",
      -          "skipped"
      -        ],
      -        "type": "string"
      -      },
      -      "taxes_included": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Whether this source's totals include tax. Null means it has not been established for that source, not that tax is excluded."
      -      },
      -      "top": {
      -        "description": "The cheapest few priced rows from this source.",
      -        "items": {
      -          "additionalProperties": true,
      -          "type": "object"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "provider",
      -      "search_status"
      -    ],
      -    "type": "object"
      -  },
      -  "type": "array"
      -}
    • removedOutput schema / properties / providers_skipped
      Removed value: -{
      -  "description": "Sources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.",
      -  "items": {
      -    "additionalProperties": true,
      -    "properties": {
      -      "detail": {
      -        "type": "string"
      -      },
      -      "provider": {
      -        "type": "string"
      -      },
      -      "reason": {
      -        "description": "'no_key': no RapidAPI key for that source's listing arrived with the call. 'not_subscribed': the key supplied is not subscribed to that listing. 'key_rejected': the key was refused outright.",
      -        "type": "string"
      -      },
      -      "subscribe_url": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "provider",
      -      "reason"
      -    ],
      -    "type": "object"
      -  },
      -  "type": "array"
      -}
    • changedOutput schema / properties / results / description
      Previous value: -"The properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. Each row is the source's own object, passed through. latitude and longitude are the property's WGS84 coordinates in decimal degrees, from the source that answered (Booking.com on Booking rows, Airbnb on Airbnb rows), null when the source publishes none."New value: +"The properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. Each row is the source's own object, passed through. latitude and longitude are the property's WGS84 coordinates in decimal degrees, from Booking.com, null when it publishes none."
  3. Changed2 schema fields changed
    • changedOutput schema / properties / results / description
      Previous value: -"The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'."New value: +"The properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'. Each row is the source's own object, passed through. latitude and longitude are the property's WGS84 coordinates in decimal degrees, from the source that answered (Booking.com on Booking rows, Airbnb on Airbnb rows), null when the source publishes none."
    • addedOutput schema / properties / results / items / properties
      Added value: +{
      +  "latitude": {
      +    "anyOf": [
      +      {
      +        "type": "number"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ]
      +  },
      +  "longitude": {
      +    "anyOf": [
      +      {
      +        "type": "number"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ]
      +  }
      +}
  4. Changed6 schema fields changed
    • changedInput schema / properties / max_searches / description
      Previous value: -"Cap the billed requests this call may make. One stay is one request, so a 30-day range at two lengths is 60; lower this to spend less and the range is sampled evenly across the calendar rather than cut short at the front."New value: +"The billed requests this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- the cap rises to cover a request that size by itself. Set it lower to spend less, or higher (hard maximum 200) for a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front."
    • addedOutput schema / properties / api_usage / properties / hub_requests_billed
      Added value: +{
      +  "description": "How many HTTP requests RapidAPI actually billed. Larger than requests_used_by_this_call when a search failed with a server error and was retried, because the retry is billed too. This is the figure the invoice will show.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / api_usage / properties / requests_used_by_this_call / description
      Added value: +"How many date/destination combinations were searched -- what the answer COVERS."
    • addedOutput schema / properties / search_coverage / properties / stopped_early
      Added value: +{
      +  "description": "Present when something other than the cap ended the fan-out. 'deadline': the call reached its time limit and the remaining combinations were never sent or billed, so the results are real but do not cover the whole range.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / search_status / description
      Previous value: -"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help -- ask for fewer dates or nights, or move to a larger plan."
    • changedOutput schema / properties / search_status / enum
      Previous value: -[
      -  "ok",
      -  "empty",
      -  "partial",
      -  "degraded",
      -  "trial_exhausted"
      -]New value: +[
      +  "ok",
      +  "empty",
      +  "partial",
      +  "degraded",
      +  "trial_exhausted",
      +  "quota_exceeded"
      +]
  5. Changed2 schema fields changed
    • changedOutput schema / properties / search_status / description
      Previous value: -"Date-range searches only. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help."
    • changedOutput schema / properties / search_status / enum
      Previous value: -[
      -  "ok",
      -  "empty",
      -  "partial",
      -  "degraded"
      -]New value: +[
      +  "ok",
      +  "empty",
      +  "partial",
      +  "degraded",
      +  "trial_exhausted"
      +]
  6. Changed24 schema fields changed
    • addedInput schema / properties / checkin_date / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / checkin_date / default
      Added value: +null
    • changedInput schema / properties / checkin_date / description
      Previous value: -"First night of the stay, \"YYYY-MM-DD\"."New value: +"First night of the stay, \"YYYY-MM-DD\". Give this with checkout_date for one stay, or use checkin_date_from plus checkin_date_to for a range of check-in dates."
    • removedInput schema / properties / checkin_date / type
      Removed value: -"string"
    • addedInput schema / properties / checkin_date_from
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "First check-in date of a range, \"YYYY-MM-DD\". Needs checkin_date_to and nights, and prices one stay per check-in date in the range -- the hotel equivalent of the flights date range."
      +}
    • addedInput schema / properties / checkin_date_to
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Last check-in date of the range, \"YYYY-MM-DD\"."
      +}
    • addedInput schema / properties / checkout_date / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / checkout_date / default
      Added value: +null
    • changedInput schema / properties / checkout_date / description
      Previous value: -"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date."New value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date. Give either this or nights, not both."
    • removedInput schema / properties / checkout_date / type
      Removed value: -"string"
    • addedInput schema / properties / max_searches
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Cap the billed requests this call may make. One stay is one request, so a 30-day range at two lengths is 60; lower this to spend less and the range is sampled evenly across the calendar rather than cut short at the front."
      +}
    • addedInput schema / properties / nights
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "items": {
      +        "type": "integer"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "How many nights to stay, as a number (3) or a list ([2, 3, 7]) to price several lengths. Derives the check-out date from each check-in date, so it replaces checkout_date rather than joining it."
      +}
    • addedInput schema / properties / providers
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Which sources to price this stay on, e.g. [\"booking\"], [\"airbnb\"] or [\"booking\", \"airbnb\"]. Defaults to [\"booking\"]. Each source is a separate RapidAPI subscription, so a source you have no key for is not called; it comes back named in providers_skipped with the reason and where to subscribe, rather than silently missing. filters and price_as_seen_from apply to booking only; airbnb takes price_min, price_max and room_types instead, and rows from it carry rating_scale 5 where booking's carry 10."
      +}
    • changedInput schema / required
      Previous value: -[
      -  "destination",
      -  "checkin_date",
      -  "checkout_date"
      -]New value: +[
      +  "destination"
      +]
    • changedOutput schema / description
      Previous value: -"A completed hotel search. The hotels upstream reports no search-status header, so these results carry no search_status field."New value: +"A completed hotel search. A single stay carries no search_status: the hotels upstream reports no search-status header, and one call either answered or raised. A DATE-RANGE search does carry one, derived from the fan-out rather than from the upstream -- some of its stays can fail while others answer, and `results` then holds only the cheapest stay's properties, so `stays` is where the shape of the answer lives."
    • addedOutput schema / properties / caveats
      Added value: +{
      +  "description": "Sentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / cheapest_overall
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "properties": {
      +        "checkin_date": {
      +          "type": "string"
      +        },
      +        "checkout_date": {
      +          "type": "string"
      +        },
      +        "currency": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "nights": {
      +          "anyOf": [
      +            {
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "price_per_night": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "property": {
      +          "anyOf": [
      +            {
      +              "additionalProperties": true,
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
      +        },
      +        "total": {
      +          "type": "number"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "The cheapest stay across everything priced, or null when nothing was. `results` holds this stay's full property list."
      +}
    • addedOutput schema / properties / partial
      Added value: +{
      +  "description": "Present when some stays failed but others were priced. Plain text saying how much of the request the answer covers.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / providers
      Added value: +{
      +  "description": "One entry per source that was called, in the order they were requested. Only present when `providers` named more than the default source.",
      +  "items": {
      +    "additionalProperties": true,
      +    "description": "What one accommodation source answered. Present for every source that was CALLED, whether or not it answered: a source with search_status 'degraded' carries a reason, a null count and no prices, which is not the same answer as a source that found nothing.",
      +    "properties": {
      +      "cheapest_link": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "cheapest_name": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "cheapest_total": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "count": {
      +        "anyOf": [
      +          {
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "How many properties from this source carried a price. Null when the source did not answer -- zero would read as 'nothing there', which a failed search does not know."
      +      },
      +      "currency": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "The currency THIS row's totals are in. Rows in different currencies are not comparable and nothing is converted."
      +      },
      +      "detail": {
      +        "description": "Plain text for the model to relay to a human.",
      +        "type": "string"
      +      },
      +      "median_total": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "provider": {
      +        "description": "Which source this row is about, e.g. 'booking'.",
      +        "type": "string"
      +      },
      +      "rating_scale": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "What a review score from this source is out of: 10 on Booking, 5 on Airbnb. Read it before comparing two scores."
      +      },
      +      "retrieved_at": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When these rows were read, taken from the rows themselves rather than from when this answer was assembled."
      +      },
      +      "search_reason": {
      +        "type": "string"
      +      },
      +      "search_status": {
      +        "description": "'ok': the source answered with priced results. 'empty': it answered and had nothing for that stay -- a real answer. 'degraded': it was asked and could not answer, so count is null and an empty list from it means nothing.",
      +        "enum": [
      +          "ok",
      +          "empty",
      +          "degraded",
      +          "skipped"
      +        ],
      +        "type": "string"
      +      },
      +      "taxes_included": {
      +        "anyOf": [
      +          {
      +            "type": "boolean"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Whether this source's totals include tax. Null means it has not been established for that source, not that tax is excluded."
      +      },
      +      "top": {
      +        "description": "The cheapest few priced rows from this source.",
      +        "items": {
      +          "additionalProperties": true,
      +          "type": "object"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "provider",
      +      "search_status"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / providers_skipped
      Added value: +{
      +  "description": "Sources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.",
      +  "items": {
      +    "additionalProperties": true,
      +    "properties": {
      +      "detail": {
      +        "type": "string"
      +      },
      +      "provider": {
      +        "type": "string"
      +      },
      +      "reason": {
      +        "description": "'no_key': no RapidAPI key for that source's listing arrived with the call. 'not_subscribed': the key supplied is not subscribed to that listing. 'key_rejected': the key was refused outright.",
      +        "type": "string"
      +      },
      +      "subscribe_url": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "provider",
      +      "reason"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / results_for_stay
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Which stay `results` belongs to on a date-range search, or null when nothing was priced. Without it the rows read as 'the search's results' and get quoted against the wrong dates."
      +}
    • addedOutput schema / properties / search_coverage
      Added value: +{
      +  "additionalProperties": true,
      +  "description": "What was actually priced on a date-range search. Present whether or not the request was truncated, so a model can state honestly what its answer rests on.",
      +  "properties": {
      +    "checkin_dates_searched": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "max_searches_per_request": {
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    "note": {
      +      "type": "string"
      +    },
      +    "requested_combinations": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "searched_combinations": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "stays_searched": {
      +      "description": "The exact date pairs priced.",
      +      "items": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "checkin_date": {
      +            "type": "string"
      +          },
      +          "checkout_date": {
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "truncated": {
      +      "description": "True when the request expanded past this call's spend ceiling and was sampled. A stay absent from stays_searched was never priced, which is not the same as having no rooms.",
      +      "type": "boolean"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedOutput schema / properties / search_status
      Added value: +{
      +  "description": "Date-range searches only. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry.",
      +  "enum": [
      +    "ok",
      +    "empty",
      +    "partial",
      +    "degraded"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / stays
      Added value: +{
      +  "description": "One entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it.\n\nRead this rather than inferring coverage from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that.",
      +  "items": {
      +    "additionalProperties": true,
      +    "properties": {
      +      "cheapest": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": true,
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
      +      },
      +      "cheapest_total": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "checkin_date": {
      +        "type": "string"
      +      },
      +      "checkout_date": {
      +        "type": "string"
      +      },
      +      "currency": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "median_total": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Median stay total over this stay's priced properties -- what the date costs generally, next to what its one cheapest room costs."
      +      },
      +      "nights": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "price_per_night": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "cheapest_total divided by nights, rounded."
      +      },
      +      "priced_count": {
      +        "anyOf": [
      +          {
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "How many of those carried a price. The others are not evidence about what the stay costs."
      +      },
      +      "property_count": {
      +        "anyOf": [
      +          {
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Properties returned for this stay. Null when it was not searched or its search errored."
      +      },
      +      "reason": {
      +        "enum": [
      +          "ok",
      +          "no_availability",
      +          "no_price",
      +          "search_failed",
      +          "not_searched"
      +        ],
      +        "type": "string"
      +      },
      +      "search_status": {
      +        "enum": [
      +          "ok",
      +          "empty",
      +          "degraded",
      +          "not_searched"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "checkin_date",
      +      "checkout_date",
      +      "search_status",
      +      "reason"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  7. Changed1 schema field changed
    • changedInput schema / properties / price_as_seen_from / description
      Previous value: -"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. This is what makes rate-parity and geo-pricing checks possible; omit it for a neutral price."New value: +"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. For a rate-parity check hold one named property fixed and call each country a few times, because rates move between calls and one call per country can show a gap that is not there. Omit it for a neutral price."
  8. Changed4 schema fields changed
    • addedOutput schema / description
      Added value: +"A completed hotel search. The hotels upstream reports no search-status header, so these results carry no search_status field."
    • addedOutput schema / properties
      Added value: +{
      +  "api_usage": {
      +    "additionalProperties": true,
      +    "description": "What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed.",
      +    "properties": {
      +      "note": {
      +        "description": "The same figures as a sentence, for the model to relay.",
      +        "type": "string"
      +      },
      +      "plan_requests_limit": {
      +        "type": "integer"
      +      },
      +      "plan_requests_remaining": {
      +        "type": "integer"
      +      },
      +      "requests_used_by_this_call": {
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "applied_filters": {
      +    "description": "Which of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through."
      +  },
      +  "message": {
      +    "type": "string"
      +  },
      +  "needs_api_key": {
      +    "description": "True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it.",
      +    "type": "boolean"
      +  },
      +  "quota_exhausted": {
      +    "description": "True when the caller's RapidAPI plan has no requests left for the current period.",
      +    "type": "boolean"
      +  },
      +  "result_count": {
      +    "minimum": 0,
      +    "type": "integer"
      +  },
      +  "results": {
      +    "description": "The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'.",
      +    "items": {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  "signup_url": {
      +    "description": "Where the caller subscribes or changes plan.",
      +    "type": "string"
      +  }
      +}
    • addedOutput schema / required
      Added value: +[
      +  "results"
      +]
    • addedOutput schema / title
      Added value: +"Hotel search result"
  9. Changed9 schema fields changed
    • addedInput schema / properties / adults / description
      Added value: +"Number of adult guests. Defaults to the upstream default when omitted."
    • addedInput schema / properties / budget_per_night / description
      Added value: +"Only return properties at or below this nightly price, in `currency`."
    • addedInput schema / properties / checkin_date / description
      Added value: +"First night of the stay, \"YYYY-MM-DD\"."
    • addedInput schema / properties / checkout_date / description
      Added value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date."
    • addedInput schema / properties / children / description
      Added value: +"Number of children sharing the room."
    • addedInput schema / properties / currency / description
      Added value: +"ISO currency code for the prices returned, e.g. \"usd\"."
    • addedInput schema / properties / destination / description
      Added value: +"Where to stay, in free text the way a person would say it, e.g. \"Rome\" or \"Tokyo Shibuya\". A city, district, landmark or region all work; no internal location ID is needed."
    • addedInput schema / properties / filters / description
      Added value: +"Property filters to apply, e.g. [\"free_cancellation\", \"breakfast_included\"]. An unknown name is rejected with the list of valid ones rather than being ignored."
    • addedInput schema / properties / price_as_seen_from / description
      Added value: +"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. This is what makes rate-parity and geo-pricing checks possible; omit it for a neutral price."
  10. First observed

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses critical behavior: rates go stale within minutes, current prices require a fresh search, free sign-in allowance is 10 searches per day, and oversized ranges are refused before running. It also explains sampling under max_searches and that caller-owned keys automatically raise the cap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but mostly front-loaded and information-dense, with core purpose and return shape stated first. Some sentences repeat details already present in the schema, so it is slightly less concise than it could be for a 15-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complex parameter set, output schema, and annotations, the description is complete enough to call the tool correctly. It covers freshness, caps, free-tier constraints, sampling behavior, and the difference between fixed and range searches.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains limit, nights, max_searches, price_as_seen_from, and most other parameters in detail. The description adds useful mode-level context, especially for multi-stay range pricing and parity checks, but much of its parameter explanation duplicates the schema rather than adding new semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: live Booking.com hotel availability and nightly prices for a destination and date range. The scope is distinct from a name lookup, so an agent can distinguish it from find_hotel_by_name without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear operational context for fixed-date searches, date-range searches, parity checks, and free-tier limits. It does not explicitly say to use find_hotel_by_name when a property name is already known, so sibling routing is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.