Services & Scheduling
Services
Services are the bookable offerings of your organization. Each service has its own duration, pricing, and which staff can provide it.
Creating a service
POST /api/org/services
Authorization: Bearer your-token
Content-Type: application/json
{
"name": "Deep Tissue Massage",
"description": "60-minute full-body deep tissue massage",
"duration": 60,
"price": 150000,
"category_id": 2,
"buffer_time": 15,
"color": "#6366f1"
}
Field reference:
| Field | Type | Description |
|---|---|---|
name | string | Service name shown to clients |
description | string | Short description (1–3 sentences) |
duration | integer | Duration in minutes |
price | integer | Price in smallest currency unit |
category_id | integer | Category grouping (optional) |
buffer_time | integer | Post-appointment gap in minutes (cleanup, travel) |
color | string | Hex color for calendar display |
prepay_required | boolean | Require payment at booking |
prepay_amount | integer | Fixed deposit amount (if prepay_required) |
max_advance_days | integer | How many days ahead this service can be booked |
min_lead_hours | integer | Minimum hours required before booking |
is_active | boolean | Whether service is visible and bookable |
Service categories
Group services into categories for better organization on your booking page:
GET /api/org/services/categories
Categories are shared across your organization and help clients navigate your service menu.
Tips for services
- Duration accuracy — Underestimate and you create gaps; overestimate and you lose slots. Time yourself.
- Buffer time — Always add a buffer for room turnover, notes, or preparation. Even 5–10 minutes prevents rushed sessions.
- Pricing — Set the price clients will pay. If you use deposits, set
prepay_amountto the deposit andprepay_required: true. - Colors — Assign different colors to service categories — it makes the staff calendar much easier to read.
Schedules
A schedule defines when a staff member is available to take appointments. Until a schedule is set, no slots are generated for that staff member.
Create a schedule entry
POST /api/org/schedule
Authorization: Bearer your-token
Content-Type: application/json
{
"staff_id": 1,
"day_of_week": 1,
"start_time": "09:00",
"end_time": "18:00"
}
day_of_week: 0 = Sunday, 1 = Monday, ..., 6 = Saturday.
View a schedule
GET /api/org/schedule?staff_id=1
Update a schedule entry
PUT /api/org/schedule/{id}
Content-Type: application/json
{
"start_time": "10:00",
"end_time": "19:00"
}
Delete a schedule entry
DELETE /api/org/schedule/{id}
Full week example
A typical Monday–Friday 9–6 schedule for staff member #1:
[
{ "staff_id": 1, "day_of_week": 1, "start_time": "09:00", "end_time": "18:00" },
{ "staff_id": 1, "day_of_week": 2, "start_time": "09:00", "end_time": "18:00" },
{ "staff_id": 1, "day_of_week": 3, "start_time": "09:00", "end_time": "18:00" },
{ "staff_id": 1, "day_of_week": 4, "start_time": "09:00", "end_time": "18:00" },
{ "staff_id": 1, "day_of_week": 5, "start_time": "09:00", "end_time": "18:00" }
]
Availability Exceptions
Exceptions override the regular schedule for specific dates — useful for holidays, days off, or special hours.
Create an exception
POST /api/org/availability/exceptions
Authorization: Bearer your-token
Content-Type: application/json
{
"staff_id": 1,
"date": "2026-05-01",
"is_day_off": true,
"reason": "National holiday"
}
For a partial day (different hours):
{
"staff_id": 1,
"date": "2026-12-31",
"is_day_off": false,
"start_time": "09:00",
"end_time": "14:00",
"reason": "New Year's Eve — half day"
}
List exceptions
GET /api/org/availability/exceptions?staff_id=1
Tips:
- Create recurring exceptions for all known holidays at the start of the year
- If a staff member is sick, create a same-day exception with
is_day_off: true— existing appointments are preserved and can be rescheduled - Exceptions take precedence over the regular schedule for their specific date
How Slots Are Calculated
The slot calculator considers:
- Staff schedule — when they work (day, start, end times)
- Availability exceptions — overrides for specific dates
- Existing appointments — booked slots are blocked
- Service duration — slot length matches the service
- Buffer time — added after each appointment
- Organization settings — advance booking limits, slot interval, lead time
Slots are returned with a start_time, end_time, and the staff_id of the available staff member.
Checking available slots
Clients (and you, via API) can check slots:
GET /api/booking/{slug}/slots?service_id=1&date=2026-04-01
Or for a range:
GET /api/booking/{slug}/slots/range?service_id=1&start_date=2026-04-01&end_date=2026-04-07
Viewing the Calendar
The organization calendar shows all appointments across all staff:
GET /api/org/appointments/calendar?start=2026-04-01&end=2026-04-30
Returns appointments grouped by date, suitable for rendering a monthly/weekly calendar view.