API

Booki API Reference

Complete REST API reference for Booki. Base path /api/v1 with real payloads, responses, and multi-tenant flows.

Quick Start

Base path: /api/v1/...
Environment: Subdomain-based multi-tenancy (e.g., acme.booki.app)
Auth: Bearer token via Authorization: Bearer <accessToken> header

Key Concepts

  • Tenant resolution: The Nuxt frontend auto-injects x-tenant-slug on every API request via the shared $api plugin (extracted from the subdomain). For direct/curl usage, pass X-Tenant-Slug: <slug> manually.
  • User types: admin, owner, branch-manager, customer, guest. Different endpoints and roles apply.
  • Multi-tenancy: All data scoped by organizationId. For authenticated users, organizationId comes from the JWT token (set at login). For public endpoints, it is resolved by the tenant middleware from x-tenant-slug or subdomain.
  • OTP flows: Owner registration uses a 3-step OTP flow. Customer registration is direct (no OTP).
  • Payment: Maya payment gateway integration (webhooks, checkout sessions).

How the Frontend Sends the Tenant Slug

The shared $api plugin (from codi-layer) automatically injects x-tenant-slug on every request:

// codi-layer/app/plugins/api.ts
const tenantSlug = useTenant()?.value?.slug;
if (tenantSlug) {
  options.headers.set("x-tenant-slug", tenantSlug);
}

useTenant() extracts the first subdomain from window.location.hostname:

  • janes-salon.booki.app{ slug: "janes-salon" } → header sent automatically
  • owner.booki.app → no subdomain match → header not sent (owner app uses JWT)
  • admin.booki.app → no tenant context → header not sent

For customer-booki-web-app, the Nitro server middleware also injects x-tenant-slug into proxied request headers server-side.

Tenant Resolution Priority (Backend)

The resolveTenant middleware resolves organizationId in this order:

  1. Authenticated user's organizationId (from JWT token, if logged in)
  2. ?organizationId query parameter
  3. :organizationId route parameter — direct ID from URL, no DB lookup
  4. Slug from request — checked in order: x-tenant-slug header → ?slug query param → :slug route param

For a deeper dive, see the Multi-Tenancy Guide.

organizationId Sources

ContextSourceHow
Authenticated requests (owner, branch-manager, customer)JWT token (req.user.organizationId)Embedded at login/registration — no header needed
Public / guest requestsTenant middleware (x-tenant-slug header or subdomain)Resolved via x-tenant-slug → org lookup in DB
Routes with :organizationId path paramRoute parameter (req.params.organizationId)Direct ID in URL — no DB lookup (e.g. POST /bookings/organizations/:organizationId/...)
POST /api/v1/auth/loginOptional tenantIf x-tenant-slug present → scoped login; if absent → owner/admin global login

User Type Access Overview

AppUser TypeRole(s)API Sections
cms-booki-web-appGuest / PublicAuth (register owner), Tenant, Bookings (public), Packages (public), Business Hours (public), Services
customer-booki-web-appCustomercustomerAuth (login, register customer), Bookings (authenticated), Users (profile), Maya (checkout), User Payment Methods
owner-booki-web-appOwner / Branch Managerowner, branch-managerAuth (login), Organizations, Branches, Packages, Business Hours (owner), Owner Bookings, Owner Customers, Maya (webhook), Integrations, Subscription
admin-booki-web-appAdminadminAuth (login), Admin Billing, Admin Organizations, User Management

API Modules

Guest / Public — cms-booki-web-app

Customer — customer-booki-web-app

Owner / Branch Manager — owner-booki-web-app

Admin — admin-booki-web-app

Guides & Patterns


All pages include real request payloads, response examples, and curl commands.
For exact validation rules, see booki-api/src/validations/.