Two ways to integrate
Pick the path that matches what you’re building:Public Booking API
Build a custom booking UI: read the business’s services and pricing, show real availability, and create scheduled orders or leads. This is what the rest of this reference documents.
Website lead capture
Just want website form submissions to land in the CRM as leads? Copy the ready-made embed snippet from Settings → Website Leads — no custom code required.
The Public Booking API uses a per-tenant token for access control. There are no API keys or bearer tokens to manage.
Authentication & tokens
Every endpoint is scoped by a token in the URL path — there is noAuthorization header. Two kinds of token are accepted, and either works on every endpoint:
The token must match
^[a-zA-Z0-9_-]{1,255}$. A malformed token returns 400 invalid_token; a well-formed token that doesn’t resolve to a tenant with booking enabled returns 404 not_found.
Base URL
How it works
All booking API endpoints share the same path prefix:{token} with your booking slug or lead token. The three endpoints cover the full booking flow:
Get config
Fetch services, body types, pricing, and page branding.
Get availability
Return open time slots for a given date.
Submit booking
Create an order or lead from customer input.
Rate limiting
The submit endpoint is rate limited to 5 requests per 10 minutes per IP address to prevent abuse. All other endpoints are unrestricted.CAPTCHA requirement
The submit endpoint requires a Cloudflare Turnstile CAPTCHA token in the request body (theturnstile_token field). Add the Turnstile widget to your page and pass the token when submitting.
The booking page token is separate from Cloudflare Turnstile. Your Turnstile site key is configured by Cloudflare — the booking token comes from your CRM settings.
Order vs. lead creation
When a booking is submitted, the CRM creates either an order or a lead depending on how the tenant has configured their booking page:
Either way, a successful
submit returns { "success": true, "confirmation_message": ... }. The record (order or lead) appears in the business’s workspace immediately.
End-to-end integration flow
A complete custom booking integration walks through the three endpoints in order. The config call gives you everything to render the form; availability narrows it to a bookable slot; submit creates the record.1
Fetch config
GET /config once on page load. Use the response to render your service list, vehicle body-type selector (for auto businesses), currency, and branding. Cache it for the session — it rarely changes.2
Render services and body types
Build the form from
services[] (id, name, base_price, estimated_duration) and, for auto businesses, body_types[] (id, name, surcharge_percent). Compute the displayed price as base_price × (1 + surcharge_percent/100) when a body type is selected.3
Fetch availability
When the customer picks a date, call
GET /availability?date=YYYY-MM-DD&service_ids=.... Pass the selected service IDs so slot length matches the real job duration. Render the returned slots[]; an empty array means no openings that day.4
Submit the booking
Collect a Turnstile token, then
POST /submit with the customer object, service_ids, the chosen slot start as date, and optional vehicle/membership/notes. On 200, show confirmation_message.5
Handle errors
Map the documented error codes to user-facing messages — most importantly
409 slot_unavailable (the slot was taken while the customer filled the form; re-fetch availability) and 429 too_many_requests (rate limited; ask them to retry shortly).End-to-end flow
Security model
The booking API is intentionally public — it’s meant to be called from a customer’s browser on any domain — so it does not rely on a secret API key. Instead, several layers work together to keep it safe to expose:
Because of these layers, the endpoints safely send
Access-Control-Allow-Origin: * — they can be called from any domain, which is what a public booking widget requires. The wide-open CORS header is not the security boundary; the token, Turnstile, rate limiting, and server-side validation are. Treat the booking token as public (it’s visible in your page source by design) and never put any secret CRM credential in front-end code.