Reservation

Services, providers, bookings, and availability management

The Reservation module provides complete booking functionality including services, providers, availability, and checkout.

Services

Services represent bookable offerings (haircuts, consultations, classes, etc.).

Create Service

POST /v1/businesses/{businessId}/services
SDK: sdk.reservation.createService()

Create a new bookable service.

const result = await sdk.reservation.createService({
key: 'haircut',
nodeIds: ['node_services', 'node_hair'],
blocks: [
  {
    key: 'description',
    type: 'TEXT',
    content: {
      body: { en: 'Professional haircut service' }
    }
  }
],
prices: [
  { market: 'USD', amount: 3500 },
  { market: 'EUR', amount: 3200 }
],
durations: [
  { duration: 30, isPause: false },
  { duration: 45, isPause: false }
],
isApprovalRequired: false,
status: 'ACTIVE',
providers: [
  {
    providerId: 'prv_sarah',
    workingTime: {
      workingDays: [
        { day: 'MONDAY', workingHours: [{ from: 540, to: 1020 }] },
        { day: 'TUESDAY', workingHours: [{ from: 540, to: 1020 }] }
      ],
      outcastDates: [],
      specificDates: []
    }
  }
]
});

Parameters

Name Type Description
key required string Unique service key identifier
slug optional Record<string, string> Locale-keyed URL slugs
access optional PUBLIC | AUTHENTICATED | PRIVATE Access level
nodeIds optional string[] Category node IDs
networkIds optional string[] Network IDs
blocks optional Block[] Content blocks for service details
prices optional Price[] Pricing per market (array of { market, amount })
durations optional ServiceDuration[] Duration segments (array of { duration: number, isPause: boolean })
isApprovalRequired optional boolean Whether bookings need approval
location optional Location Service location (for mobile services)
status optional DRAFT | ACTIVE | ARCHIVED Service status
providers optional ServiceProviderInput[] Provider assignments with working time

Get Service

GET /v1/businesses/{businessId}/services/{id}
SDK: sdk.reservation.getService()

Retrieve a service by ID or slug.

// By ID
const result = await sdk.reservation.getService({
  id: 'svc_xyz789'
});

// By slug (locale-aware)
const result = await sdk.reservation.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

GET /v1/businesses/{businessId}/services
SDK: sdk.reservation.getServices()

List all services with filtering.

const result = await sdk.reservation.getServices({
providerId: 'prv_sarah',
ids: ['svc_1', 'svc_2'],
query: 'haircut',
statuses: ['ACTIVE'],
nodeId: 'node_services',
blocks: ['description', 'gallery'],
sortField: 'createdAt',
sortDirection: 'desc',
priceFrom: 2000,
priceTo: 5000,
cursor: null,
limit: 20
});

result.items.forEach(service => {
console.log(service.key, service.prices);
});

Parameters

Name Type Description
providerId optional string Filter by provider
ids optional string[] Filter by specific service IDs
query optional string Search query
statuses optional string[] Filter by statuses
nodeId optional string Filter by category node
blocks optional Block[] Filter by blocks content
matchAll optional boolean If true, match all filters (AND); if false, match any (OR)
sortField optional string Sort field
sortDirection optional asc | desc Sort direction
priceFrom optional number Minimum price filter
priceTo optional number Maximum price filter
from optional number Filter by availability from (Unix timestamp)
to optional number Filter by availability to (Unix timestamp)
createdAtFrom optional number Filter by creation date (Unix timestamp)
createdAtTo optional number Filter by creation date (Unix timestamp)
cursor optional string Pagination cursor
limit optional number Items per page

Update Service

PUT /v1/businesses/{businessId}/services/{id}
SDK: sdk.reservation.updateService()
await sdk.reservation.updateService({
  id: 'svc_xyz789',
  key: 'premium-haircut',
  prices: [{ market: 'USD', amount: 4000 }],
  status: 'ACTIVE'
});

Parameters

Name Type Description
id required string Service ID to update
key required string Service key identifier
slug optional Record<string, string> Locale-keyed URL slugs
access optional PUBLIC | AUTHENTICATED | PRIVATE Access level
nodeIds optional string[] Category node IDs
networkIds optional string[] Network IDs
blocks optional Block[] Content blocks
prices optional Price[] Pricing per market
durations optional ServiceDuration[] Duration segments ({ duration, isPause })
isApprovalRequired optional boolean Whether bookings need approval
location optional Location Service location
status optional DRAFT | ACTIVE | ARCHIVED Service status
providers optional ServiceProviderInput[] Provider assignments with working time

Delete Service

DELETE /v1/businesses/{businessId}/services/{id}
SDK: sdk.reservation.deleteService()
await sdk.reservation.deleteService({
  id: 'svc_xyz789'
});

Bulk Schedule

POST /v1/businesses/{businessId}/services/bulk-schedule
SDK: sdk.reservation.bulkSchedule()

Apply working time to multiple services and providers at once.

await sdk.reservation.bulkSchedule({
  serviceIds: ['svc_haircut', 'svc_coloring'],
  providerIds: ['prv_sarah', 'prv_mike'],
  workingTime: {
    workingDays: [
      { day: 'MONDAY', workingHours: [{ from: 540, to: 1020 }] },
      { day: 'TUESDAY', workingHours: [{ from: 540, to: 1020 }] },
      { day: 'WEDNESDAY', workingHours: [{ from: 540, to: 1020 }] },
      { day: 'THURSDAY', workingHours: [{ from: 540, to: 1020 }] },
      { day: 'FRIDAY', workingHours: [{ from: 540, to: 1020 }] }
    ],
    outcastDates: [],
    specificDates: []
  }
});

Parameters

Name Type Description
serviceIds required string[] Services to apply schedule to
providerIds required string[] Providers to apply schedule to
workingTime required WorkingTime Working time configuration

Providers

Providers are staff members who perform services.

Create Provider

POST /v1/businesses/{businessId}/providers
SDK: sdk.reservation.createProvider()
const result = await sdk.reservation.createProvider({
key: 'sarah-johnson',
nodeIds: ['node_stylists'],
blocks: [
  {
    key: 'bio',
    type: 'TEXT',
    content: {
      body: { en: 'Senior stylist with 10 years experience' }
    }
  },
  {
    key: 'image',
    type: 'IMAGE',
    content: {
      mediaId: 'media_sarah123'
    }
  }
],
concurrentLimit: 1,  // Can handle 1 client at a time
status: 'ACTIVE'
});

Parameters

Name Type Description
key required string Unique provider key identifier
slug optional Record<string, string> Locale-keyed URL slugs
access optional PUBLIC | AUTHENTICATED | PRIVATE Access level
nodeIds optional string[] Category node IDs
networkIds optional string[] Network IDs
blocks optional Block[] Content blocks (bio, image, etc.)
concurrentLimit optional number Max concurrent bookings (default 1)
status optional DRAFT | ACTIVE | ARCHIVED Provider status

Get Provider

GET /v1/businesses/{businessId}/providers/{id}
SDK: sdk.reservation.getProvider()
// By ID
const result = await sdk.reservation.getProvider({
  id: 'prv_abc123'
});

// By slug
const result = await sdk.reservation.getProvider({
  slug: 'sarah-johnson'
});

List Providers

GET /v1/businesses/{businessId}/providers
SDK: sdk.reservation.getProviders()
const result = await sdk.reservation.getProviders({
serviceId: 'svc_haircut',
ids: ['prv_1', 'prv_2'],
query: 'sarah',
statuses: ['ACTIVE'],
nodeId: 'node_stylists',
blocks: 'bio,image',
sortField: 'createdAt',
sortDirection: 'desc',
cursor: null,
limit: 20,
createdAtFrom: '2024-01-01',
createdAtTo: '2024-12-31'
});

result.items.forEach(provider => {
console.log(provider.key, provider.concurrentLimit);
});

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
nodeId optional string Filter by category node
blocks optional Block[] Filter by blocks content
matchAll optional boolean If true, match all filters (AND); if false, match any (OR)
sortField optional string Sort field
sortDirection optional asc | desc Sort direction
from optional number Filter by availability from (Unix timestamp)
to optional number Filter by availability to (Unix timestamp)
createdAtFrom optional number Filter by creation date (Unix timestamp)
createdAtTo optional number Filter by creation date (Unix timestamp)
cursor optional string Pagination cursor
limit optional number Items per page

Get Provider Working Time

GET /v1/businesses/{businessId}/providers/{providerId}/working-time
SDK: sdk.reservation.getProviderWorkingTime()

Get a provider’s availability schedule.

const result = await sdk.reservation.getProviderWorkingTime({
  providerId: 'prv_abc123',
  serviceId: 'svc_haircut'  // Optional: filter by service
});

// Returns working time configuration
console.log(result.workingDays);
console.log(result.outcastDates);
console.log(result.specificDates);

Parameters

Name Type Description
providerId required string Provider ID
serviceId optional string Filter working time by specific service

Update Provider

PUT /v1/businesses/{businessId}/providers/{id}
SDK: sdk.reservation.updateProvider()
await sdk.reservation.updateProvider({
  id: 'prv_abc123',
  key: 'sarah-johnson-senior',
  concurrentLimit: 2,
  status: 'ACTIVE'
});

Parameters

Name Type Description
id required string Provider ID to update
key required string Provider key identifier
slug optional Record<string, string> Locale-keyed URL slugs
access optional PUBLIC | AUTHENTICATED | PRIVATE Access level
nodeIds optional string[] Category node IDs
networkIds optional string[] Network IDs
blocks optional Block[] Content blocks
concurrentLimit optional number Max concurrent bookings
status optional DRAFT | ACTIVE | ARCHIVED Provider status

Delete Provider

DELETE /v1/businesses/{businessId}/providers/{id}
SDK: sdk.reservation.deleteProvider()
await sdk.reservation.deleteProvider({
  id: 'prv_abc123'
});

Cart (Client-Side)

The SDK provides local cart management for building booking flows.

Add to Cart

sdk.reservation.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.reservation.getCart();
// Returns array of Slot objects
console.log(cart);

Remove from Cart

sdk.reservation.removeFromCart('slot_123');

Clear Cart

sdk.reservation.clearCart();

Reservations

Create Reservation

POST /v1/businesses/{businessId}/reservations
SDK: sdk.reservation.createReservation()

Create a reservation from selected slots.

const result = await sdk.reservation.createReservation({
  // Any additional params
});

Get Reservation

GET /v1/businesses/{businessId}/reservations/{id}
SDK: sdk.reservation.getReservation()
const result = await sdk.reservation.getReservation({
  id: 'res_xyz789'
});

console.log(result.status, result.parts, result.payment);

Search Reservations

GET /v1/businesses/{businessId}/reservations
SDK: sdk.reservation.searchReservations()
const result = await sdk.reservation.searchReservations({
query: '[email protected]',
serviceIds: ['svc_haircut'],
providerIds: ['prv_sarah'],
accountId: 'acc_customer123',
from: 1704067200,  // Unix timestamp
to: 1704672000,
status: 'CONFIRMED',
sortField: 'createdAt',
sortOrder: 'desc',
cursor: null,
limit: 50
});

result.items.forEach(reservation => {
console.log(reservation.id, reservation.status);
});

Parameters

Name Type Description
query optional string Search query
serviceIds optional string[] Filter by services
providerIds optional string[] Filter by providers
accountId optional string Filter by customer account
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 Reservation

PUT /v1/businesses/{businessId}/reservations/{id}
SDK: sdk.reservation.updateReservation()
await sdk.reservation.updateReservation({
  id: 'res_xyz789',
  status: 'CANCELLED',
  blocks: [
    {
      key: 'cancellation-reason',
      type: 'TEXT',
      content: { body: 'Customer request' }
    }
  ],
  items: [/* updated items */],
  payment: null
});

Parameters

Name Type Description
id required string Reservation ID to update
status required string Status: CREATED, PENDING, AUTHORIZED, CONFIRMED, COMPLETED, CANCELLED, FAILED
blocks required Block[] Reservation content blocks
items optional ReservationItemPayload[] Updated reservation items
payment optional Payment | null Updated payment information

Checkout

Get Quote

POST /v1/businesses/{businessId}/reservations/quote
SDK: sdk.reservation.getQuote()

Calculate pricing before checkout.

const quote = await sdk.reservation.getQuote({
items: [
  {
    serviceId: 'svc_haircut',
    providerId: 'prv_sarah',
    from: 1704110400,
    to: 1704112200
  }
],
paymentMethodId: 'pm_card_visa',
promoCode: 'FIRSTVISIT',
location: {
  lat: 40.7128,
  lng: -74.0060
}
});

console.log('Subtotal:', quote.subtotal);
console.log('Discount:', quote.discount);
console.log('Total:', quote.total);

Parameters

Name Type Description
items required ReservationQuoteItem[] Items with serviceId, providerId, from, to timestamps
paymentMethodId optional string Payment method for fee calculation
promoCode optional string Promo code for discount
location optional Location Customer location (for mobile services)

Checkout Reservation

POST /v1/businesses/{businessId}/reservations/checkout
SDK: sdk.reservation.checkout()

Process payment for a reservation. Can use cart items or provide items directly.

// Using cart items (if cart has items)
const result = await sdk.reservation.checkout({
paymentMethodId: 'pm_card_visa',
blocks: [
  {
    key: 'customer-info',
    type: 'FORM',
    content: {
      email: '[email protected]',
      firstName: 'John',
      lastName: 'Doe',
      phone: '+1234567890'
    }
  },
  {
    key: 'notes',
    type: 'TEXT',
    content: { body: 'First time customer' }
  }
],
promoCodeId: 'promo_firstvisit',
location: {
  lat: 40.7128,
  lng: -74.0060
}
});

// Or provide items directly
const result = await sdk.reservation.checkout({
items: [
  {
    serviceId: 'svc_haircut',
    providerId: 'prv_sarah',
    from: 1704110400,
    to: 1704112200
  }
],
paymentMethodId: 'pm_card_visa',
blocks: [/* customer info blocks */]
});

Parameters

Name Type Description
items optional any[] Reservation items (uses cart if not provided)
paymentMethodId optional string Payment method from Stripe
blocks optional Block[] Customer info and notes as content blocks
promoCodeId optional string Applied promo code ID
location optional Location Customer location

Complete Booking Flow

async function bookAppointment() {
  // 1. Get available services
  const services = await sdk.reservation.getServices({
    statuses: ['ACTIVE']
  });

  // 2. Get providers for a service
  const providers = await sdk.reservation.getProviders({
    serviceId: 'svc_haircut',
    statuses: ['ACTIVE']
  });

  // 3. Get provider working time
  const workingTime = await sdk.reservation.getProviderWorkingTime({
    providerId: 'prv_sarah',
    serviceId: 'svc_haircut'
  });

  // 4. User selects a slot - add to cart
  sdk.reservation.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
  const quote = await sdk.reservation.getQuote({
    items: sdk.reservation.getCart().map(s => ({
      serviceId: s.serviceId,
      providerId: s.providerId,
      from: s.from,
      to: s.to
    })),
    promoCode: 'FIRSTVISIT'
  });

  console.log('Total:', quote.total);

  // 6. Checkout
  const result = await sdk.reservation.checkout({
    paymentMethodId: 'pm_card_visa',
    blocks: [
      {
        key: 'customer',
        type: 'FORM',
        content: {
          email: '[email protected]',
          firstName: 'John',
          lastName: 'Doe'
        }
      }
    ]
  });

  // 7. Clear cart after successful booking
  sdk.reservation.clearCart();

  return result;
}
Tip

Use concurrentLimit on providers to control how many appointments they can handle simultaneously (e.g., set to 2 for group classes).