Skip to content

Reservations API

Manage your booking system with services, providers, availability, and reservations.

Before using the raw API, see the Reservation Booking Integration Guide for complete flows:

  • Service Browsing: List services with pricing and duration
  • Provider Schedules: Fetch working hours and availability
  • Slot Selection: Get available time slots for booking
  • Quote & Checkout: Price calculation and payment
import { createArkySDK } from 'arky-sdk';
// Client-side init with guest token
const sdk = createArkySDK({
baseUrl: 'https://api.arky.io',
businessId: 'your-business-id',
market: 'us',
autoGuest: true,
// ... token handlers
});
// 1. Fetch services
const { items: services } = await sdk.reservation.getServices({
limit: 20,
});
// 2. Get service detail
const service = await sdk.reservation.getService({ id: 'svc_123' });
// 3. Get provider schedule
const schedule = await sdk.reservation.getProviderWorkingTime({
providerId: 'provider_456',
from: startDate,
to: endDate,
});
// 4. Get available slots
const { items: slots } = await sdk.reservation.getAvailableSlots({
serviceId: 'svc_123',
providerId: 'prov_456',
from: startDate,
to: endDate,
});
// 5. Get quote
const quote = await sdk.reservation.getQuote({
currency: 'usd',
paymentMethod: 'CREDIT_CARD',
parts: [{
serviceId: 'svc_123',
providerId: 'prov_456',
startTime: selectedSlot.startTime,
endTime: selectedSlot.endTime,
}],
});
// 6. Checkout (create reservation)
const reservation = await sdk.reservation.checkout({
parts: [{
serviceId: 'svc_123',
providerId: 'prov_456',
startTime: selectedSlot.startTime,
endTime: selectedSlot.endTime,
}],
paymentMethod: 'CREDIT_CARD',
});
// 7. Redirect to payment if needed
if (reservation.paymentUrl) {
window.location.href = reservation.paymentUrl;
}

See Reservation Integration Guide for full patterns.


  • Services/Providers: /v1/businesses/{businessId}
  • Reservations: /v1/reservations

Requires Authorization: Bearer <access_token> header. Guest tokens can be used for browsing and booking.


Services are bookable offerings (e.g., “Haircut”, “Massage”, “Consultation”).

Endpoint: POST /v1/businesses/{businessId}/services

const service = await sdk.reservation.createService({
name: 'Haircut',
slug: 'haircut',
description: 'Professional haircut service',
duration: 1800, // 30 minutes in seconds
pricing: {
markets: [
{
marketId: 'US',
currency: 'USD',
price: 3500, // $35.00 in cents
},
],
},
providerIds: ['provider_1', 'provider_2'], // Who can perform this service
blocks: [], // Optional: custom fields for booking
statuses: [
{
id: 'status_1',
status: 'ACTIVE',
changedBy: 'USER',
timestamp: Date.now() / 1000,
},
],
});

Endpoint: GET /v1/businesses/{businessId}/services

const { items, cursor } = await sdk.reservation.getServices({
limit: 20,
cursor: null,
});
console.log('Services:', items.length);

Endpoint: GET /v1/businesses/{businessId}/services/{id}

const service = await sdk.reservation.getService({
id: 'service_abc123',
});
console.log('Duration:', service.duration);
console.log('Providers:', service.providerIds);

Endpoint: PUT /v1/businesses/{businessId}/services/{id}

const updated = await sdk.reservation.updateService({
id: 'service_abc123',
name: 'Premium Haircut',
duration: 2700, // 45 minutes
pricing: {...},
});

Endpoint: DELETE /v1/businesses/{businessId}/services/{id}

await sdk.reservation.deleteService({
id: 'service_abc123',
});

Providers are individuals/resources that perform services (e.g., stylists, therapists, rooms).

Endpoint: POST /v1/businesses/{businessId}/providers

const provider = await sdk.reservation.createProvider({
name: 'Jane Smith',
slug: 'jane-smith',
description: 'Senior stylist with 10 years experience',
userId: 'user_xyz', // Optional: link to user account
serviceIds: ['service_haircut', 'service_coloring'],
statuses: [
{
id: 'status_1',
status: 'ACTIVE',
changedBy: 'USER',
timestamp: Date.now() / 1000,
},
],
});

Endpoint: GET /v1/businesses/{businessId}/providers

const { items, cursor } = await sdk.reservation.getProviders({
limit: 20,
cursor: null,
serviceId: 'service_haircut', // Optional: filter by service
});

Endpoint: GET /v1/businesses/{businessId}/providers/{id}

const provider = await sdk.reservation.getProvider({
id: 'provider_abc123',
});
console.log('Services:', provider.serviceIds);

Endpoint: PUT /v1/businesses/{businessId}/providers/{id}

const updated = await sdk.reservation.updateProvider({
id: 'provider_abc123',
name: 'Jane Smith (Senior)',
serviceIds: ['service_haircut', 'service_coloring', 'service_styling'],
});

Endpoint: DELETE /v1/businesses/{businessId}/providers/{id}

await sdk.reservation.deleteProvider({
id: 'provider_abc123',
});

Fetch a provider’s schedule.

Endpoint: GET /v1/businesses/{businessId}/providers/{providerId}/working-time

const workingTime = await sdk.reservation.getProviderWorkingTime({
providerId: 'provider_abc123',
serviceIds: ['service_haircut'], // Optional filter
});
console.log('Working days:', workingTime.workingDays);
console.log('Outcast dates:', workingTime.outcastDates); // Holidays, closures
console.log('Specific dates:', workingTime.specificDates); // Override schedule

Response:

{
"workingDays": [
{
"day": "monday",
"workingHours": [
{ "from": 540, "to": 1020 }
]
},
{
"day": "tuesday",
"workingHours": [
{ "from": 540, "to": 720 },
{ "from": 780, "to": 1020 }
]
}
],
"outcastDates": [
{
"month": 12,
"day": 25,
"workingHours": []
}
],
"specificDates": [
{
"year": 2024,
"month": 11,
"day": 15,
"workingHours": [{ "from": 600, "to": 900 }]
}
]
}

Time Format:

  • Times are in minutes from midnight (e.g., 540 = 9:00 AM, 1020 = 5:00 PM)

Set working hours for one or more providers (see Business API).


Get bookable time slots for a service.

Endpoint: GET /v1/businesses/{businessId}/services/{serviceId}/available-slots

const slots = await sdk.reservation.getAvailableSlots({
serviceId: 'service_haircut',
startTime: Math.floor(Date.now() / 1000),
endTime: Math.floor(Date.now() / 1000) + 7 * 24 * 3600, // Next 7 days
providerId: 'provider_abc123', // Optional: specific provider
limit: 1000,
});
slots.forEach((slot) => {
console.log('Provider:', slot.providerId);
console.log('Start:', new Date(slot.startTime * 1000));
console.log('End:', new Date(slot.endTime * 1000));
});

Response:

[
{
"providerId": "provider_abc123",
"serviceId": "service_haircut",
"startTime": 1698765432,
"endTime": 1698767232
},
{
"providerId": "provider_abc123",
"serviceId": "service_haircut",
"startTime": 1698767232,
"endTime": 1698769032
}
]

Endpoint: POST /v1/reservations

const reservation = await sdk.reservation.createReservation({
customerId: 'user_xyz',
parts: [
{
id: 'part_1',
serviceId: 'service_haircut',
providerId: 'provider_abc123',
startTime: 1698765432,
endTime: 1698767232,
price: 3500,
},
],
blocks: [
// Optional: customer notes, preferences
{
id: 'notes',
type: 'TEXT',
value: 'Please use scissors only, no clippers',
},
],
statuses: [
{
id: 'status_1',
status: 'PENDING',
changedBy: 'USER',
timestamp: Date.now() / 1000,
},
],
});

Endpoint: GET /v1/reservations/{id}

const reservation = await sdk.reservation.getReservation({
id: 'reservation_abc123',
});
console.log('Parts:', reservation.parts.length);
console.log('Total:', reservation.total);
console.log('Status:', reservation.statuses[reservation.statuses.length - 1].status);

Endpoint: PUT /v1/reservations/{id}

const updated = await sdk.reservation.updateReservation({
id: 'reservation_abc123',
parts: [...], // Updated time slots
blocks: [...],
});

Endpoint: GET /v1/reservations/search

const { items, cursor } = await sdk.reservation.searchReservations({
limit: 20,
cursor: null,
status: 'CONFIRMED', // Optional filter
providerId: 'provider_abc123', // Optional filter
startTime: Math.floor(Date.now() / 1000),
endTime: Math.floor(Date.now() / 1000) + 7 * 24 * 3600,
});

Get reservations for the authenticated user.

Endpoint: GET /v1/reservations

const { items, cursor } = await sdk.reservation.searchMyReservations({
limit: 20,
cursor: null,
});

Calculate pricing for a reservation.

Endpoint: POST /v1/payments/quote

const quote = await sdk.reservation.getQuote({
currency: 'USD',
paymentMethod: 'CREDIT_CARD',
parts: [
{
serviceId: 'service_haircut',
providerId: 'provider_abc123',
startTime: 1698765432,
endTime: 1698767232,
},
],
promoCode: 'FIRST20', // Optional
});
console.log('Subtotal:', quote.subtotal);
console.log('Tax:', quote.tax);
console.log('Discount:', quote.discount);
console.log('Total:', quote.total);

Process payment and create reservation.

Endpoint: POST /v1/reservations/checkout

const result = await sdk.reservation.checkout({
parts: [
{
serviceId: 'service_haircut',
providerId: 'provider_abc123',
startTime: 1698765432,
endTime: 1698767232,
},
],
paymentMethod: 'CREDIT_CARD',
blocks: [
{
id: 'notes',
type: 'TEXT',
value: 'Customer notes...',
},
],
promoCode: 'FIRST20',
});
if (result.checkoutUrl) {
// Redirect to Stripe checkout
window.location.href = result.checkoutUrl;
} else {
// Reservation confirmed
console.log('Reservation ID:', result.reservationId);
}

Reservations can have multiple parts (e.g., haircut + coloring). Each part has:

{
id: 'part_1',
serviceId: 'service_haircut',
providerId: 'provider_abc123',
startTime: 1698765432, // Unix timestamp
endTime: 1698767232, // Unix timestamp
price: 3500, // cents
blocks: [], // Optional: part-specific data
}

Common statuses:

  • PENDING: Awaiting confirmation
  • CONFIRMED: Booked and confirmed
  • IN_PROGRESS: Currently happening
  • COMPLETED: Finished
  • CANCELLED: Cancelled by user or business
  • NO_SHOW: Customer didn’t show up