Manage a booking
Travellers reach this page from checkout, from the link in their emails, or by typing their reference and email. It opens the booking with one proof (personal data): the token, the lead’s email, or the traveller’s session.
Open the booking
Section titled “Open the booking”curl "https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE?token=TOKEN_FROM_THE_LINK" \ -H "Tp-Publishable-Key: $TP_KEY"const res = await fetch("https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE?token=TOKEN_FROM_THE_LINK", { headers: { "Tp-Publishable-Key": process.env.TP_KEY!, },})const answer = await res.json()Answer: 200 OK
{ "ref": "TP-4HZQ-8MNE", "status": "confirmed", "start": "2026-11-14T15:00", "pax": 3, "hold_expires_at": null, "pending_expires_at": null, "trip": { "title": "Desert safari with BBQ dinner", "option": "Shared 4WD, afternoon", "product_id": "5b1f0c3e-8d2a-4f6b-9c41-2e7a9d0b6f13" }, "payment": { "method": "pay_on_arrival", "status": "pay_on_arrival", "due_at": null, "on_arrival": { "amount": 18000, "currency": "USD" }, "bank": null, "receipt": null, "link": null }, "details": { "status": "not_needed", "due_at": null, "needed": 0, "complete": 0, "overdue": false }, "cancellation": null, "rejection_reason": null, "quote": { "option_id": "9e4c2a71-3b5d-4e8f-a1c6-7d20f5b93e48", "lines": [ { "kind": "unit", "ref": "1c7e9b42-6a3f-4d85-b0e2-58f4a1c9d736", "label": "Adult", "qty": 2, "unit_price": { "amount": 6500, "currency": "USD" }, "original_unit_price": null, "total": { "amount": 13000, "currency": "USD" }, "pay_at": "upfront", "included": false, "vehicle": null }, { "kind": "unit", "ref": "2d8fac53-7b40-4e96-81f3-69a5b2dae847", "label": "Child (3-11)", "qty": 1, "unit_price": { "amount": 5000, "currency": "USD" }, "original_unit_price": null, "total": { "amount": 5000, "currency": "USD" }, "pay_at": "upfront", "included": false, "vehicle": null } ], "totals": { "due_now": { "amount": 18000, "currency": "USD" }, "pay_locally": [], "grand_total": { "amount": 18000, "currency": "USD" } }, "confirmation": "instant", "pending_expires_at": null, "remaining": 14, "pax": 3, "pairing": false, "vehicles": [], "fx": { "base": "USD", "quote": "USD", "rate": "1", "rate_id": "0f6d2b8e-4c1a-4e5f-9b3d-7a8c6e2f1d90", "as_of": "2026-10-01T00:00:00.000Z" }, "policy": { "name": "Flexible", "tiers": [ { "from_days": 1, "to_days": null, "refund_pct": 100 }, { "from_days": 0, "to_days": 0, "refund_pct": 0 } ], "preset": "flexible" }, "pickup": null }}With the reference and the lead’s email instead of the token, the booking
opens too, but can’t be cancelled. A wrong token or email gets the same
404 as a reference that doesn’t exist, so a guess learns nothing:
curl "https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE?email=someone.else%40example.com" \ -H "Tp-Publishable-Key: $TP_KEY"const res = await fetch("https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE?email=someone.else%40example.com", { headers: { "Tp-Publishable-Key": process.env.TP_KEY!, },})const answer = await res.json()Answer: 404 Not Found
{ "type": "about:blank", "title": "Not Found", "status": 404, "code": "NotFound", "detail": "No booking TP-4HZQ-8MNE.", "entity": "booking"}Show its status, the trip as sold (trip), the start, the price lines
and the payment. A booking never carries the lead’s contact details.
Cancel
Section titled “Cancel”Show what cancelling now gives back first, from the policy the booking was sold with:
curl "https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE/refund?token=TOKEN_FROM_THE_LINK" \ -H "Tp-Publishable-Key: $TP_KEY"const res = await fetch("https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE/refund?token=TOKEN_FROM_THE_LINK", { headers: { "Tp-Publishable-Key": process.env.TP_KEY!, },})const answer = await res.json()Answer: 200 OK
{ "days_before": 12, "refund_pct": 100, "refund": { "amount": 18000, "currency": "USD" }, "paid": { "amount": 18000, "currency": "USD" }}Then cancel with the token, or with the traveller’s session if they are signed in. The places go back on sale, and the traveller is emailed.
curl -X POST "https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE/cancel?token=TOKEN_FROM_THE_LINK" \ -H "Tp-Publishable-Key: $TP_KEY" \ -H "Content-Type: application/json" \ -d '{ "reason": "Our flight was moved."}'const res = await fetch("https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE/cancel?token=TOKEN_FROM_THE_LINK", { method: "POST", headers: { "Tp-Publishable-Key": process.env.TP_KEY!, "Content-Type": "application/json", }, body: JSON.stringify({ "reason": "Our flight was moved." }),})const answer = await res.json()Answer: 200 OK (shortened)
{ "ref": "TP-4HZQ-8MNE", "status": "cancelled", "cancellation": { "by": "traveller", "refund_pct": 100, "refund": { "amount": 18000, "currency": "USD" } }}Cancelling twice is 409 Conflict; read the booking again to show its
state.
Travellers’ details
Section titled “Travellers’ details”When the trip needs details after booking, the booking’s details says how
many are done and when the rest are due.
GET /v1/public/bookings/{ref}/travellershas the form: what the trip asks, and the travellers given so far, with sensitive fields masked.PUT /v1/public/bookings/{ref}/travellers/{position}saves one traveller, 1 being the lead.POST /v1/public/bookings/{ref}/travellers/{position}/linkmakes a link for the lead to forward, so each traveller fills in their own.
A transfer’s receipt
Section titled “A transfer’s receipt”For a booking paid by bank transfer, the traveller can send the receipt:
POST /v1/public/bookings/{ref}/receipt, with the file itself as the body
(a PDF, or a JPEG, PNG or WebP image, up to 10 MB). The payment becomes
proof_submitted for the seller to check.
A mistyped email
Section titled “A mistyped email”Right after booking, the confirmation page can fix the lead’s email or
phone, sending the contact_token from checkout as token:
POST /v1/public/bookings/{ref}/contact-changes. A six-digit code is
emailed (to the new address for an email, to the booking’s email for a
phone), and POST /v1/public/bookings/{ref}/contact-changes/{id}/confirm
with that code makes the change. The traveller can fix the email this way
for 30 minutes after booking, by default; after that, the seller corrects
it.
Travellers with an account
Section titled “Travellers with an account”A traveller can sign in on your site with an emailed link
(POST /v1/public/auth/sign-in-link, then POST /v1/public/auth/verify)
or a passkey, once the seller has set your
page to manage a booking: sign-in
belongs to that site. Signed in, GET /v1/public/me/bookings lists their bookings,
and their session opens and cancels them without a token. Pass the session
cookie on from your server as you received it.