Booking
Services, providers, bookings, availability, and checkout
The Booking module provides complete booking functionality including services, providers, availability, and checkout.
Services
Services represent bookable offerings (haircuts, consultations, classes, etc.).
Create Service
/v1/businesses/{businessId}/services sdk.booking.createService() Create a new bookable service.
const result = await sdk.booking.createService({
key: 'haircut',
blocks: [
{
key: 'description',
type: 'TEXT',
content: {
body: { en: 'Professional haircut service' }
}
}
],
taxonomies: [
{ taxonomyId: 'tax_category', entryId: 'entry_hair' }
],
status: 'ACTIVE'
});Parameters
| Name | Type | Description |
|---|---|---|
key required | string | Unique service key identifier |
blocks optional | Block[] | Content blocks for service details |
taxonomies optional | TaxonomyEntry[] | Taxonomy assignments |
status optional | DRAFT | ACTIVE | ARCHIVED | Service status |
Get Service
/v1/businesses/{businessId}/services/{id} sdk.booking.getService() Retrieve a service by ID or slug.
// By ID
const result = await sdk.booking.getService({
id: 'svc_xyz789'
});
// By slug (locale-aware)
const result = await sdk.booking.getService({
slug: 'haircut'
});
Parameters
| Name | Type | Description |
|---|---|---|
id optional | string | Service ID (use this OR slug) |
slug optional | string | Service slug (locale-aware lookup) |
List Services
/v1/businesses/{businessId}/services sdk.booking.getServices() List all services with filtering.
const result = await sdk.booking.getServices({
ids: ['svc_1', 'svc_2'],
query: 'haircut',
statuses: ['ACTIVE'],
sortField: 'createdAt',
sortDirection: 'desc',
cursor: null,
limit: 20
});
result.items.forEach(service => {
console.log(service.key);
});Parameters
| Name | Type | Description |
|---|---|---|
ids optional | string[] | Filter by specific service IDs |
query optional | string | Search query |
statuses optional | string[] | Filter by statuses |
taxonomyQuery optional | any[] | Filter by taxonomy entries |
sortField optional | string | Sort field |
sortDirection optional | asc | desc | Sort direction |
cursor optional | string | Pagination cursor |
limit optional | number | Items per page |
Update Service
/v1/businesses/{businessId}/services/{id} sdk.booking.updateService() await sdk.booking.updateService({
id: 'svc_xyz789',
key: 'premium-haircut',
status: 'ACTIVE'
});
Parameters
| Name | Type | Description |
|---|---|---|
id required | string | Service ID to update |
key optional | string | Service key identifier |
blocks optional | Block[] | Content blocks |
taxonomies optional | TaxonomyEntry[] | Taxonomy assignments |
status optional | DRAFT | ACTIVE | ARCHIVED | Service status |
Delete Service
/v1/businesses/{businessId}/services/{id} sdk.booking.deleteService() await sdk.booking.deleteService({
id: 'svc_xyz789'
});
Providers
Providers are staff members who perform services.
Create Provider
/v1/businesses/{businessId}/providers sdk.booking.createProvider() const result = await sdk.booking.createProvider({
key: 'sarah-johnson',
blocks: [
{
key: 'bio',
type: 'TEXT',
content: {
body: { en: 'Senior stylist with 10 years experience' }
}
},
{
key: 'image',
type: 'IMAGE',
content: {
mediaId: 'media_sarah123'
}
}
],
status: 'ACTIVE'
});Parameters
| Name | Type | Description |
|---|---|---|
key required | string | Unique provider key identifier |
audienceIds optional | string[] | Audience IDs for access control |
blocks optional | Block[] | Content blocks (bio, image, etc.) |
taxonomies optional | TaxonomyEntry[] | Taxonomy assignments |
status optional | DRAFT | ACTIVE | ARCHIVED | Provider status |
Get Provider
/v1/businesses/{businessId}/providers/{id} sdk.booking.getProvider() // By ID
const result = await sdk.booking.getProvider({
id: 'prv_abc123'
});
// By slug
const result = await sdk.booking.getProvider({
slug: 'sarah-johnson'
});
Parameters
| Name | Type | Description |
|---|---|---|
id optional | string | Provider ID (use this OR slug) |
slug optional | string | Provider slug (locale-aware lookup) |
List Providers
/v1/businesses/{businessId}/providers sdk.booking.getProviders() const result = await sdk.booking.getProviders({
serviceId: 'svc_haircut',
ids: ['prv_1', 'prv_2'],
query: 'sarah',
statuses: ['ACTIVE'],
sortField: 'createdAt',
sortDirection: 'desc',
cursor: null,
limit: 20
});
result.items.forEach(provider => {
console.log(provider.key, provider.status);
});Parameters
| Name | Type | Description |
|---|---|---|
serviceId optional | string | Filter by service |
ids optional | string[] | Filter by specific provider IDs |
query optional | string | Search query |
statuses optional | string[] | Filter by statuses |
taxonomyQuery optional | any[] | Filter by taxonomy entries |
sortField optional | string | Sort field |
sortDirection optional | asc | desc | Sort direction |
createdAtFrom optional | string | Filter by creation date |
createdAtTo optional | string | Filter by creation date |
cursor optional | string | Pagination cursor |
limit optional | number | Items per page |
Update Provider
/v1/businesses/{businessId}/providers/{id} sdk.booking.updateProvider() await sdk.booking.updateProvider({
id: 'prv_abc123',
key: 'sarah-johnson-senior',
status: 'ACTIVE'
});
Parameters
| Name | Type | Description |
|---|---|---|
id required | string | Provider ID to update |
key optional | string | Provider key identifier |
audienceIds optional | string[] | Audience IDs for access control |
blocks optional | Block[] | Content blocks |
taxonomies optional | TaxonomyEntry[] | Taxonomy assignments |
status optional | DRAFT | ACTIVE | ARCHIVED | Provider status |
Delete Provider
/v1/businesses/{businessId}/providers/{id} sdk.booking.deleteProvider() await sdk.booking.deleteProvider({
id: 'prv_abc123'
});
Service Providers
Service providers link a provider to a service with working time, pricing, and duration configuration.
Find Service Providers
/v1/businesses/{businessId}/service-providers sdk.booking.findServiceProviders() Get all provider connections for a service (or all service-provider connections for the business).
const serviceProviders = await sdk.booking.findServiceProviders({
serviceId: 'svc_haircut'
});
for (const sp of serviceProviders) {
console.log(sp.providerId, sp.workingDays, sp.prices);
}
Parameters
| Name | Type | Description |
|---|---|---|
serviceId optional | string | Filter by service ID |
providerId optional | string | Filter by provider ID |
Create Service Provider
/v1/businesses/{businessId}/service-providers sdk.booking.createServiceProvider() Connect a provider to a service with working time and pricing configuration.
const serviceProvider = await sdk.booking.createServiceProvider({
serviceId: 'svc_haircut',
providerId: 'prv_sarah',
workingDays: [
{ day: 'MONDAY', workingHours: [{ from: 540, to: 1020 }] },
{ day: 'TUESDAY', workingHours: [{ from: 540, to: 1020 }] }
],
specificDates: [],
prices: [{ market: 'us', amount: 5000 }],
durations: [{ duration: 60, isPause: false }],
slotInterval: 30
});
Parameters
| Name | Type | Description |
|---|---|---|
serviceId required | string | Service ID |
providerId required | string | Provider ID |
workingDays required | WorkingDay[] | Weekly working schedule (day + workingHours in minutes from midnight) |
specificDates required | SpecificDate[] | Overrides for specific dates |
prices optional | Price[] | Pricing per market |
durations optional | ServiceDuration[] | Duration segments ({ duration, isPause }) |
slotInterval required | number | Slot interval in minutes |
Update Service Provider
/v1/businesses/{businessId}/service-providers/{id} sdk.booking.updateServiceProvider() await sdk.booking.updateServiceProvider({
id: 'sp_abc123',
workingDays: [/* ... */],
specificDates: [],
slotInterval: 30
});
Delete Service Provider
/v1/businesses/{businessId}/service-providers/{id} sdk.booking.deleteServiceProvider() await sdk.booking.deleteServiceProvider({
id: 'sp_abc123'
});
Availability
Get Availability
/v1/businesses/{businessId}/bookings/availability sdk.booking.getAvailability() Fetch available slots for a service in a given month. Returns a per-provider, per-day breakdown with open spots.
const availability = await sdk.booking.getAvailability({
serviceId: 'svc_haircut',
month: '2026-04',
providerId: 'prv_sarah' // optional
});
availability.providers.forEach(provider => {
provider.days.forEach(day => {
day.slots.forEach(slot => {
console.log(day.date, slot.from, slot.to, 'spots:', slot.spots);
});
});
});Parameters
| Name | Type | Description |
|---|---|---|
serviceId required | string | Service ID to check availability for |
month required | string | Month in YYYY-MM format |
providerId optional | string | Limit to a specific provider |
Cart (Client-Side)
The SDK provides local cart management for building booking flows. The cart lives in memory on the client — it is not persisted server-side.
Add to Cart
sdk.booking.addToCart({
id: 'slot_123',
serviceId: 'svc_haircut',
providerId: 'prv_sarah',
from: 1704110400, // Unix timestamp
to: 1704112200,
timeText: '10:00 AM',
dateText: 'Jan 15, 2024'
});
Get Cart
const cart = sdk.booking.getCart();
// Returns array of Slot objects
console.log(cart);
Remove from Cart
sdk.booking.removeFromCart('slot_123');
Clear Cart
sdk.booking.clearCart();
Bookings
Create Booking
/v1/businesses/{businessId}/bookings sdk.booking.createBooking() Create a booking directly (without going through checkout). Most flows should use checkout() instead.
const result = await sdk.booking.createBooking({
// booking payload
});
Get Booking
/v1/businesses/{businessId}/bookings/{id} sdk.booking.getBooking() const result = await sdk.booking.getBooking({
id: 'bkg_xyz789'
});
console.log(result.status, result.parts, result.payment);
Parameters
| Name | Type | Description |
|---|---|---|
id required | string | Booking ID |
Search Bookings
/v1/businesses/{businessId}/bookings sdk.booking.searchBookings() const result = await sdk.booking.searchBookings({
query: 'john@example.com',
serviceIds: ['svc_haircut'],
providerIds: ['prv_sarah'],
from: 1704067200, // Unix timestamp
to: 1704672000,
status: 'CONFIRMED',
sortField: 'createdAt',
sortOrder: 'desc',
cursor: null,
limit: 50
});
result.items.forEach(booking => {
console.log(booking.id, booking.status);
});Parameters
| Name | Type | Description |
|---|---|---|
query optional | string | Search query |
serviceIds optional | string[] | Filter by services |
providerIds optional | string[] | Filter by providers |
from optional | number | Start date (Unix timestamp) |
to optional | number | End date (Unix timestamp) |
status optional | string | Filter by status: CREATED, PENDING, AUTHORIZED, CONFIRMED, COMPLETED, CANCELLED, FAILED |
sortField optional | string | Sort field |
sortOrder optional | asc | desc | Sort order |
cursor optional | string | Pagination cursor |
limit optional | number | Items per page |
Update Booking
/v1/businesses/{businessId}/bookings/{id} sdk.booking.updateBooking() await sdk.booking.updateBooking({
id: 'bkg_xyz789',
status: 'CANCELLED',
forms: [/* updated form submissions */],
parts: [/* updated booking parts */],
payment: null
});
Parameters
| Name | Type | Description |
|---|---|---|
id required | string | Booking ID to update |
status optional | string | Status: CREATED, PENDING, AUTHORIZED, CONFIRMED, COMPLETED, CANCELLED, FAILED |
forms optional | any | Form submissions attached to the booking |
parts optional | any | Updated booking parts (slot groupings) |
payment optional | Payment | null | Updated payment information |
Checkout
Get Quote
/v1/businesses/{businessId}/bookings/quote sdk.booking.getQuote() Calculate pricing before checkout. Items are grouped by service + provider, with an array of slot ranges.
const quote = await sdk.booking.getQuote({
items: [
{
serviceId: 'svc_haircut',
providerId: 'prv_sarah',
slots: [
{ from: 1704110400, to: 1704112200 }
]
}
],
paymentMethodId: 'pm_card_visa',
promoCode: 'FIRSTVISIT',
location: {
country: 'US',
state: 'NY',
postalCode: '10001'
}
});
console.log('Subtotal:', quote.subtotal);
console.log('Total:', quote.total);Parameters
| Name | Type | Description |
|---|---|---|
items required | BookingQuoteItem[] | Items grouped by serviceId + providerId, each with a slots array ({ from, to }) |
paymentMethodId optional | string | Payment method for fee calculation |
promoCode optional | string | Promo code for discount |
location optional | ZoneLocation | Customer location ({ country, state, city, postalCode }) for zone matching |
Checkout
/v1/businesses/{businessId}/bookings/checkout sdk.booking.checkout() Process payment and create a booking. If items is omitted, the SDK groups the client-side cart into items automatically.
// Using cart items (if cart has items)
const result = await sdk.booking.checkout({
paymentMethodId: 'pm_card_visa',
forms: [
{
formId: 'form_customer_info',
values: {
email: 'customer@example.com',
firstName: 'John',
lastName: 'Doe',
phone: '+1234567890'
}
}
],
promoCodeId: 'promo_firstvisit',
location: {
country: 'US',
state: 'NY',
postalCode: '10001'
}
});
// Or provide items directly
const result2 = await sdk.booking.checkout({
items: [
{
serviceId: 'svc_haircut',
providerId: 'prv_sarah',
slots: [{ from: 1704110400, to: 1704112200 }]
}
],
paymentMethodId: 'pm_card_visa',
forms: []
});Parameters
| Name | Type | Description |
|---|---|---|
items optional | BookingQuoteItem[] | Booking items (uses cart if not provided) |
paymentMethodId optional | string | Payment method from Stripe |
forms optional | any[] | Form submissions (customer info, notes, etc.) |
promoCodeId optional | string | Applied promo code ID |
location optional | ZoneLocation | Customer location for zone matching |
Complete Booking Flow
async function bookAppointment() {
// 1. Get available services
const services = await sdk.booking.getServices({
statuses: ['ACTIVE']
});
// 2. Get providers for a service
const providers = await sdk.booking.getProviders({
serviceId: 'svc_haircut',
statuses: ['ACTIVE']
});
// 3. Get availability for a given month
const availability = await sdk.booking.getAvailability({
serviceId: 'svc_haircut',
month: '2026-04'
});
// 4. User selects a slot - add to cart
sdk.booking.addToCart({
id: 'slot_unique_id',
serviceId: 'svc_haircut',
providerId: 'prv_sarah',
from: 1704110400,
to: 1704112200,
timeText: '10:00 AM',
dateText: 'Jan 15, 2024'
});
// 5. Get quote (items are grouped by service + provider with slots[])
const cart = sdk.booking.getCart();
const quote = await sdk.booking.getQuote({
items: [
{
serviceId: 'svc_haircut',
providerId: 'prv_sarah',
slots: cart.map(s => ({ from: s.from, to: s.to }))
}
],
promoCode: 'FIRSTVISIT'
});
console.log('Total:', quote.total);
// 6. Checkout (uses cart automatically if items omitted)
const result = await sdk.booking.checkout({
paymentMethodId: 'pm_card_visa',
forms: [
{
formId: 'form_customer_info',
values: {
email: 'customer@example.com',
firstName: 'John',
lastName: 'Doe'
}
}
]
});
// 7. Clear cart after successful booking
sdk.booking.clearCart();
return result;
}
Use slotInterval on service providers to control how the available slot grid is generated (e.g. 15, 30, or 60 minutes). Use durations with isPause segments to model preparation or clean-up time between appointments.