Complete guide to integrating ZvenBook's booking system API into your applications.
Get up and running with ZvenBook in under 5 minutes. This guide will walk you through creating your first booking.
npm install @zvenbook/sdk
Or use your preferred package manager: yarn add @zvenbook/sdk
or pnpm add @zvenbook/sdk
import { createSdk } from '@zvenbook/sdk';
const sdk = createSdk({
baseUrl: 'https://your-zvenbook-instance.vercel.app'
// No API key required for public endpoints
});
// Health check
const health = await sdk.health();
console.log(health); // { ok: true }
Replace the baseUrl with your deployed ZvenBook instance URL.
async function bookAppointment() {
try {
// 1. List available tenants or use tenantId from environment variables
const { tenants } = await sdk.listTenants();
const tenantId = tenants[0]._id || process.env.NEXT_PUBLIC_TENANT_ID;
// 2. Get services and providers
const [{ services }, { providers }] = await Promise.all([
sdk.listServices({ tenantId }),
sdk.listProviders({ tenantId })
]);
// 3. Check availability
const { slots } = await sdk.availability({
tenantId,
serviceId: services[0]._id,
providerId: providers[0]._id,
start: '2024-01-15T08:00:00Z',
end: '2024-01-15T18:00:00Z',
timezone: 'Europe/Stockholm'
});
// 4. Create booking
const booking = await sdk.createBooking({
tenantId,
serviceId: services[0]._id,
providerId: providers[0]._id,
start: slots[0].start,
end: slots[0].end,
contactEmail: 'customer@example.com',
contactFirstName: 'John',
contactLastName: 'Doe'
});
console.log('Booking created:', booking);
} catch (error) {
console.error('Booking failed:', error);
}
}
Tenants represent separate organizations or business units. Each tenant has isolated data including services, providers, and bookings.
Best Practice: Use meaningful tenant IDs like your company name or domain (e.g., 'acme-corp', 'salon-downtown').
Services define what can be booked - haircuts, consultations, equipment rentals, etc. Each service has duration, buffer times, and capacity settings.
await sdk.createService({
tenantId: 'salon',
name: 'Haircut & Style',
durationMin: 60, // Service takes 60 minutes
bufferBeforeMin: 10, // 10 min prep time
bufferAfterMin: 15, // 15 min cleanup time
capacity: 1 // One customer at a time
});
Providers are the people or resources that deliver services - stylists, doctors, conference rooms, etc. They have working schedules and can be assigned to multiple services.
await sdk.createProvider({
tenantId: 'salon',
name: 'Alex Johnson',
timezone: 'Europe/Stockholm',
email: 'alex@salon.com'
});
// Set working hours
await sdk.createWeeklyRule({
tenantId: 'salon',
providerId: 'alex',
timezone: 'Europe/Stockholm',
days: [
{ weekday: 1, start: '09:00', end: '17:00' }, // Monday
{ weekday: 2, start: '09:00', end: '17:00' }, // Tuesday
// ... more days
]
});
/availability
Get available time slots for a service and provider.
/bookings
Create a new booking with automatic email confirmation.
/cancel/:token
Cancel a booking using its cancellation token (no auth required).
/reschedule/:token
Reschedule a booking to a new time slot.
For a complete list of all endpoints with detailed parameters and examples, check out our comprehensive SDK documentation and the README file.
Real-world examples of integrating ZvenBook into different platforms and frameworks.
import { createSdk } from '@zvenbook/sdk';
import { useState, useEffect } from 'react';
const sdk = createSdk({ baseUrl: process.env.NEXT_PUBLIC_ZVENBOOK_URL });
export default function BookingWidget({ tenantId, serviceId }) {
const [slots, setSlots] = useState([]);
const [providers, setProviders] = useState([]);
useEffect(() => {
async function loadData() {
const { providers } = await sdk.listProviders({ tenantId });
setProviders(providers);
if (providers.length > 0) {
const { slots } = await sdk.availability({
tenantId, serviceId, providerId: providers[0]._id,
start: new Date().toISOString(),
end: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
timezone: 'Europe/Stockholm'
});
setSlots(slots);
}
}
loadData();
}, [tenantId, serviceId]);
const bookSlot = async (slot) => {
await sdk.createBooking({
tenantId, serviceId, providerId: providers[0]._id,
start: slot.start, end: slot.end,
contactEmail: 'customer@example.com',
contactFirstName: 'John', contactLastName: 'Doe'
});
};
return (
<div className="space-y-2">
{slots.map(slot => (
<button key={slot.start} onClick={() => bookSlot(slot)}
className="p-2 bg-blue-500 text-white rounded">
{new Date(slot.start).toLocaleString()}
</button>
))}
</div>
);
}
const { createSdk } = require('@zvenbook/sdk');
const express = require('express');
const sdk = createSdk({ baseUrl: process.env.ZVENBOOK_URL });
const app = express();
app.use(express.json());
app.post('/book-appointment', async (req, res) => {
try {
const booking = await sdk.createBooking({
tenantId: req.body.tenantId,
serviceId: req.body.serviceId,
autoSelectProvider: true, // Auto-select optimal provider
start: req.body.start,
end: req.body.end,
contactEmail: req.body.email,
contactFirstName: req.body.firstName,
contactLastName: req.body.lastName
});
res.json({ success: true, booking });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Virtual meetings with auto-generated Jitsi rooms
const booking = await sdk.createBooking({
// ... other fields
virtualMeetingPlatform: 'jitsi', // Auto-generates meeting room
notes: 'First time customer - please call if needed'
});
// Multi-location support
const booking = await sdk.createBooking({
// ... other fields
locationName: 'Downtown Office',
locationAddress: '123 Main St, Stockholm',
entryPinCode: '1234',
entryInstructions: 'Use side entrance after hours'
});
// Provider workload analytics
const { providers } = await sdk.getProviderWorkload({
tenantId: 'salon-123',
start: '2024-01-01T00:00:00Z',
end: '2024-01-31T23:59:59Z'
});
providers.forEach(provider => {
console.log(`${provider.name}: ${provider.booking_count} bookings`);
});
ZvenBook includes a comprehensive email system with automatic confirmations, reminders, and cancellation notifications.
Sent automatically when bookings are created with ICS calendar attachments.
Automatic reminders sent 24 hours before appointments.
Sent when bookings are cancelled with calendar removal.
Updated calendar invitations when bookings are rescheduled.
Email functionality requires environment variables to be configured:
RESEND_API_KEY=your-resend-api-key
FROM_EMAIL=bookings@yourdomain.com
BASE_URL=https://yourdomain.com
The API uses standard HTTP status codes and returns detailed error messages in JSON format.
Invalid request parameters or missing required fields.
Booking conflicts with existing appointments or business rules.
Resource not found (service, provider, booking, etc.).
// Example error response
{
"error": "Time overlaps with existing booking",
"code": "BOOKING_CONFLICT",
"details": {
"conflictingBooking": "booking-123",
"suggestedSlots": [
{ "start": "2024-01-15T11:00:00Z", "end": "2024-01-15T12:00:00Z" }
]
}
}