clndr.pro API
The clndr.pro REST API puts your booking pages on your own site. List your booking pages, read the open time slots for a day, and create bookings from a browser or a server. From a server you can also list, confirm and cancel the bookings that come in.
Base URL: https://www.clndr.pro/api/v1
Use the www host. https://clndr.pro redirects to it, and HTTP clients drop the Authorization header when they follow a redirect to another host, so requests to the bare domain fail with 401 Missing API key.
Authentication
Send an API key with every request, as a bearer token or in the x-clndr-key header:
Authorization: Bearer clndr_sk_4f1c…Create keys in the clndr.pro dashboard under API Keys. A key belongs to the clndr.pro account that created it and only ever sees that account's booking pages and bookings. See API keys for rotation and storage.
| Key type | Prefix | Use it in | Default scopes |
|---|---|---|---|
| Secret | clndr_sk_ | Your server only | booking_pages:read booking_pages:slots bookings:create bookings:read bookings:write |
| Publishable | clndr_pk_ | Browsers and mobile apps | booking_pages:read booking_pages:slots bookings:create |
Scopes
| Scope | Allows |
|---|---|
booking_pages:read | List booking pages and read one with its questions |
booking_pages:slots | Read open time slots |
bookings:create | Create a booking on one of your pages |
bookings:read | List and read bookings (guest names and emails included) |
bookings:write | Confirm and cancel bookings |
A request without a required scope gets 403. Publishable keys can never hold bookings:read or bookings:write.
Errors
Errors return a JSON body with a human-readable message:
{ "error": "Booking page not found" }| Status | Meaning |
|---|---|
400 | The request is malformed: a missing field, invalid JSON, a bad email address or timestamp. The message names it. |
401 | The key is missing, unknown, revoked or expired. |
403 | The key lacks a scope, or the booking page belongs to another account. |
404 | No such booking page or booking for this key's account. |
409 | The slot is taken, or (with a publishable key) isn't one the slots endpoint offers. Fetch the slots again. |
429 | Rate limit hit: the key's per-minute limit (wait Retry-After seconds), or the guest email's 5 bookings an hour. |
500 | Something failed on our side. Retry with backoff. |
Rate limits
Limits are per key, in fixed 60-second windows: 300 requests for secret keys and 120 for publishable keys. A 429 carries Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds). Successful responses don't carry these headers.
Separately, one guest email address can create at most 5 bookings an hour.
CORS
Every endpoint answers preflight requests with Access-Control-Allow-Origin: *, so a publishable key works from any origin.
Dates and times
Timestamps are ISO 8601 in UTC, for example 2026-10-15T13:30:00.000Z. Format them in the guest's timezone when you display them. A host's own timezone is userProfile.timezone on Get a booking page.
Field names
Request bodies use camelCase (guestEmail). Response objects are database rows and use snake_case (guest_email). The TypeScript SDK has types for all of them.