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/api

Authentication

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.

Public No auth neededAdmin Session required

Authentication

POST/api/registerPublic

Create a new user account. Optionally create an organization group and first shop.

Body

name*stringUser's full name
email*stringUnique email address
password*stringAccount password
phonestringPhone number
isAdminbooleanCreate as shop admin (default: false)
businessNamestringFranchise group name (required if isAdmin)
businessSlugstringURL slug for the group (required if isAdmin)
shopNamestringFirst shop name (required if isAdmin)
shopSlugstringURL 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

GET/api/slotsPublic

Get available time slots for a service on a given date. Returns sorted HH:mm strings.

Query Parameters

organizationId*stringOrganization (shop) ID
serviceId*stringService to check availability for
date*stringDate in YYYY-MM-DD format
employeeIdstringFilter by specific employee

Response 200

{
  "slots": ["09:00", "09:30", "10:00", "10:30", "11:00"]
}
POST/api/bookingsPublic

Create a new booking. Validates employee availability, working hours, buffer times, and blocked slots.

Body

organizationId*stringOrganization (shop) ID
serviceId*stringService being booked
date*stringDate in YYYY-MM-DD format
startTime*stringStart time in HH:mm format
customerName*stringCustomer name
customerPhone*stringCustomer phone
employeeIdstringPreferred employee (auto-assigned if omitted)
customerEmailstringFor confirmation email
notesstringBooking 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"
  }
}
GET/api/public/settingsPublic

Get public booking settings for a shop (no auth required).

Query Parameters

organizationId*stringOrganization (shop) ID

Response 200

{
  "name": "City Center",
  "bookingWindowDays": 60,
  "slotIntervalMinutes": 30,
  "currency": "EUR"
}

Employees

GET/api/employeesAdmin

List active employees. In public context, pass organizationId as query param.

Query Parameters

serviceIdstringFilter by service capability
organizationIdstringOrg ID (public context)
includeNextAvailablebooleanInclude next available slot (checks 7 days)

Response 200

{
  "employees": [
    { "id": "uuid", "name": "John", "imageUrl": null, "nextAvailable": "Today, 10:00" }
  ]
}
POST/api/employeesAdmin

Create a new employee with optional service assignments.

Body

name*stringEmployee name
emailstringEmployee email
imageUrlstringProfile image URL
serviceIdsstring[]Services this employee can perform

Response 201

{ "employee": { "id": "uuid", "name": "John", ... } }
PUT/api/employees/:idAdmin

Update employee details and service assignments.

Body

namestringEmployee name
emailstringEmployee email
isActivebooleanActive status
serviceIdsstring[]Replace service assignments
DELETE/api/employees/:idAdmin

Soft-delete an employee (sets isActive to false).

PUT/api/employees/:id/scheduleAdmin

Replace an employee's weekly schedule.

Body

schedule*arrayArray of { dayOfWeek (1-7 ISO), startTime (HH:mm), endTime (HH:mm) }
POST/api/employees/:id/exceptionsAdmin

Create a schedule exception (day off or custom hours).

Body

date*stringDate in YYYY-MM-DD
isBlocked*booleanTrue = day off, False = custom hours
startTimestringCustom start time (HH:mm)
endTimestringCustom end time (HH:mm)
reasonstringReason for exception

Services

GET/api/servicesAdmin

List 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
    }
  ]
}
POST/api/servicesAdmin

Create a new service.

Body

name*stringService name
durationMinutes*numberDuration in minutes
priceInCents*numberPrice in cents (e.g. 3500 = 35.00)
descriptionstringService description
imageUrlstringService image
PUT/api/services/:idAdmin

Update a service.

DELETE/api/services/:idAdmin

Soft-delete a service (sets isActive to false).

Bookings

GET/api/bookings/:idAdmin

Get booking details by ID.

Response 200

{
  "booking": {
    "id": "uuid", "referenceCode": "BK-a1b2c3",
    "status": "CONFIRMED", "startTime": "...", "endTime": "...",
    "service": { "name": "Haircut" },
    "employee": { "name": "John" }
  }
}
PUT/api/bookings/:idAdmin

Update a booking. Set status to CANCELLED to trigger cancellation flow (email + waitlist notification).

Body

statusstringCONFIRMED | CANCELLED | COMPLETED | NO_SHOW
employeeIdstringReassign to another employee
startTimestringReschedule start time (ISO)
endTimestringReschedule end time (ISO)
POST/api/bookings/:id/repeatAdmin

Create the next occurrence of a recurring booking.

POST/api/admin/bulk-reassignAdmin

Bulk reassign or cancel all bookings for an employee on a date.

Body

employeeId*stringEmployee to reassign from
date*stringDate in YYYY-MM-DD
action*string"reassign" or "cancel"

Response 200

{ "reassigned": 3, "failed": 0, "cancelled": 0 }

Calendar

GET/api/admin/calendarAdmin

Get all calendar data for a day: employees, bookings, and blocked slots.

Query Parameters

date*stringDate in YYYY-MM-DD

Response 200

{
  "employees": [{ "id": "uuid", "name": "John" }],
  "bookings": [{ "id": "uuid", "startTime": "...", "endTime": "...", "service": {...} }],
  "blockedSlots": [{ "id": "uuid", "startTime": "...", "endTime": "...", "reason": "Lunch" }]
}
POST/api/blocked-slotsAdmin

Block a time slot for an employee or the entire shop.

Body

startTime*stringStart time (ISO)
endTime*stringEnd time (ISO)
employeeIdstringSpecific employee (null = shop-wide)
reasonstringReason for blocking
DELETE/api/blocked-slots?id=:idAdmin

Remove a blocked time slot.

Waitlist

GET/api/waitlistAdmin

List waitlist entries, optionally filtered by status.

Query Parameters

statusstringWAITING | NOTIFIED | BOOKED | EXPIRED
POST/api/waitlistAdmin

Add a customer to the waitlist when their preferred slot is unavailable.

Body

serviceId*stringRequested service
preferredDate*stringPreferred date (YYYY-MM-DD)
preferredTimeStart*stringPreferred start time (HH:mm)
preferredTimeEnd*stringPreferred end time (HH:mm)
customerName*stringCustomer name
customerPhone*stringCustomer phone
preferredEmployeeIdstringPreferred employee
customerEmailstringCustomer email
PUT/api/waitlist/:idAdmin

Update waitlist entry status.

DELETE/api/waitlist/:idAdmin

Remove a waitlist entry.

Settings

GET/api/settingsAdmin

Get 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"
}
PUT/api/settingsAdmin

Update shop settings. Values are clamped to valid ranges.

Body

namestringShop display name
timezonestringIANA timezone (e.g. Europe/Amsterdam)
slotIntervalMinutesnumberSlot grid interval (5-120)
bookingWindowDaysnumberHow far ahead customers can book (1-365)
bufferMinutesnumberBuffer between bookings (0-60)
reminderHoursBeforenumberHours before to send reminder (1-72)
confirmationEmailEnabledbooleanSend confirmation emails
reminderEnabledbooleanSend reminder emails

Shops & Members

GET/api/admin/shopsAdmin

List all shops in your franchise group.

Response 200

{
  "shops": [
    { "id": "uuid", "name": "City Center", "slug": "city-center", "address": "", "city": "", "isActive": true }
  ]
}
POST/api/admin/shopsAdmin

Create a new shop within your group. Requires OWNER role.

Body

name*stringShop name
slug*stringURL slug (3-48 chars, lowercase, hyphens)
addressstringStreet address
citystringCity
postalCodestringPostal code
countrystringCountry code (default: NL)
GET/api/admin/my-orgsAdmin

List all organizations you have access to (used by org switcher).

Response 200

{
  "organizations": [
    { "id": "uuid", "name": "City Center", "groupName": "Jane's Barbers" }
  ]
}
POST/api/admin/org-switchAdmin

Switch your active organization. Updates session for subsequent requests.

Body

organizationId*stringOrganization to switch to
GET/api/admin/membersAdmin

List all members in your group.

POST/api/admin/membersAdmin

Add a member to your group. Requires OWNER role.

Body

email*stringEmail of existing user to add
role*stringOWNER or ADMIN
DELETE/api/admin/members?userId=:idAdmin

Remove a member from your group. Requires OWNER role. Cannot remove yourself.

Ready to integrate?

Create your account and start building.

Get Started