Show dates and time slots with the Booking API
- Last verified
- Last verified Sep 29, 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; the Booking API quickstart shows how to sell them.
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. type is EVENT_TEMPLATE or ADMISSION. 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($type: OfferableTypeEnum!, $id: ID!, $span: TsRange!, $quantity: Int!) {
bookingCalendarAvailability(type: $type, id: $id, span: $span, quantity: $quantity) {
dates {
value
remainingQuota
currentPriceValue
}
}
}{ "type": "EVENT_TEMPLATE", "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.
- The dates are returned in date order.
remainingQuotais a number sent as a string."2147483647"means the offer has no place limit; do not show it as a count.
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($type: OfferableTypeEnum!, $id: ID!, $day: TsRange!, $quantity: Int!) {
offer(id: $id, type: $type, posId: "auto") {
... on Admission {
timeZone
priceRules(posId: "auto") {
id
priceCategory {
nameTranslated
}
product {
currentPriceValue
}
}
potentialEvents(posId: "auto", span: $day, spanOperator: CONTAINS_START, quantity: $quantity) {
edges {
node {
span
remainingQuota
}
}
}
}
... 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
}
}
}
}
}
}
}
}{ "type": "EVENT_TEMPLATE", "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 price categories the customer can choose, such as adult and child tickets, come from priceRules:
- For an event template, each slot has its own
priceRules. - For an admission, the
priceRulesbelong to the admission and apply to every slot; the slots themselves have none.
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. For an admission, use offerableType: "ADMISSION".
{
"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. The returned totalGrossValue can be higher than the sum of the prices when the venue charges fees.
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. |