Reservations API
Manage your booking system with services, providers, availability, and reservations.
Integration Patterns
Section titled “Integration Patterns”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
Complete Booking Flow
Section titled “Complete Booking Flow”import { createArkySDK } from 'arky-sdk';
// Client-side init with guest tokenconst sdk = createArkySDK({ baseUrl: 'https://api.arky.io', businessId: 'your-business-id', market: 'us', autoGuest: true, // ... token handlers});
// 1. Fetch servicesconst { items: services } = await sdk.reservation.getServices({ limit: 20,});
// 2. Get service detailconst service = await sdk.reservation.getService({ id: 'svc_123' });
// 3. Get provider scheduleconst schedule = await sdk.reservation.getProviderWorkingTime({ providerId: 'provider_456', from: startDate, to: endDate,});
// 4. Get available slotsconst { items: slots } = await sdk.reservation.getAvailableSlots({ serviceId: 'svc_123', providerId: 'prov_456', from: startDate, to: endDate,});
// 5. Get quoteconst 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 neededif (reservation.paymentUrl) { window.location.href = reservation.paymentUrl;}See Reservation Integration Guide for full patterns.
Base URL
Section titled “Base URL”- Services/Providers:
/v1/businesses/{businessId} - Reservations:
/v1/reservations
Authentication
Section titled “Authentication”Requires Authorization: Bearer <access_token> header. Guest tokens can be used for browsing and booking.
Services
Section titled “Services”Services are bookable offerings (e.g., “Haircut”, “Massage”, “Consultation”).
Create Service
Section titled “Create Service”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, }, ],});curl -X POST https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/services \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Haircut", "slug": "haircut", "description": "Professional haircut service", "duration": 1800, "pricing": {...}, "providerIds": ["provider_1", "provider_2"], "blocks": [], "statuses": [...] }'Get Services
Section titled “Get Services”Endpoint: GET /v1/businesses/{businessId}/services
const { items, cursor } = await sdk.reservation.getServices({ limit: 20, cursor: null,});
console.log('Services:', items.length);curl "https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/services?limit=20" \ -H "Authorization: Bearer YOUR_TOKEN"Get Service
Section titled “Get Service”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);curl https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/services/SERVICE_ID \ -H "Authorization: Bearer YOUR_TOKEN"Update Service
Section titled “Update Service”Endpoint: PUT /v1/businesses/{businessId}/services/{id}
const updated = await sdk.reservation.updateService({ id: 'service_abc123', name: 'Premium Haircut', duration: 2700, // 45 minutes pricing: {...},});curl -X PUT https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/services/SERVICE_ID \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Premium Haircut", "duration": 2700 }'Delete Service
Section titled “Delete Service”Endpoint: DELETE /v1/businesses/{businessId}/services/{id}
await sdk.reservation.deleteService({ id: 'service_abc123',});curl -X DELETE https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/services/SERVICE_ID \ -H "Authorization: Bearer YOUR_TOKEN"Providers
Section titled “Providers”Providers are individuals/resources that perform services (e.g., stylists, therapists, rooms).
Create Provider
Section titled “Create Provider”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, }, ],});curl -X POST https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Jane Smith", "slug": "jane-smith", "description": "Senior stylist", "userId": "user_xyz", "serviceIds": ["service_haircut"], "statuses": [...] }'Get Providers
Section titled “Get Providers”Endpoint: GET /v1/businesses/{businessId}/providers
const { items, cursor } = await sdk.reservation.getProviders({ limit: 20, cursor: null, serviceId: 'service_haircut', // Optional: filter by service});# All providerscurl "https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers?limit=20" \ -H "Authorization: Bearer YOUR_TOKEN"
# Filter by servicecurl "https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers?serviceId=SERVICE_ID&limit=20" \ -H "Authorization: Bearer YOUR_TOKEN"Get Provider
Section titled “Get Provider”Endpoint: GET /v1/businesses/{businessId}/providers/{id}
const provider = await sdk.reservation.getProvider({ id: 'provider_abc123',});
console.log('Services:', provider.serviceIds);curl https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers/PROVIDER_ID \ -H "Authorization: Bearer YOUR_TOKEN"Update Provider
Section titled “Update Provider”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'],});curl -X PUT https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers/PROVIDER_ID \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Jane Smith (Senior)", "serviceIds": [...] }'Delete Provider
Section titled “Delete Provider”Endpoint: DELETE /v1/businesses/{businessId}/providers/{id}
await sdk.reservation.deleteProvider({ id: 'provider_abc123',});curl -X DELETE https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers/PROVIDER_ID \ -H "Authorization: Bearer YOUR_TOKEN"Working Time & Schedules
Section titled “Working Time & Schedules”Get Provider Working Time
Section titled “Get Provider Working Time”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, closuresconsole.log('Specific dates:', workingTime.specificDates); // Override schedulecurl "https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/providers/PROVIDER_ID/working-time?serviceIds=SERVICE_ID" \ -H "Authorization: Bearer YOUR_TOKEN"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 Provider Schedules
Section titled “Set Provider Schedules”Set working hours for one or more providers (see Business API).
Available Slots
Section titled “Available Slots”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));});curl "https://api.arky.io/v1/businesses/YOUR_BUSINESS_ID/services/SERVICE_ID/available-slots?startTime=1698765432&endTime=1699370232&limit=1000" \ -H "Authorization: Bearer YOUR_TOKEN"Response:
[ { "providerId": "provider_abc123", "serviceId": "service_haircut", "startTime": 1698765432, "endTime": 1698767232 }, { "providerId": "provider_abc123", "serviceId": "service_haircut", "startTime": 1698767232, "endTime": 1698769032 }]Reservations
Section titled “Reservations”Create Reservation
Section titled “Create Reservation”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, }, ],});curl -X POST https://api.arky.io/v1/reservations \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "businessId": "YOUR_BUSINESS_ID", "market": "US", "customerId": "user_xyz", "parts": [...], "blocks": [...], "statuses": [...] }'Get Reservation
Section titled “Get Reservation”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);curl "https://api.arky.io/v1/reservations/RESERVATION_ID?businessId=YOUR_BUSINESS_ID" \ -H "Authorization: Bearer YOUR_TOKEN"Update Reservation
Section titled “Update Reservation”Endpoint: PUT /v1/reservations/{id}
const updated = await sdk.reservation.updateReservation({ id: 'reservation_abc123', parts: [...], // Updated time slots blocks: [...],});curl -X PUT https://api.arky.io/v1/reservations/RESERVATION_ID \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "parts": [...], "blocks": [...] }'Search Reservations
Section titled “Search Reservations”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,});curl "https://api.arky.io/v1/reservations/search?businessId=YOUR_BUSINESS_ID&status=CONFIRMED&startTime=1698765432&endTime=1699370232&limit=20" \ -H "Authorization: Bearer YOUR_TOKEN"My Reservations
Section titled “My Reservations”Get reservations for the authenticated user.
Endpoint: GET /v1/reservations
const { items, cursor } = await sdk.reservation.searchMyReservations({ limit: 20, cursor: null,});curl "https://api.arky.io/v1/reservations?limit=20" \ -H "Authorization: Bearer YOUR_TOKEN"Checkout Flow
Section titled “Checkout Flow”Get Quote
Section titled “Get Quote”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);curl -X POST https://api.arky.io/v1/payments/quote \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "businessId": "YOUR_BUSINESS_ID", "market": "US", "currency": "USD", "paymentMethod": "CREDIT_CARD", "lines": [ { "type": "SERVICE", "serviceId": "service_haircut", "quantity": 1 } ], "promoCode": "FIRST20" }'Checkout
Section titled “Checkout”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);}curl -X POST https://api.arky.io/v1/reservations/checkout \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "businessId": "YOUR_BUSINESS_ID", "market": "US", "parts": [...], "paymentMethod": "CREDIT_CARD", "blocks": [...], "promoCode": "FIRST20" }'Reservation Parts
Section titled “Reservation Parts”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}Reservation Statuses
Section titled “Reservation Statuses”Common statuses:
PENDING: Awaiting confirmationCONFIRMED: Booked and confirmedIN_PROGRESS: Currently happeningCOMPLETED: FinishedCANCELLED: Cancelled by user or businessNO_SHOW: Customer didn’t show up