3. API Reference
Conventions
Every transaction in the Stays API follows the same wire rules. Learn them once here; the endpoint pages assume them throughout. This page mirrors the "generic conventions" chapter of the reference documentation this API is contract-compatible with, so an integrator moving across finds the same guarantees in the same places.
Response envelope
Every response — success or failure — uses the same JSON envelope:
{ "code": 0, "msg": "success", "data": {} }| Field | Type | Meaning |
|---|---|---|
| code | integer | Result code. 0 = success; anything else is a business error code (see Error handling). |
| msg | string | Human-readable result message. |
| data | object | The business payload. Present on success; errors carry only code and msg. |
The body code is authoritative. Some business failures are delivered with HTTP 200, so check code rather than the transport status alone:
- A booking whose rate moved between CheckAvail and the commit returns HTTP 200 with
code100001111(ARI Changed) — not an HTTP error. - CheckAvail itself answers a sold-out room with
code0and carries the outcome indata.status, never as an error code.
The inverse also holds: a 4xx/5xx does not by itself tell you which class of failure fired — read the code to distinguish a parameter error from a system error.
Data formats
| Item | Format | Example |
|---|---|---|
| Dates (check-in, check-out) | yyyy-MM-dd (ISO) |
2026-01-01 |
| Timestamps (booking time, cancel time, windows) | RFC 3339 / ISO 8601 | 2026-01-01T10:00:00Z |
Webhook eventTime |
Unix milliseconds | 1704067200000 |
countryCode, residencyCode, nationalityCode, Market |
ISO 3166-1 alpha-2 | AE, US |
Currency (body and Currency header) |
ISO 4217 | USD |
Language header |
IETF BCP 47 | en, en-US (default en-US) |
Every request is POST with a JSON body and Content-Type: application/json.
Localised strings (I18N)
Human-readable text (names, addresses, board names) is returned as a localised object whose keys are the fixed language codes the contract declares:
{
"en": "Jumeirah Beach Hotel",
"zh": "朱美拉海滩酒店",
"ar": "فندق جميرا بيتش"
}en is the default system language; zh (Chinese) and ar (Arabic) complete the set. The Language request header (BCP 47, default en-US) selects the content language where the API returns a single string.
Occupancy semantics
roomOccupancies is one entry per room, each carrying adultCount and optional childrenAges:
[{ "adultCount": 2, "childrenAges": [5, 7] }, { "adultCount": 1 }]- Children are declared per room in
childrenAges, one entry per child, accepted from age 0 with no upper bound. There is no fixed infant band — handling follows each hotel's and supplier's policy. - Multiple rooms with different occupancies: submit the highest adult count across all rooms, applied to every room. Rooms with 1 adult and 2 adults → send
adultCount: 2for both; children are always sent individually.
Sessions
HotelList returns a sessionId in data.basic.sessionId. Carry it as the Session-Id header on every later call in the flow — it is required on HotelList, HotelRates, CheckAvail, Book and Cancel.
The session carries context from search to booking, providing pricing consistency and availability stability. A ratePkgId is only resolvable inside the session that produced it; using a stale or mismatched session is one cause of 404 not found.
Idempotency
Book is idempotent on customerReferenceNo: retrying with the same value returns the original order instead of creating a second one. A UUID is the usual choice. This is what makes timeout recovery safe — never re-issue a Book with a fresh reference to "try again"; reuse the original one and confirm via QueryOrders.
Need help?
Questions about these conventions or your integration: integrations@ttdbooking.com Full documentation: developer.ttdbooking.com/hotel-api/docs

