Property/getBookingOffers
PMS v1 facade method. Returns the priced, bookable offers a property can honour for a given search (dates, occupancy, promo code), one row per room × rate × placement. This is the same call the public booking widget uses on the search results page — the facade lets your PMS reach the same engine that answers real guests.
Cutover status: shadow-ready. The method is registered in the QC
facade with translator + link builder both ported. Live cut-over is
per-api_user, driven from qc_v1_cutover — see the
PMS v1 facade overview.
Request
GET https://api.quendoo.com/api/pms/v1/property/getBookingOffers
?api_key=…
&bm_code=hotelname
&date_from=2027-01-15
&nights=3
&guests[0][adults]=2
&guests[0][children_by_ages][]=6
&promo_code=SUMMER25
¤cy=EUR
Query params
| Param | Type | Required | Notes |
|---|---|---|---|
api_key |
string | yes | Your legacy PMS v1 api-key. Property scope is derived from it. |
bm_code |
string | yes | The active booking_buttons.url_key on the property — legacy calls it the booking module code. |
date_from |
YYYY-MM-DD |
yes | Check-in date. |
nights |
int | yes | Length of stay. date_to = date_from + nights (checkout is next-morning-of). |
guests[i][adults] |
int | yes | Adults for the i-th room in the search. Repeat guests[i] per room. |
guests[i][children_by_ages][] |
int[] | no | Children ages for the i-th room. Empty if no children. Each age >= 0. |
promo_code |
string | no | Applies at pricing time; stacked according to promotion rules. Missing = no promo. |
currency |
string | no | 3-letter ISO. Missing = the booking button's provider currency is used. |
Errors
| Status | message |
When |
|---|---|---|
| 400 | Bad request data! |
Any of bm_code / date_from / nights>0 / guests[] are missing or empty. |
| 400 | Bad request data for the 'guests'->'adults' param! |
An entry in guests[] has adults <= 0. |
| 400 | Bad request data for the 'guests' param! |
guests[i] or its children_by_ages is not an array. |
| 400 | Bad request data for the 'guests'->'children_by_ages'->'age' param! |
A child age is negative. |
| 404 | Booking module '{bm_code}' not found or inactive. |
No active booking_buttons row on the property with that url_key. |
| 404 | Property owner not found. |
The property has no owner row — a configuration state, not a data-entry error. |
Every string above is byte-identical to what legacy returns.
Response
{
"data": [
{
"per_room": false,
"sell_type": "P",
"room_id": 4211,
"room_name": "Double Deluxe Sea View",
"rate_id": 985,
"rate_name": "Standard B&B",
"price": 288.00,
"currency": "EUR",
"accommodation_name": "2 adult on regular bed, 1 child 4-10 years old on extra bed",
"link": "https://book.hotelname.com/search/?dates=2027-01-15~2027-01-18&guests=…"
}
]
}
Field-by-field
| Field | Meaning |
|---|---|
per_room |
true when the rate is priced per room (headline price is the whole room); false when priced per person / per occupancy. |
sell_type |
Legacy short code — R per_room, P per_person, O per_occupancy. |
room_id |
Legacy property_rooms.id — same id you get in getRoomsDetails. |
room_name |
The room's localised name at the request's active locale. |
rate_id |
Legacy rates.id. |
rate_name |
The rate plan's localised name. |
price |
Stay total in currency, rounded to two decimals. |
currency |
Effective currency — the ?currency= you asked for, or the button's provider currency when omitted. |
accommodation_name |
Human-readable placement string composed from the guest layout (see below). |
link |
Deep link into the public booking widget with the same search prefilled — dates, guests, currency, promo. Partners with a custom booking domain get a URL on that domain; others get a relative path (/{bm_code}/search/?…). |
accommodation_name composition
For per-room rates the string reads the room's bed layout —
{qty} adult on regular bed, {qty} adult on extra bed, … — and
suffixes (max room occupancy, accommodation per room).
For per-person / per-occupancy rates the string walks the
placement one line per bed slot:
{qty} adult on regular bed, {qty} child {from-age}-{to-age} years old on extra bed.
Both strings are HTML-escaped. The suffix on the per-room variant is appended after the escape — same order as legacy.
Notes
- Zero rows is a legal response — it means no rate on any room can house the requested guest layout for those dates. Do not distinguish it from "the property is closed"; the widget itself uses the same envelope in both cases.
- The engine deduplicates variants; a room with multiple rate plans emits one row per (room, rate, placement).
linkis opaque. Do not parse it — the query-string layout is a legacy detail we may compress.- Locale defaults to the property's default. Callers passing an explicit locale should use the same header their other PMS v1 calls use — the facade honours it unchanged.