Title
Create new category
Edit page index title
Edit category
Edit link
Holds, Bookings & Cancellations
Managing the transaction lifecycle involves securing inventory temporarily (Holds), confirming the final transaction (Bookings), and handling any necessary reversals (Cancellations).
Holds
Building the capability to handle Holds in your integration is mandatory, as the majority of Suppliers require a Hold prior to booking when a rate is set to holdable = true.
However, sending a Hold request is not required for every single transaction. If a rate is set to holdable = false, the Hold step is unnecessary.
To simplify your development, you can handle this in one of two ways:
- Conditional Logic: Build logic in your system to only send a Hold request when the selected rate returns
holdable = true. - Always Send: Send a Hold request for every transaction regardless of the flag. If the rate is actually
holdable = false, Travel Curious will automatically intercept the request, safely bypass the Supplier's hold process, and return a successful response so your flow doesn't break.
The Hold is placed to ensure the product stays available until the customer is ready to check out the cart or commit to the booking. The hold request relies on a combination of parameters to successfully lock inventory. While you must include the supplierId, productId, rateId, priceId, and travelerType to define the specifics of the experience, these fields alone do not guarantee capacity. To actually ensure the product is available and successfully secure the inventory for your guests, these values must be used in conjunction with the availabilityId and the specific at time.
When creating a Hold, you have the option to provide your own valid UUID in the id field of the request. If an ID is not included in your Create Hold request, the system will automatically generate and assign a holdId. The Hold will remain active until it is released automatically according to the configured expires time. It is best practice to issue a hold release when the guest abandons the cart or closes the browser. Please note that hold durations cannot be extended via the API; if a hold expires, you must initiate a new Hold request.
Please note that hold expiration times (the duration a hold remains active before expiring) vary between Supplier and Reseller systems. It is important to discuss these expiration windows prior to binding the channels to determine a duration that suits both the Supplier and the Reseller.
xxxxxxxxxx Booking Questions in Holds v1.3
If the Rate includes bookingQuestions[] with phase: hold, those answers must be submitted as part of the Hold request body. Required questions (required: true) will cause the Hold request to fail if they are omitted.
Include an answers array at the Hold level for questions with scope: booking, or within each traveler context for questions with scope: guest:
xxxxxxxxxx{ "hold": { "items": [...], "answers": [ { "questionId": "q_123", "answer": "Window seat" }, { "questionId": "q_456", "answer": true } ] }}For questions with scope: guest and phase: hold, submit the answer inside the relevant items[].ext or traveler block (refer to the API Reference for the exact structure for your Supplier).
See Booking Questions for full details on question types, dependencies, and PII handling.
Releasing a Hold
Releasing a Hold frees the reserved inventory immediately, making it available for other customers rather than waiting for automatic expiry. Always release the Hold when:
- A guest abandons their cart or closes the browser
- A Booking attempt fails and the guest does not retry
Bookings
Whenever Travel Curious receives a Booking request from the Reseller, it evaluates the holdable boolean located on the selected Rate object.
- If
holdable = true: The booking request MUST include theholdId. Without it, the booking request will fail. Travel Curious will verify that the details of the booking match the details of the hold exactly. The details of the booking cannot be modified from the hold (e.g., changing the number of travelers or the price). Modifying these details will cause the booking to fail, even if the requested inventory is otherwise available. - If
holdable = false(or no hold was made): AholdIdis not required and should not be provided. Because noholdIdis present in the request, the system presumes no hold was made and skips hold validation entirely. The Reseller simply submits the Booking request directly with the necessarysupplierId,productId,rateId,priceId,availabilityId,startTime, andtravelerdetails.
Assuming the booking request is correctly formatted, matches the hold request data (if a hold was required), includes any mandatory BookingAnswers, and is accepted by the Supplier's reservation system, the booking is successful and a unique booking ID (id) is returned.
Key fields:
holdId- Required whenholdable: true. Ties the Booking to the reserved inventory slot.resellerBookingRef- Your own internal reference ID. Store this alongside the Travel Curiousbooking.idfor reconciliation.customer- The lead customer's contact details, used for voucher delivery and operator manifests.traveler- used to provide multiple guest detailstraveler.isLead- Exactly one traveler per Booking Item must haveisLead: true.traveler.type- Must match theageBandfrom the Rate price used in this item.
xxxxxxxxxx// Click to edit codeTicket and Barcode Delivery
All barcodes and ticket data in a booking confirmation are returned under the tickets[] array, regardless of whether the booking contains one ticket or many.
Delivery method: Check product.deliveryMethod in the Product response to determine how tickets are structured for this specific integration:
This value varies by Supplier and integration. Always read it from the response rather than assuming one model applies universally.
Delayed ticket delivery: For some integrations, the booking confirmation will not contain an actual scannable barcode. Instead, tickets[] may carry an instruction message such as "Your tickets will be delivered no later than 2 weeks prior to the performance". This happens when the Supplier or ticketing system sends tickets directly to the customer's email address - either automatically at confirmation or at a defined point before the event date. In this case, the guest should be informed that their tickets will arrive separately and that the booking confirmation email from you serves as proof of purchase in the meantime.
Booking statuses
| Status | Description |
|---|---|
OPEN | Confirmed and active |
PENDING | Awaiting asynchronous processing from the Supplier system |
REDEEMED | All items have been scanned or checked in |
CANCELLED | Booking is voided |
FAILED | Booking was not successful |
OLCI_PENDING | Awaiting online check-in |
If the Product has instantConfirmation: false, the initial status will be PENDING. Poll GET /bookings/{booking_id} at a reasonable interval until the status resolves to OPEN or FAILED.
HTTP 202 and Pending Bookings
For most integrations, a successful Booking returns HTTP 200 with status OPEN and tickets included. However, if the Product has instantConfirmation: false - typically high-volume systems or live event ticketing platforms - the API may return HTTP 202 Accepted with status PENDING instead.
A 202 response means Travel Curious has received and queued the booking request, but the Supplier or ticketing system has not yet confirmed it. Tickets are not returned in a 202 response. Here is the full flow:
- You send the Booking request and receive
HTTP 202withbooking.status: PENDINGand notickets[] - Travel Curious forwards the request to the Supplier or ticketing system and waits for confirmation
- You poll
GET /v1.3/bookings/{booking_id}at regular intervals to check whether the status has changed - Once the Supplier confirms, Travel Curious updates the booking status from
PENDINGtoOPENand the full ticket data becomes available in the GET response - Resolution time varies; it may be within a few minutes, or up to 24 hours before the event date depending on the Supplier
Polling guidance: Stop polling once status is OPEN or FAILED. Surface a "booking in progress" state to the guest during this window rather than showing an error or forcing them to retry.
Pending booking support is agreed as part of the channel binding process. If you are connecting to live event or high-volume Suppliers, confirm with your Travel Curious Integration Manager whether 202 responses are expected for that integration.
Booking Questions in Bookings v1.3
Questions with phase: booking must be submitted in the Booking request body, not the Hold. These are questions where the answer can only be finalized at the time of purchase confirmation.
xxxxxxxxxx{ "booking": { "holdId": "...", "customer": {...}, "items": [...], "answers": [ { "questionId": "q_789", "answer": "Gluten-free" } ] }}Cancellations
In order to Cancel a Booking, the booking_id is required.
When sending a cancellation request, you can provide a
reasonenum (CUSTOMER,SUPPLIER,FRAUD,OTHER) and can optionally includereasonDetailsto help expedite any manual review processes.
Please note that some Suppliers do not accept cancellations initiated by the customer or Reseller for products via the API; their products or rates are set to cancelable = false. In this case, if reservations need to be cancelled anyway, a manual business process between Supplier and Reseller needs to be agreed upon. However, if a Supplier cancels an event and a Reseller needs to cancel multiple reservations, Travel Curious can help find a solution to let the Reseller cancel via the API so that the guest refunds can be carried out between Supplier and Reseller and reported.
Please remember to implement extension maps to the Hold, Booking and Cancellation requests.
Questions? We'd love to hear them. Contact Travel Curious Support.