Get Booking Slots
About
The bookingSlots query retrieves available time slots for a booking product on a specific date. This query is essential for building the booking UI — when a customer selects a date, you use this query to fetch and display the available slots they can choose from before adding the product to cart.
Why This Query Is Needed
When adding a booking product to the cart, the booking input requires a specific time slot (e.g., "slot": "12:00 PM - 01:00 PM"). But the available slots depend on the product's configuration (duration, break time, operating hours) and the selected date (day-of-week availability, existing bookings). This query resolves all of that and returns only the slots that are actually available for selection.
The typical flow is:
- Query the product to get
bookingProductIdfrom thebookingProductsrelationship - Customer selects a date on the frontend
- Query
bookingSlotswith thebookingProductIdand selected date to get available slots - Customer picks a slot from the results
- Add to cart using the selected slot value in the
bookingJSON
The shape of the response depends on the product's booking type — Default, Appointment, and Table return a flat list, Rental returns time-range groups, and Event returns nothing. See Response by Booking Type.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | Int! | Yes | The bookingProductId — obtained from the product query's bookingProducts relationship (not the product ID). |
date | String! | Yes | The date to check for available slots in YYYY-MM-DD format. |
Response Fields
Every entry is the same object type. Which fields carry a value depends on the booking type — the unused ones come back null.
| Field | Type | Populated for | Description |
|---|---|---|---|
slotId | String | All | Identifier for the entry. Flat types repeat the timestamp range here; grouped rental entries carry the group's index. |
from | String | Flat types | Slot start. Appointment and Table return a time ("10:00 AM"); Default returns a full day and time ("Thu, 13 Aug 08:00 AM"). |
to | String | Flat types | Slot end, in the same format as from. |
timestamp | String | Flat types | Unix range as "from-to", e.g. "1786595400-1786599000". |
qty | String | Appointment, Table | Bookings still available for the slot. null for Default. |
time | String | Rental | Label of the time-range group, e.g. "08:00 AM - 11:59 PM". |
slots | Iterable | Rental | JSON array of the individual hourly slots in the group, each an object of from, to, timestamp, and qty. |
Select slots on its own — it is a JSON value, so it returns whole and cannot take a sub-selection. Do not select id: the entries have no standalone endpoint, so asking for it fails the whole entry.
Response by Booking Type
| Booking Type | Response Structure | Fields to Query |
|---|---|---|
| Default | Flat — one entry spanning the product's whole availability window | slotId, from, to, timestamp |
| Appointment | Flat — one entry per bookable slot | slotId, from, to, timestamp, qty |
| Table | Flat — one entry per bookable sitting | slotId, from, to, timestamp, qty |
| Rental | Grouped by time range, hourly slots nested inside | slotId, time, slots |
| Event | Empty array — availability is sold as tickets | — |
Rental returns the grouped hourly shape whichever renting type the product uses, daily included. Read the ticket fields on the product's bookingProducts node for events.
How to Get the bookingProductId
The id parameter for this query is not the product ID — it is the bookingProductId from the product's bookingProducts relationship. Query it like this:
query getProduct($id: ID!) {
product(id: $id) {
id
name
bookingProducts {
edges {
node {
_id # This is the bookingProductId to use
type # default, appointment, rental, table, event
}
}
}
}
}Use the _id value from bookingProducts.edges.node as the id argument in the bookingSlots query.
Common Use Cases
Build a Date + Slot Picker (Non-Rental)
# Step 1: User selects a date, fetch available slots
query {
bookingSlots(id: 3, date: "2026-08-13") {
from
to
timestamp
qty
}
}Then use the from and to values to construct the slot field for the add-to-cart mutation:
{
"booking": "{\"type\":\"appointment\",\"date\":\"2026-08-13\",\"slot\":\"10:00 AM - 10:45 AM\"}"
}Build an Hourly Rental Slot Picker
# Fetch grouped rental slots
query {
bookingSlots(id: 4, date: "2026-08-13") {
time
slots
}
}Display the time groups as headers and individual slots as selectable options. Then use the selected slot for add-to-cart:
{
"booking": "{\"type\":\"rental\",\"renting_type\":\"hourly\",\"date\":\"2026-08-13\",\"slot\":\"12:00 PM - 01:00 PM\"}"
}Best Practices
- Use the
bookingProductId, not the product ID — theidargument takes the_idfrom thebookingProductsrelationship - Check for empty results — an empty array means no slots are available on that date; prompt for a different one
- Check
qtywhere it applies — Appointment and Table slots carry aqty; hide any slot whoseqtyis0. Default slots returnqtyasnull, so there is nothing to test. - Handle both structures — read the product's booking
typeto know whether to expect flat slots or grouped rental groups - Refresh on date change — re-query whenever the customer picks a different date
Related Resources
- Single Product - Get product details including
bookingProductsrelationship - Add to Cart - Add booking product to cart with selected slot

