Show dates and time slots with the Booking API
- Last verified
- Last verified Sep 23, 2026
Use this guide when customers choose a date and time before booking, for example for timed entry or recurring tours. It shows a calendar month, lists the time slots of the chosen day and adds a slot to the cart. Events with one fixed date skip the calendar; see Book a dated event.
Before you start
- An event template or admission with published time slots in the shop. In the Booking API, these offers have the types
EVENT_TEMPLATEandADMISSION. - The offer's
id, for example fromoffers(posId: "auto", offerableTypes: [EVENT_TEMPLATE]). - The request headers described in the Booking API quickstart.
Show the calendar
Request the bookable dates for the visible month. span is a half-open range: the first day is included and the last day is not. Pass the number of places the customer wants as quantity.
query CalendarDates($id: ID!, $span: TsRange!, $quantity: Int!) {
bookingCalendarAvailability(type: EVENT_TEMPLATE, id: $id, span: $span, quantity: $quantity) {
dates {
value
remainingQuota
currentPriceValue
}
}
}{ "id": "42", "span": "[2026-10-01,2026-11-01)", "quantity": 3 }{
"data": {
"bookingCalendarAvailability": {
"dates": [
{ "value": "2026-10-07", "remainingQuota": "50", "currentPriceValue": { "amount": 2000, "currency": "EUR" } },
{ "value": "2026-10-14", "remainingQuota": "12", "currentPriceValue": { "amount": 2500, "currency": "EUR" } }
]
}
}
}Each entry is a date with at least one bookable slot. remainingQuota is the number of places left on that date and currentPriceValue is the lowest price that day, which you can show as "from" pricing. Use ADMISSION as type for admissions.
List the time slots of a day
When the customer selects a date, request that day's slots. Pass the day from midnight to midnight in the offer's time zone, converted to UTC, and use spanOperator: CONTAINS_START to return the slots that start within it. Read the time zone from the offer's timeZone field.
query TimeSlots($id: ID!, $day: TsRange!, $quantity: Int!) {
offer(id: $id, type: EVENT_TEMPLATE, posId: "auto") {
... on EventTemplate {
timeZone
potentialEvents(posId: "auto", span: $day, spanOperator: CONTAINS_START, quantity: $quantity) {
edges {
node {
span
remainingQuota
priceRules(posId: "auto") {
id
priceCategory {
nameTranslated
}
product {
currentPriceValue
}
}
}
}
}
}
}
}{ "id": "42", "day": "[2026-10-06T22:00:00Z,2026-10-07T22:00:00Z)", "quantity": 3 }This example is 7 October 2026 in the Europe/Berlin time zone.
Each slot has a span in UTC, for example [2026-10-07T08:00:00Z,2026-10-07T08:30:00Z). Display the start in the offer's timeZone. The slot's priceRules are the price categories the customer can choose, such as adult and child tickets, with their prices.
Add the slot to the cart
Add the slot with its span as offerableSpan. Add one pricing per chosen price category, with the price rule's id.
{
"input": {
"offerableType": "EVENT_TEMPLATE",
"offerableId": "42",
"offerableSpan": "[2026-10-07T08:00:00Z,2026-10-07T08:30:00Z)",
"pricings": [
{ "quantity": 2, "priceOriginType": "PRICE_RULE", "priceOriginId": "1" },
{ "quantity": 1, "priceOriginType": "PRICE_RULE", "priceOriginId": "2" }
]
}
}Send these variables with the AddToCart mutation from the quickstart. Add requestId with the cart token when the cart already exists.
Book a dated event
Events with one fixed date and time have the type EVENT. Read the event's price categories and add them without offerableSpan:
query EventPrices($id: ID!) {
offer(id: $id, type: EVENT, posId: "auto") {
... on Event {
id
span
remainingQuota
priceRules(posId: "auto") {
id
priceCategory {
nameTranslated
}
product {
currentPriceValue
}
}
}
}
}Then call AddToCart with offerableType: "EVENT", the event's id and a pricing per chosen price category.
Troubleshooting
| Problem | What to check |
|---|---|
| The calendar returns no dates | The offer is published for the shop and has time slots in the requested range. The range end is excluded. |
| A date shows places but no slots | Use the same quantity for dates and slots, and a day range from midnight to midnight in the offer's time zone, converted to UTC. |
| Adding the slot fails with an availability error | The slot filled up in the meantime. Reload the slots and let the customer choose again. |