Skip to main content
This guide ties the endpoint pages together into one guest journey. It tells you what to call, what to show the guest, what to save, and what to do when something expires or fails. For a hands-on run of the same flow, see the Quickstart. For every ID and token, see the IDs and Tokens Cheat Sheet.
Sandbox only has hotels in 12 test cities, such as Dubai, Paris, Tokyo and Bangkok. Start every test from Sandbox autocomplete for one of those cities, and use IDs from the same environment.

The flow at a glance

Step by step

For each step: what to call, what to show the guest, what to persist, and what can expire.

1. Destination and nationality

3. Live prices

4. Property detail and rooms

5. Prebook

6. Create the booking

7. Track the result

8. Cancel

Time limits

Error recovery

Work from the guest’s point of view: tell them what happened, then return them to the earliest step that can fix it. Full code list: Errors & Retries.

Build the guest experience

Price states

Search prices are shopping data. Decide what to show from price.status, never from amount alone. price.amount is the whole-stay total in cents of price.currency. It is null unless the status is live or recent, so never show 0. It can go down while you poll when a cheaper supplier answers. Show the indicative nature of the price (“from”) until the guest reaches prebook, where the price is confirmed.

Room cards

Rooms arrive as family objects (a room type) with variants (one bed configuration each). Offers from several suppliers sit on the same family or variant. Draw one card per family:
  • Header: the family name and details (photos, size, description, amenities), labelled with details.source.
  • Variants: show beds, bedrooms, max_guests and smoking only from the variant object. null means unknown.
  • Offer rows: one per offer, with the price from pricing.native_ledger.totals[0].total, meal plan label, cancellation badge from cancellation.refundability and the free-cancellation deadline. Offers listed under bed_assignment.suppliers go under “Bed type assigned by the hotel”.
  • Always show each row’s own provider_room beds and maximum guests.
  • Show must_display notices before the guest books, and payable_at_property as “pay at hotel”.
  • A later event can replace a family: store families by unifystays_room_id and overwrite.
Grouping only decides where an offer is drawn. You always book the supplier’s own offer with booking_token and room_allocation_id. Never use a room or family ID as a booking key. See Get Hotel Rooms for the client logic and card keys for multi-room searches.

Checkout

  • Build the form from the prebook booking_requirements: label, control from value_type, allowed_values, constraints, and who answers from scope and room_allocation_ids. Ask once, after prebook.
  • For each room create one ADULT per adult and one minor per child age (age 0 or 1 is INFANT, 2 and over is CHILD). Exactly one guest in the booking is the lead guest.
  • Show a countdown to offer.lifecycle.expires_at, and the full cancellation policy and notices before the guest pays.
  • Unifystays does not collect payment from the guest. payment.payer and payment.collection_timing tell you who is charged and when.

Booking status screens

Multi-room bookings

A rooms request holds one occupancy object per room. The chosen offer, its prebook and the booking all contain one allocation per requested room. Keep two rooms with the same name as two entries: their room_allocation_id values differ. Never mix rooms from different offers. In Create Booking, send every prebook allocation exactly once; array order does not matter.
A search price or a room option is not a booking guarantee. Prebook right before booking, and book with the prebooking_id and offer_id of that same prebook response.

Next

Read Caching Strategy, Errors & Retries and the Launch Checklist.