curl "$UNIFYSTAYS_BASE_URL/hotels/prebook" \
-X POST \
-H "content-type: application/json" \
-H "x-api-key: $UNIFYSTAYS_API_KEY" \
-H "X-Unifystays-Contract-Version: 1" \
-d '{
"hotel_id": "13553916",
"booking_token": "bq7.quote-id.0.signature"
}'
{
"contract_version": "1",
"success": true,
"message": "Pre-booking completed. Option is available and ready for booking.",
"data": {
"prebooking_id": "pbq7.prebook-id.signature",
"offer": {
"offer_id": "off_65db5f20d91b47d3a73d834dfa44c50e",
"revision": 2,
"offer_family_id": null,
"supersedes_offer_id": "off_92b941fda86b4ad698044ab35152eaa5",
"provider_code": "RATEHAWK",
"quote_context": {
"hotel": {
"id": "13553916",
"name": "Example Hotel",
"address": "Example Road",
"city": null,
"state": null,
"country": null,
"postal_code": null,
"latitude": null,
"longitude": null,
"timezone": null
},
"check_in": "2026-10-12",
"check_out": "2026-10-15",
"nights": 3,
"rooms": [{ "adults": 2, "child_ages": [] }],
"residency": "IN",
"nationality": "IN",
"language": "en"
},
"lifecycle": { "stage": "PREBOOK", "quoted_at": "2026-09-02T10:05:00.000Z", "expires_at": "2026-09-02T10:15:00.000Z", "prebook_required": false, "price_guaranteed": true, "availability": "AVAILABLE", "rooms_remaining": 2, "on_request": false },
"rooms": [],
"pricing": {},
"payment": {},
"commercial": {},
"cancellation": {},
"booking_requirements": [
{
"requirement_id": "br_title_all_guests_1",
"code": "TITLE",
"label": "Title",
"value_type": "ENUM",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": ["MR", "MRS", "MS", "MISS", "MASTER", "OTHER"],
"description": null,
"constraints": null
},
{
"requirement_id": "br_first_name_all_guests_2",
"code": "FIRST_NAME",
"label": "First name",
"value_type": "TEXT",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_last_name_all_guests_3",
"code": "LAST_NAME",
"label": "Last name",
"value_type": "TEXT",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_email_lead_guest_4",
"code": "EMAIL",
"label": "Email",
"value_type": "EMAIL",
"scope": "LEAD_GUEST",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_phone_lead_guest_5",
"code": "PHONE",
"label": "Phone",
"value_type": "PHONE",
"scope": "LEAD_GUEST",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
}
],
"nightly_prices": [],
"promotions": [],
"benefits": [],
"notices": []
},
"revalidation": {
"result": "UNCHANGED",
"decision": "READY_TO_BOOK",
"changes": []
}
}
}
Search & hotels
Prebook a Room
Idempotently refresh the complete selected HotelOffer before booking.
POST
/
hotels
/
prebook
curl "$UNIFYSTAYS_BASE_URL/hotels/prebook" \
-X POST \
-H "content-type: application/json" \
-H "x-api-key: $UNIFYSTAYS_API_KEY" \
-H "X-Unifystays-Contract-Version: 1" \
-d '{
"hotel_id": "13553916",
"booking_token": "bq7.quote-id.0.signature"
}'
{
"contract_version": "1",
"success": true,
"message": "Pre-booking completed. Option is available and ready for booking.",
"data": {
"prebooking_id": "pbq7.prebook-id.signature",
"offer": {
"offer_id": "off_65db5f20d91b47d3a73d834dfa44c50e",
"revision": 2,
"offer_family_id": null,
"supersedes_offer_id": "off_92b941fda86b4ad698044ab35152eaa5",
"provider_code": "RATEHAWK",
"quote_context": {
"hotel": {
"id": "13553916",
"name": "Example Hotel",
"address": "Example Road",
"city": null,
"state": null,
"country": null,
"postal_code": null,
"latitude": null,
"longitude": null,
"timezone": null
},
"check_in": "2026-10-12",
"check_out": "2026-10-15",
"nights": 3,
"rooms": [{ "adults": 2, "child_ages": [] }],
"residency": "IN",
"nationality": "IN",
"language": "en"
},
"lifecycle": { "stage": "PREBOOK", "quoted_at": "2026-09-02T10:05:00.000Z", "expires_at": "2026-09-02T10:15:00.000Z", "prebook_required": false, "price_guaranteed": true, "availability": "AVAILABLE", "rooms_remaining": 2, "on_request": false },
"rooms": [],
"pricing": {},
"payment": {},
"commercial": {},
"cancellation": {},
"booking_requirements": [
{
"requirement_id": "br_title_all_guests_1",
"code": "TITLE",
"label": "Title",
"value_type": "ENUM",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": ["MR", "MRS", "MS", "MISS", "MASTER", "OTHER"],
"description": null,
"constraints": null
},
{
"requirement_id": "br_first_name_all_guests_2",
"code": "FIRST_NAME",
"label": "First name",
"value_type": "TEXT",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_last_name_all_guests_3",
"code": "LAST_NAME",
"label": "Last name",
"value_type": "TEXT",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_email_lead_guest_4",
"code": "EMAIL",
"label": "Email",
"value_type": "EMAIL",
"scope": "LEAD_GUEST",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_phone_lead_guest_5",
"code": "PHONE",
"label": "Phone",
"value_type": "PHONE",
"scope": "LEAD_GUEST",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
}
],
"nightly_prices": [],
"promotions": [],
"benefits": [],
"notices": []
},
"revalidation": {
"result": "UNCHANGED",
"decision": "READY_TO_BOOK",
"changes": []
}
}
}
Prebook is the supplier-backed recheck immediately before booking. Send the
hotel and opaque token from the same streamed offer. Missing
Prebook is automatically idempotent by organization and booking-token
identity. Concurrent duplicate calls return
Prebook always issues a new
X-Unifystays-Contract-Version defaults to 1.
curl "$UNIFYSTAYS_BASE_URL/hotels/prebook" \
-X POST \
-H "content-type: application/json" \
-H "x-api-key: $UNIFYSTAYS_API_KEY" \
-H "X-Unifystays-Contract-Version: 1" \
-d '{
"hotel_id": "13553916",
"booking_token": "bq7.quote-id.0.signature"
}'
PREBOOK_IN_PROGRESS with
Retry-After. Completed repeats return the exact stored result.
{
"contract_version": "1",
"success": true,
"message": "Pre-booking completed. Option is available and ready for booking.",
"data": {
"prebooking_id": "pbq7.prebook-id.signature",
"offer": {
"offer_id": "off_65db5f20d91b47d3a73d834dfa44c50e",
"revision": 2,
"offer_family_id": null,
"supersedes_offer_id": "off_92b941fda86b4ad698044ab35152eaa5",
"provider_code": "RATEHAWK",
"quote_context": {
"hotel": {
"id": "13553916",
"name": "Example Hotel",
"address": "Example Road",
"city": null,
"state": null,
"country": null,
"postal_code": null,
"latitude": null,
"longitude": null,
"timezone": null
},
"check_in": "2026-10-12",
"check_out": "2026-10-15",
"nights": 3,
"rooms": [{ "adults": 2, "child_ages": [] }],
"residency": "IN",
"nationality": "IN",
"language": "en"
},
"lifecycle": { "stage": "PREBOOK", "quoted_at": "2026-09-02T10:05:00.000Z", "expires_at": "2026-09-02T10:15:00.000Z", "prebook_required": false, "price_guaranteed": true, "availability": "AVAILABLE", "rooms_remaining": 2, "on_request": false },
"rooms": [],
"pricing": {},
"payment": {},
"commercial": {},
"cancellation": {},
"booking_requirements": [
{
"requirement_id": "br_title_all_guests_1",
"code": "TITLE",
"label": "Title",
"value_type": "ENUM",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": ["MR", "MRS", "MS", "MISS", "MASTER", "OTHER"],
"description": null,
"constraints": null
},
{
"requirement_id": "br_first_name_all_guests_2",
"code": "FIRST_NAME",
"label": "First name",
"value_type": "TEXT",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_last_name_all_guests_3",
"code": "LAST_NAME",
"label": "Last name",
"value_type": "TEXT",
"scope": "ALL_GUESTS",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_email_lead_guest_4",
"code": "EMAIL",
"label": "Email",
"value_type": "EMAIL",
"scope": "LEAD_GUEST",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
},
{
"requirement_id": "br_phone_lead_guest_5",
"code": "PHONE",
"label": "Phone",
"value_type": "PHONE",
"scope": "LEAD_GUEST",
"room_allocation_ids": [],
"required": true,
"allowed_values": [],
"description": null,
"constraints": null
}
],
"nightly_prices": [],
"promotions": [],
"benefits": [],
"notices": []
},
"revalidation": {
"result": "UNCHANGED",
"decision": "READY_TO_BOOK",
"changes": []
}
}
}
offer_id, increments revision, and sets
supersedes_offer_id. It atomically rebuilds pricing, rooms, meals, payment,
cancellation, notices, benefits, availability, and commercial terms. Never
merge individual values into the rooms-stage offer.
The refreshed pricing.native_ledger is the authoritative supplier/property
obligation. usd_ledger contains the same logical lines converted completely to
USD, or is null when any required FX rate is unavailable. Commercial display,
net, gross, commission and selling-price fields are informational and must not be
added to either ledger. Pricing and the structured provider-room fallback are
replaced as one atomic offer snapshot.
Identity and tax-document requirements, including passport or PAN, appear in
booking_requirements. Mandatory legal or supplier instructions appear in
notices; there is no separate public compliance object.
Treat booking_requirements as a server-driven form schema. Display label,
choose a control from value_type, apply allowed_values and constraints,
and collect answers only for guests selected by scope and
room_allocation_ids. At booking, echo the exact requirement_id with the
answer value. New certified requirement codes do not require a booking request
schema change.
Booking must send accepted_offer_id equal to data.offer.offer_id, plus the
returned prebooking_id. revalidation.decision is the only action signal:
READY_TO_BOOK can proceed, RECONFIRMATION_REQUIRED must be shown and
accepted, and NOT_BOOKABLE must return the customer to room selection.
revalidation.changes[] contains only semantic differences. Each change has a
stable category/code, impact, scope, description, and optional native/USD money
change. A currency-set change is NOT_COMPARABLE; unavailable FX produces a
null difference_usd, never a fabricated zero. The complete refreshed
data.offer is always authoritative—do not merge it with the rooms-stage offer.Authorizations
Environment-specific API key created in the Unifystays portal
Headers
Hotel API contract version. Missing defaults to v1.
Available options:
1 Body
application/json
Unifystays hotel id currently shown to the user. It must match the hotel bound to booking_token.
Example:
"13553916"
Short signed booking token from rooms API option (booking_token). Provider routing and prebook context are resolved server-side from Postgres context.
Example:
"bq7.Y0QxTmtKc21Wbmk.7.6zI4D6fUEw2jVv7KQdM4Kw"
Requested response language (for example en).
Example:
"en"