Idempotency & safe bookings
A booking is played once. This page describes the mechanisms that protect you from duplicates and uncertain bookings.
clientReference: mandatory and unique
Every booking carries your reference (clientReference, e.g. PARTNER-2026-000481):
- It is mandatory in
POST /v1/{code}/bookings. - It is unique per partner: replaying the same request with the same
clientReferencereturns the same booking (200 OK) with theX-Idempotent-Replay: trueheader — no second booking is created, no second charge is made. - A new
clientReferencewith the samerateKeycreates a new booking (if the rate is still guaranteed).
A duplicate returns the existing booking
# 1st call → 201 Created, reference: BPG-2026-000123
# identical 2nd call → 200 OK, reference: BPG-2026-000123, X-Idempotent-Replay: true
Generate your clientReference before the call and keep it: it lets you
recover a booking after a timeout with no risk of double booking.
Retry rules
| Operation | Retry allowed? |
|---|---|
POST /bookings | Never a “fresh” call: replay the same request with the same clientReference |
POST /checkrate, POST /availability | Yes (business read, no side effects) |
GET * (hotels, bookings, voucher…) | Yes, a single retry on error or timeout |
POST /bookings/{ref}/cancel | Idempotent by nature: replaying returns the current cancellation state |
Price guaranteed for 10 minutes
After a successful checkrate, the price is guaranteed for 10 minutes (expiresAt in the response):
- Book within this window with the verified
rateKey: the price will not move. - After
expiresAt, therateKeyis rejected (422 rate_expired): search again, thencheckrateagain.
Recommended timeouts
| Call | Recommended client timeout |
|---|---|
Reads (hotels, reference, bookings…) | 15 s |
availability, checkrate | 25 s |
bookings (create) | 45 s |
On a booking creation timeout, never retry with a new clientReference: replay the same request, or check the booking exists via GET /v1/{code}/bookings?from=…&to=….