Skip to content

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_TEMPLATE and ADMISSION.
  • The offer's id, for example from offers(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.

graphql
query CalendarDates($id: ID!, $span: TsRange!, $quantity: Int!) {
  bookingCalendarAvailability(type: EVENT_TEMPLATE, id: $id, span: $span, quantity: $quantity) {
    dates {
      value
      remainingQuota
      currentPriceValue
    }
  }
}
json
{ "id": "42", "span": "[2026-10-01,2026-11-01)", "quantity": 3 }
json
{
  "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.

graphql
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
              }
            }
          }
        }
      }
    }
  }
}
json
{ "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.

json
{
  "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:

graphql
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

ProblemWhat to check
The calendar returns no datesThe 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 slotsUse 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 errorThe slot filled up in the meantime. Reload the slots and let the customer choose again.