Public booking API
Three endpoints, all under /api/public/booking/.
GET service info
GET /api/public/booking/:agencyId/:clientId/:serviceIdReturns:
{
"agency": {
"name": "Acme Salons",
"logoUrl": "https://...",
"primaryColor": "#4f46e5",
"supportEmail": "hello@acme-salons.com",
"supportPhone": "+91 ..."
},
"client": {
"name": "Main Branch",
"logoUrl": null
},
"service": {
"name": "Haircut",
"description": "30-min cut + style",
"durationMinutes": 30,
"bufferMinutes": 5,
"priceAmountCents": 50000,
"priceCurrency": "inr",
"color": "#4f46e5"
}
}GET available slots
GET /api/public/booking/:agencyId/:clientId/:serviceId/slots?from=[iso]&to=[iso]Returns:
{
"slots": [
{ "startAt": "2026-06-01T03:30:00.000Z", "endAt": "2026-06-01T04:00:00.000Z", "remainingCapacity": 1 },
{ "startAt": "2026-06-01T04:00:00.000Z", "endAt": "2026-06-01T04:30:00.000Z", "remainingCapacity": 1 }
]
}Window cap: 60 days. Returns 503 with "No business hours configured" if the
client hasn’t set hours yet.
POST create booking
POST /api/public/bookings
Content-Type: application/json
{
"agencyId": 3,
"clientId": 8,
"serviceId": 42,
"startAt": "2026-06-01T03:30:00.000Z",
"customerName": "Raj",
"customerPhone": "+91 98765 43210",
"customerEmail": "raj@example.com"
}Success → 200:
{
"ok": true,
"booking": {
"id": 1234,
"startAt": "2026-06-01T03:30:00.000Z",
"endAt": "2026-06-01T04:00:00.000Z",
"serviceName": "Haircut",
"status": "CONFIRMED",
"cancelToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}Use cancelToken to build the self-service cancel URL:
https://[agency]/book/cancel?t=[cancelToken]Errors:
400— invalid input / past slot / missing fields404— service not found409— slot just taken (race) → ask the customer to pick another429— rate limit hit; retry afterRetry-After503— business hours not configured / Google Calendar not connected
Last updated on