TouricalDevelopers
Endpoints

Bookings

Read the bookings against your published trips. Write capture is deliberately limited in v1.

A booking is a traveller's purchase of a trip. Each booking holds a frozen snapshot of the trip at booking time and walks through a status lifecycle.

payment_pending → deposit_paid → confirmed → trip_in_progress → completed
                                          → cancelled
                                          → refunded
                                          → disputed
MethodPathScope
GET/api/v1/bookingsbookings:read
POST/api/v1/bookingsbookings:write (returns 501 — see below)
GET/api/v1/bookings/{id}bookings:read

The Booking object:

FieldTypeNotes
idstringOpaque booking id.
bookingNumberstringPer-tenant human-friendly reference, e.g. "TR-2026-00001". Not a counter.
tripIdstringThe trip this booking is against.
tripVersionintegerPinned at booking creation.
statusenumLifecycle state, see above.
totalRetailCentsintegerFrozen at booking creation.
applicationFeeCentsintegerTourical platform fee, ≤ €40 cap.
currencystringISO 4217.
travelerNamestring | nullCaptured at checkout; null on bookings created before it was collected.
travelerEmailstring | nullAs above.
confirmedAtISO 8601 | nullWhen the booking moved to confirmed.
cancelledAtISO 8601 | null
departureIdstring | nullFor published trips with multi-departure rosters.
departureStartDateISO 8601 | null
departureEndDateISO 8601 | null
createdAtISO 8601
updatedAtISO 8601

GET /api/v1/bookings

List bookings in the tenant. Cursor-paginated.

Required scope — bookings:read

Query parameters

NameTypeDefaultNotes
limitinteger50Max 100.
cursorstring—From a previous response.
statusstring—Filter to one lifecycle state.
tripIdstring—Filter to bookings against one trip.

Response 200

{
  "data": [ /* Booking[] */ ],
  "meta": { "cursor": "bk_a1b2c3" | null, "hasMore": true | false }
}

Errors — 401 unauthorized, 403 (scope-required, or plan-required when the plan has no API access), 429 rate-limited.

GET/api/v1/bookingsTry it

Requests are proxied through this docs site so CORS doesn't block the call. Use a sandbox token if you don't want test calls hitting live data.

Query parameters

limit
cursor
status
tripId
GET /api/v1/bookings

GET /api/v1/bookings/{id}

Fetch a single booking by id.

Required scope — bookings:read

Path parameters

NameTypeRequiredNotes
idstringyesBooking id.

Response 200

{ "data": /* Booking */ }

Errors — 401, 403 scope-required, 404 not-found.

GET/api/v1/bookings/{id}Try it

Requests are proxied through this docs site so CORS doesn't block the call. Use a sandbox token if you don't want test calls hitting live data.

Path parameters

idrequired
GET /api/v1/bookings/{id}

POST /api/v1/bookings

Documents the future booking-creation contract. Returns 501 today.

Direct booking creation via the API requires Stripe Connect PaymentIntent capture, which lives behind the storefront. Until that is exposed on the API surface, this endpoint accepts the future request shape and returns a 501 problem with a next.checkoutUrl pointing the traveller at the storefront.

Required scope — bookings:write

Request body

FieldTypeRequiredNotes
tripIdstringyesMust reference a trip published in your tenant.
travelerNamestringyes1–200 chars.
travelerEmailstringyesValid email, ≤ 320 chars.

Response 501 — application/problem+json

{
  "type": "https://developers.tourical.com/errors/booking-create-not-supported",
  "title": "Booking creation requires the storefront",
  "status": 501,
  "detail": "Direct booking creation via the public API isn't supported yet. Redirect the traveller to the storefront URL below to capture payment.",
  "next": {
    "checkoutUrl": "https://app.tourical.com/tour/<trip-slug>/checkout?email=…"
  }
}

Errors before 501 — 401 unauthorized, 403 (scope-required, or plan-required when the plan has no API access), 404 not-found (unknown tripId), 422 validation-failed (Trip must be published before bookings can be created via the API.), 429 rate-limited.

POST/api/v1/bookingsTry it

Documents the future contract. Returns 501 with a checkout redirect URL.

Requests are proxied through this docs site so CORS doesn't block the call. Use a sandbox token if you don't want test calls hitting live data.

POST /api/v1/bookings

On this page