API Reference
Integrate Boeqy into your workflow with our REST API. All endpoints return JSON. Admin endpoints require a valid session with an active organization selected.
Base URL
https://your-domain.com/apiAuthentication
Boeqy uses session-based authentication via NextAuth. Admin endpoints require a valid JWT session with selectedOrgId set. Public endpoints (booking, slots) accept organizationId as a query parameter.
Authentication
/api/registerPublicCreate a new user account. Optionally create an organization group and first shop.
Body
| name* | string | User's full name |
| email* | string | Unique email address |
| password* | string | Account password |
| phone | string | Phone number |
| isAdmin | boolean | Create as shop admin (default: false) |
| businessName | string | Franchise group name (required if isAdmin) |
| businessSlug | string | URL slug for the group (required if isAdmin) |
| shopName | string | First shop name (required if isAdmin) |
| shopSlug | string | URL slug for the shop (required if isAdmin) |
Response 201
{
"user": { "id": "uuid", "email": "jane@barbers.com" },
"group": { "id": "uuid", "slug": "janes-barbers" },
"organization": { "id": "uuid", "slug": "city-center" }
}Public Booking
/api/slotsPublicGet available time slots for a service on a given date. Returns sorted HH:mm strings.
Query Parameters
| organizationId* | string | Organization (shop) ID |
| serviceId* | string | Service to check availability for |
| date* | string | Date in YYYY-MM-DD format |
| employeeId | string | Filter by specific employee |
Response 200
{
"slots": ["09:00", "09:30", "10:00", "10:30", "11:00"]
}/api/bookingsPublicCreate a new booking. Validates employee availability, working hours, buffer times, and blocked slots.
Body
| organizationId* | string | Organization (shop) ID |
| serviceId* | string | Service being booked |
| date* | string | Date in YYYY-MM-DD format |
| startTime* | string | Start time in HH:mm format |
| customerName* | string | Customer name |
| customerPhone* | string | Customer phone |
| employeeId | string | Preferred employee (auto-assigned if omitted) |
| customerEmail | string | For confirmation email |
| notes | string | Booking notes |
Response 201
{
"booking": {
"id": "uuid",
"referenceCode": "BK-a1b2c3",
"serviceId": "uuid",
"employeeId": "uuid",
"startTime": "2026-03-25T09:00:00.000Z",
"endTime": "2026-03-25T09:30:00.000Z",
"status": "CONFIRMED"
}
}/api/public/settingsPublicGet public booking settings for a shop (no auth required).
Query Parameters
| organizationId* | string | Organization (shop) ID |
Response 200
{
"name": "City Center",
"bookingWindowDays": 60,
"slotIntervalMinutes": 30,
"currency": "EUR"
}Employees
/api/employeesAdminList active employees. In public context, pass organizationId as query param.
Query Parameters
| serviceId | string | Filter by service capability |
| organizationId | string | Org ID (public context) |
| includeNextAvailable | boolean | Include next available slot (checks 7 days) |
Response 200
{
"employees": [
{ "id": "uuid", "name": "John", "imageUrl": null, "nextAvailable": "Today, 10:00" }
]
}/api/employeesAdminCreate a new employee with optional service assignments.
Body
| name* | string | Employee name |
| string | Employee email | |
| imageUrl | string | Profile image URL |
| serviceIds | string[] | Services this employee can perform |
Response 201
{ "employee": { "id": "uuid", "name": "John", ... } }/api/employees/:idAdminUpdate employee details and service assignments.
Body
| name | string | Employee name |
| string | Employee email | |
| isActive | boolean | Active status |
| serviceIds | string[] | Replace service assignments |
/api/employees/:idAdminSoft-delete an employee (sets isActive to false).
/api/employees/:id/scheduleAdminReplace an employee's weekly schedule.
Body
| schedule* | array | Array of { dayOfWeek (1-7 ISO), startTime (HH:mm), endTime (HH:mm) } |
/api/employees/:id/exceptionsAdminCreate a schedule exception (day off or custom hours).
Body
| date* | string | Date in YYYY-MM-DD |
| isBlocked* | boolean | True = day off, False = custom hours |
| startTime | string | Custom start time (HH:mm) |
| endTime | string | Custom end time (HH:mm) |
| reason | string | Reason for exception |
Services
/api/servicesAdminList all services for the current organization, ordered by sortOrder.
Response 200
{
"services": [
{
"id": "uuid", "name": "Haircut", "description": "Classic cut",
"durationMinutes": 30, "priceInCents": 3500, "isActive": true
}
]
}/api/servicesAdminCreate a new service.
Body
| name* | string | Service name |
| durationMinutes* | number | Duration in minutes |
| priceInCents* | number | Price in cents (e.g. 3500 = 35.00) |
| description | string | Service description |
| imageUrl | string | Service image |
/api/services/:idAdminUpdate a service.
/api/services/:idAdminSoft-delete a service (sets isActive to false).
Bookings
/api/bookings/:idAdminGet booking details by ID.
Response 200
{
"booking": {
"id": "uuid", "referenceCode": "BK-a1b2c3",
"status": "CONFIRMED", "startTime": "...", "endTime": "...",
"service": { "name": "Haircut" },
"employee": { "name": "John" }
}
}/api/bookings/:idAdminUpdate a booking. Set status to CANCELLED to trigger cancellation flow (email + waitlist notification).
Body
| status | string | CONFIRMED | CANCELLED | COMPLETED | NO_SHOW |
| employeeId | string | Reassign to another employee |
| startTime | string | Reschedule start time (ISO) |
| endTime | string | Reschedule end time (ISO) |
/api/bookings/:id/repeatAdminCreate the next occurrence of a recurring booking.
/api/admin/bulk-reassignAdminBulk reassign or cancel all bookings for an employee on a date.
Body
| employeeId* | string | Employee to reassign from |
| date* | string | Date in YYYY-MM-DD |
| action* | string | "reassign" or "cancel" |
Response 200
{ "reassigned": 3, "failed": 0, "cancelled": 0 }Calendar
/api/admin/calendarAdminGet all calendar data for a day: employees, bookings, and blocked slots.
Query Parameters
| date* | string | Date in YYYY-MM-DD |
Response 200
{
"employees": [{ "id": "uuid", "name": "John" }],
"bookings": [{ "id": "uuid", "startTime": "...", "endTime": "...", "service": {...} }],
"blockedSlots": [{ "id": "uuid", "startTime": "...", "endTime": "...", "reason": "Lunch" }]
}/api/blocked-slotsAdminBlock a time slot for an employee or the entire shop.
Body
| startTime* | string | Start time (ISO) |
| endTime* | string | End time (ISO) |
| employeeId | string | Specific employee (null = shop-wide) |
| reason | string | Reason for blocking |
/api/blocked-slots?id=:idAdminRemove a blocked time slot.
Waitlist
/api/waitlistAdminList waitlist entries, optionally filtered by status.
Query Parameters
| status | string | WAITING | NOTIFIED | BOOKED | EXPIRED |
/api/waitlistAdminAdd a customer to the waitlist when their preferred slot is unavailable.
Body
| serviceId* | string | Requested service |
| preferredDate* | string | Preferred date (YYYY-MM-DD) |
| preferredTimeStart* | string | Preferred start time (HH:mm) |
| preferredTimeEnd* | string | Preferred end time (HH:mm) |
| customerName* | string | Customer name |
| customerPhone* | string | Customer phone |
| preferredEmployeeId | string | Preferred employee |
| customerEmail | string | Customer email |
/api/waitlist/:idAdminUpdate waitlist entry status.
/api/waitlist/:idAdminRemove a waitlist entry.
Settings
/api/settingsAdminGet shop settings for the current organization.
Response 200
{
"name": "City Center",
"timezone": "Europe/Amsterdam",
"slotIntervalMinutes": 30,
"bookingWindowDays": 60,
"bufferMinutes": 5,
"confirmationEmailEnabled": true,
"reminderEnabled": true,
"reminderHoursBefore": 24,
"currency": "EUR"
}/api/settingsAdminUpdate shop settings. Values are clamped to valid ranges.
Body
| name | string | Shop display name |
| timezone | string | IANA timezone (e.g. Europe/Amsterdam) |
| slotIntervalMinutes | number | Slot grid interval (5-120) |
| bookingWindowDays | number | How far ahead customers can book (1-365) |
| bufferMinutes | number | Buffer between bookings (0-60) |
| reminderHoursBefore | number | Hours before to send reminder (1-72) |
| confirmationEmailEnabled | boolean | Send confirmation emails |
| reminderEnabled | boolean | Send reminder emails |
Shops & Members
/api/admin/shopsAdminList all shops in your franchise group.
Response 200
{
"shops": [
{ "id": "uuid", "name": "City Center", "slug": "city-center", "address": "", "city": "", "isActive": true }
]
}/api/admin/shopsAdminCreate a new shop within your group. Requires OWNER role.
Body
| name* | string | Shop name |
| slug* | string | URL slug (3-48 chars, lowercase, hyphens) |
| address | string | Street address |
| city | string | City |
| postalCode | string | Postal code |
| country | string | Country code (default: NL) |
/api/admin/my-orgsAdminList all organizations you have access to (used by org switcher).
Response 200
{
"organizations": [
{ "id": "uuid", "name": "City Center", "groupName": "Jane's Barbers" }
]
}/api/admin/org-switchAdminSwitch your active organization. Updates session for subsequent requests.
Body
| organizationId* | string | Organization to switch to |
/api/admin/membersAdminList all members in your group.
/api/admin/membersAdminAdd a member to your group. Requires OWNER role.
Body
| email* | string | Email of existing user to add |
| role* | string | OWNER or ADMIN |
/api/admin/members?userId=:idAdminRemove a member from your group. Requires OWNER role. Cannot remove yourself.