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| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/bookings | bookings:read |
| POST | /api/v1/bookings | bookings:write (returns 501 — see below) |
| GET | /api/v1/bookings/{id} | bookings:read |
The Booking object:
| Field | Type | Notes |
|---|---|---|
id | string | Opaque booking id. |
bookingNumber | string | Per-tenant human-friendly reference, e.g. "TR-2026-00001". Not a counter. |
tripId | string | The trip this booking is against. |
tripVersion | integer | Pinned at booking creation. |
status | enum | Lifecycle state, see above. |
totalRetailCents | integer | Frozen at booking creation. |
applicationFeeCents | integer | Tourical platform fee, ≤ €40 cap. |
currency | string | ISO 4217. |
travelerName | string | null | Captured at checkout; null on bookings created before it was collected. |
travelerEmail | string | null | As above. |
confirmedAt | ISO 8601 | null | When the booking moved to confirmed. |
cancelledAt | ISO 8601 | null | |
departureId | string | null | For published trips with multi-departure rosters. |
departureStartDate | ISO 8601 | null | |
departureEndDate | ISO 8601 | null | |
createdAt | ISO 8601 | |
updatedAt | ISO 8601 |
GET /api/v1/bookings
List bookings in the tenant. Cursor-paginated.
Required scope — bookings:read
Query parameters
| Name | Type | Default | Notes |
|---|---|---|---|
limit | integer | 50 | Max 100. |
cursor | string | — | From a previous response. |
status | string | — | Filter to one lifecycle state. |
tripId | string | — | 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.
/api/v1/bookingsTry itRequests 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
limitcursorstatustripIdGET /api/v1/bookingsGET /api/v1/bookings/{id}
Fetch a single booking by id.
Required scope — bookings:read
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
id | string | yes | Booking id. |
Response 200
{ "data": /* Booking */ }Errors — 401, 403 scope-required, 404 not-found.
/api/v1/bookings/{id}Try itRequests 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
idrequiredGET /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
| Field | Type | Required | Notes |
|---|---|---|---|
tripId | string | yes | Must reference a trip published in your tenant. |
travelerName | string | yes | 1–200 chars. |
travelerEmail | string | yes | Valid 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.
/api/v1/bookingsTry itDocuments 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
