Developer documentation
The BookAppointment API and webhooks
A small, honest REST API over your own account data, and signed webhooks when things change. Read and create appointments, list your services and team, and keep your CRM, spreadsheet or back-office system in step. Included on the Business package.
Getting started
Authentication in three steps
Every request is authenticated with a key you create in your own admin. Keys are shown once and stored only as a scrambled copy, so keep them server-side — never in browser code. Prefer to click than to curl? Settings → API & webhooks has an API playground that runs any of these requests against your own data and shows the response.
1. Create a key
Settings → API & webhooks → New key. Name it after the system that will use it and tick only the permissions it needs.
2. Send it as a bearer token
Add Authorization: Bearer ba_live_… to every request. All endpoints live under /api/public/v1 and return JSON.
3. Subscribe to events
Add an https endpoint, tick the events you want, send a test delivery and watch the delivery log.
https://www.bookappointment.co.uk/api/public/v1curl "https://www.bookappointment.co.uk/api/public/v1/services" \
-H "Authorization: Bearer ba_live_your_key"Reference
Endpoints
Rate-friendly by design: list endpoints return up to 200 records. Pass a narrower date range rather than paging through the whole diary.
Appointments that start inside a date range. Defaults to the next 30 days. Optional query parameters: from, to (ISO 8601 timestamps) and status. Returns up to 200 rows, earliest first.
curl "https://www.bookappointment.co.uk/api/public/v1/bookings?from=2026-09-01T00:00:00Z&to=2026-09-08T00:00:00Z" \
-H "Authorization: Bearer ba_live_your_key"{
"data": [
{
"id": "1f3c...",
"start_at": "2026-09-03T09:30:00+00:00",
"end_at": "2026-09-03T10:00:00+00:00",
"status": "confirmed",
"payment_status": "paid",
"service_id": "8a12...",
"staff_id": "b904...",
"location_id": null,
"customer_name": "James Barnes",
"customer_phone": "+447700900123",
"customer_email": "james@example.com",
"notes": null,
"created_at": "2026-08-28T18:04:11+00:00"
}
]
}Create an appointment. The end time is worked out from the service duration, and double bookings are rejected with a 409. A booking.created webhook fires on success.
curl -X POST "https://www.bookappointment.co.uk/api/public/v1/bookings" \
-H "Authorization: Bearer ba_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"service_id": "8a12...",
"staff_id": "b904...",
"start_at": "2026-09-03T09:30:00Z",
"customer_name": "James Barnes",
"customer_phone": "+447700900123",
"customer_email": "james@example.com",
"notes": "Requested the usual"
}'{
"data": {
"id": "1f3c...",
"start_at": "2026-09-03T09:30:00+00:00",
"end_at": "2026-09-03T10:00:00+00:00",
"status": "confirmed"
}
}Permissions
bookings.readRead appointments in a date range or by id.bookings.writeCreate, cancel and reschedule appointments.customers.readRead customer records, by search or by id.services.readRead services, durations and prices.staff.readRead team members.locations.readRead your locations/branches.availability.readRead free bookable slots for a service and date.classes.readRead the class timetable with spaces booked (gym & padel add-ons).courts.readRead courts and court bookings (padel add-on).memberships.readRead membership plans and members (gym & padel add-ons).
Errors
401Missing, unknown or revoked API key.403The key is valid but does not carry the permission the endpoint needs.404The service or team member in your request does not belong to this account.409The requested slot clashes with an existing booking.422The body failed validation — the message names the problem field.500Something went wrong on our side. Retry with backoff.
Errors are returned as { "error": "message" }.
Webhooks
Get told the moment something changes
Add as many https endpoints as you like, each with its own signing secret and its own list of events. Deliveries are logged with the response we got back, and you can resend a test at any time.
Events
booking.createdA new appointment is made online, in the admin, by the AI assistant or through the API.booking.updatedAn appointment is moved, rescheduled or its details change.booking.cancelledAn appointment is cancelled by the customer or the business.customer.createdA new customer record is added to the account.payment.succeededA card payment, deposit or Tap to Pay charge completes.
POST https://your-app.example.com/hooks/bookappointment
content-type: application/json
x-bookappointment-event: booking.created
x-bookappointment-signature: t=1789200000,v1=6f2a…{
"event": "booking.created",
"created_at": "2026-09-03T09:30:04.221Z",
"data": {
"booking": {
"id": "1f3c...",
"start_at": "2026-09-03T09:30:00+00:00",
"end_at": "2026-09-03T10:00:00+00:00",
"status": "confirmed"
}
}
}Verify the signature
The signature header carries a timestamp and an HMAC-SHA256 of timestamp.rawBody, signed with your endpoint's secret. Compare it against the raw request body before you trust the payload, and reject anything older than a few minutes.
import crypto from "node:crypto";
export function verify(rawBody: string, header: string, secret: string) {
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("=") as [string, string]),
);
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}Retries and replay
We make a single delivery attempt per event — there is no automatic retry, so your endpoint should respond quickly and return a 2xx status once it has queued the work. Every attempt is written to the delivery log with its response status and body, so you can see exactly what we sent and what came back. From that log you can resend any delivery on demand with the Test action, which replays the same event to your endpoint — useful after fixing a bug on your side. Because there are no retries, treat webhooks as a convenience notification rather than the only way data reaches your system: the REST API is always the source of truth if a delivery is missed.
Ready to connect your systems?
API access and webhooks are included on the Business package. Not sure whether the API or a no-code automation tool suits you better? Talk to us and we'll point you the right way.