Scheduling
Variant-aware availability, slot picking, bookings, reschedules, and cancellations. As of ` 0.44.30`, slot fetches accept a `variant_id`; different service variants have different durations, prices, and slot availability. `duration_minutes` on ` getAvailableSlots` was removed; the server derives it from the variant.
List services
const r = await client.scheduling.getServices()
if (!r.ok) {
console.error(r.error.code, r.error.message)
return
}
for (const service of r.value) {
console.log(service.id, service.name, service.duration_minutes)
}
const single = await client.scheduling.getService('svc_xxx')Get available slots (variant-aware)
Pass variant_id when the service has variants; slot times and capacities depend on which variant the customer is booking.
const r = await client.scheduling.getAvailableSlots({
service_id: 'svc_haircut',
date: '2026-05-08',
variant_id: 'var_haircut_premium', // 60-minute variant
participant_count: 1,
})
if (!r.ok) return
for (const slot of r.value) {
console.log(slot.start_time, slot.end_time, slot.capacity_available)
console.log(slot.available_staff)
}Get a multi-day availability range
const r = await client.scheduling.getServiceAvailability({
service_id: 'svc_haircut',
start_date: '2026-05-08',
end_date: '2026-05-15',
variant_id: 'var_haircut_premium',
location_id: 'loc_main',
participant_count: 1,
})
if (r.ok) {
for (const day of r.value.availability) {
console.log(day.date, day.has_availability, day.slots.length)
}
}Confirm a slot is still free
Before checkout, double-check the slot is bookable. checkSlotAvailability still accepts duration_minutes for ad-hoc service durations.
const r = await client.scheduling.checkSlotAvailability({
service_id: 'svc_haircut',
slot_time: '2026-05-08T15:00:00Z',
duration_minutes: 60,
participant_count: 1,
})
if (r.ok) {
if (!r.value.available) {
console.warn('Slot taken:', r.value.reason)
}
}Bookings
const single = await client.scheduling.getBooking('bk_xxx') // BookingWithDetails
const all = await client.scheduling.getCustomerBookings() // current user
const ofUser = await client.scheduling.getCustomerBookings('cus_xxx')
const upcoming = await client.scheduling.getUpcomingBookings()
const past = await client.scheduling.getPastBookings(20)Cancel a booking
const r = await client.scheduling.cancelBooking({
booking_id: 'bk_xxx',
reason: 'customer_request',
}, {
idempotencyKey: 'cancel-bk_xxx-once', // optional, auto-generated otherwise
})
if (!r.ok) {
console.error(r.error.code, r.error.message)
return
}
console.log(r.value.message)Reschedule a booking
Reschedules target an order line item, not the booking row directly. Pass the order_id and line_item_id from the original booking.
const r = await client.scheduling.rescheduleBooking({
order_id: 'ord_xxx',
line_item_id: 'li_xxx',
new_start_time: '2026-05-09T10:00:00Z',
new_end_time: '2026-05-09T11:00:00Z',
new_staff_id: 'staff_yyy', // optional
reason: 'customer_preference', // optional
reschedule_type: 'customer', // 'customer' | 'business' | 'system'
})
if (r.ok) {
console.log(r.value.staff_changed, r.value.fee_charged)
}Convenience helpers
const next = await client.scheduling.getNextAvailableSlot('svc_haircut')
if (next.ok && next.value) {
console.log(next.value.start_time)
}
const has = await client.scheduling.hasAvailabilityOn('svc_haircut', '2026-05-08')
if (has.ok) {
console.log(has.value) // true | false
}getAvailableSlots input
| Field | Type | Notes |
|---|---|---|
service_id | string | Required. |
date | string | Required. YYYY-MM-DD. |
variant_id | string | Variant-aware lookup. Different durations / prices. |
participant_count | number | For group services. |
Method reference
| Method | Returns |
|---|---|
getServices() | Result<Service[]> |
getService(id) | Result<Service | null> |
getAvailableSlots(input) | Result<AvailableSlot[]> |
getServiceAvailability(params) | Result<ServiceAvailabilityResult> |
checkSlotAvailability(input) | Result<CheckSlotAvailabilityResult> |
getBooking(id) | Result<BookingWithDetails> |
getCustomerBookings(customerId?) | Result<CustomerBooking[]> |
getUpcomingBookings() | Result<CustomerBooking[]> |
getPastBookings(limit?) | Result<CustomerBooking[]> |
cancelBooking(input, opts?) | Result<CancelBookingResult> |
rescheduleBooking(input, opts?) | Result<RescheduleBookingResult> |
getNextAvailableSlot(serviceId, fromDate?) | Result<AvailableSlot | null> |
hasAvailabilityOn(serviceId, date) | Result<boolean> |
Related
Orders
List, retrieve, and cancel orders. Anonymous orders carry a short-lived `bill_token` that the SDK persists for you, so guest order lookups Just Work after checkout.
Subscriptions
Read and manage the customer's recurring orders. Subscriptions are created during checkout when a billing plan is attached to a cart item; this surface lets you list them, pause / resume them, skip the next renewal, and cancel.