GET /v2/availability searches for bookable units and returns offers. An offer is a priced combination of a unit (room) and a rate plan for your dates and occupancy. You need an offer ID to create a booking.
Choosing what to search
Every request needs check_in and check_out (YYYY-MM-DD). It also needs one of the following:
| Search by | Parameters | Notes |
|---|---|---|
| Property IDs | property_ids | Up to 50 IDs. page and limit are ignored. |
| Location | lat, lng, radius | radius is in metres, default 2000. Paginate with page (from 0) and limit (max 50, default 10). |
To pass a list (property_ids, occupancy), either repeat the parameter or comma-separate the values. These are equivalent:
?property_ids=ABCDEFGH&property_ids=IJKLMNOP
?property_ids=ABCDEFGH,IJKLMNOP
Coordinates. lat is latitude (−90 to 90) and lng is longitude (−180 to 180). For example, London is lat=51.5072&lng=-0.1276. Swapping them is a common reason for empty results.
Occupancy: units, adults and children
Use the occupancy parameter. It describes every unit you want, and each unit can have its own guests.
Grammar
| Symbol | Meaning |
|---|---|
, | separates units |
- | separates a unit's adults from its children's ages |
; | separates children's ages within one unit |
So one unit is written <adults> or <adults>-<age>;<age>;…, and several units are joined with ,.
Examples
occupancy= | Units | Meaning |
|---|---|---|
2 | 1 | 2 adults |
2,1,3 | 3 | Unit 1: 2 adults · Unit 2: 1 adult · Unit 3: 3 adults |
2-6 | 1 | 2 adults + 1 child aged 6 |
2-6;3 | 1 | 2 adults + 2 children aged 6 and 3 |
2-6,3 | 2 | Unit 1: 2 adults + child aged 6 · Unit 2: 3 adults |
2-16,1-16;16 | 2 | Unit 1: 2 adults + child aged 16 · Unit 2: 1 adult + 2 children aged 16 |
Common mistake:
occupancy=2;1is not two units; it is rejected as invalid. For two units with 2 adults and 1 adult, sendoccupancy=2,1.
; is a legal character in a query string. If your HTTP client encodes it as %3B, that works too.
Children's ages
- Send an age for every child, from
0to16. - Many hotels price children and adults the same. If you don't know a child's age, use
16.
adults, children, number_of_units
adults, children, number_of_unitsThese are supported, but we recommend occupancy
The older form below searches for identical units:
adults=2&children=0&number_of_units=3 # 3 units, each with 2 adults
- With
children=N, every child is assumed to be 16. - When
occupancyis present,adults,childrenandnumber_of_unitsare ignored. - Use
occupancyfor new integrations.number_of_unitsmight be removed in a future release.
Limits
- Guests per unit: decided by each hotel's unit configuration (maximum occupancy of the unit), not by the API. If a unit type can't fit the guests you asked for, it isn't returned.
- Units per booking: up to 9. All units in one booking must be at the same property.
The response
{
"data": {
"offers": [ { "id": "9131b7c8-…", "property_id": "6Y1227GD", "unit_id": "782L7VG9", "rate_plan_id": "P8XW5MG2",
"price": { "...": "..." }, "occupancy_has_offer": [true, false], "payment_method": "CREDIT_CARD", "...": "..." } ],
"number_of_units": { "6Y1227GD": { "782L7VG9": 2 } },
"rate_plans": { "P8XW5MG2": { "...": "cancellation and no-show policies, meals, ..." } },
"total_properties": 1
}
}| Field | Meaning |
|---|---|
offers | One entry per bookable unit + rate plan. Price fields are explained in Pricing and taxes. |
rate_plans | The policies (cancellation, no-show, meals) of every rate plan referenced by an offer, keyed by rate_plan_id. Use these policies, not the ones on /properties. |
number_of_units | property_id → unit_id → units available. This is also how many times one offer ID can be used in a single booking. |
total_properties | For location searches: how many properties matched, for pagination. The last page is reached when total_properties <= (page + 1) * limit. For ID searches it equals the number of IDs sent. |
Multi-unit searches and occupancy_has_offer
occupancy_has_offerWhen you search for several units, each offer says which of the requested units it can fit. occupancy_has_offer is a list of booleans in the same order as the units in occupancy.
For example, with occupancy=2,1:
| Offer | occupancy_has_offer | Can be used for |
|---|---|---|
| A | [true, true] | either unit |
| B | [true, false] | the 2-adult unit only |
| C | [false, true] | the 1-adult unit only |
To book both units, create one reservation per unit. Pick, for each unit, an offer whose flag at that unit's position is true. You can use the same offer for both (offer A, if number_of_units allows 2) or mix offers (B + C).
For single-unit searches the field is always [true].
Why is my result empty?
Work through this list:
- No contract. You only see properties you have an active contract or partnership with.
GET /propertieslists them. - Corporate rates need
corporate_profile_id. Corporate negotiated rates are only returned when you send thecorporate_profile_idthey belong to. Without it you get public rates only. See Corporate profiles. - Rate restrictions. Rates might have restrictions set by the hotel such as minimum Length of Stay, Closed on Arrival etc.
- Occupancy doesn't fit. No unit type at the property can hold the guests you asked for.
- Sold out. The property has no inventory for those dates.
- Coordinates swapped, or the radius is too small.
- Appropriate key. Make sure the production key is used when performing requests.
Other parameters
| Parameter | Effect |
|---|---|
lowest=true | Return only the cheapest offer per property. |
price_breakdown=true | Add a per-night breakdown to every offer price. |
separate_rates_per_payment=true | If a rate plan supports both PAY_NOW and PAY_AT_PROPERTY, return one offer per payment mode instead of a single offer listing both. |
corporate_profile_id | Include rates negotiated for that corporate. |
Performance
- Before checkout, re-check the offer you are about to book with
GET /offers/{id}?live_check=true(Offers). That way you can be sure the offer is not expired.