View as Markdown

Widget API overview

With the Widget API you build your own booking experience: a fully custom booking flow on your site, or a native app. It is for when the booking widget cannot be shaped into what you need. It is the API that Cliento's own widget runs on.

It is a JSON API called straight from the customer's browser. It needs no API key, and one account id is all you need to start.

ToRead
See a whole booking from start to finishBooking flow
Load the account's services, resources and settingsSettings and ref-data
Find free timesAvailability
Reserve a time, add the customer and confirmCreating a booking
Look up or cancel a booking afterwardsRetrieving and cancelling a booking
Take payment when the account requires itPayments and Payment endpoints
Show the account's reviewsReviews

If you are new to the API, start with the Booking flow guide.

Base URL

All endpoints in this documentation are relative to the following base URL:

https://apibk.cliento.com/api/v2/partner/cliento/{id}

The id identifies your Cliento account, which is one location of a business. It is the same id the booking widget uses. You will find it in Cliento (go to Admin > Onlinebokning > Bokningssida / Widget).

For example, to fetch the services and resources of the account 1uAKYvE7mWcnxxdMuixis:

curl https://apibk.cliento.com/api/v2/partner/cliento/1uAKYvE7mWcnxxdMuixis/ref-data/

Authentication

The API does not use API keys. Requests are unauthenticated, and the account is identified by the id in the URL. Calls are made directly from the customer's browser and CORS is open for any origin, so you need no server of your own.

Send these headers on every request:

HeaderValue
Acceptapplication/json
Content-Typeapplication/json (for POST requests)

API stability

The API is not versioned. It is the API behind Cliento's own widget and it changes when the widget does. Changes are made with care, but expect to update a custom client when the API changes. Accept responses with fields you do not know, and ignore them.

Rate limits

The API is rate limited. Normal customer behaviour stays well within the limits. A limited request returns 429 with a Retry-After header and a body like {"key": "retry", "retryAfterSeconds": 30}. Wait that long and repeat the same call. Do not poll the status endpoint more often than every few seconds.

Captcha

Some accounts require a Google reCAPTCHA v3 token on the booking requests. They have web_requiresCaptcha set to true in their settings. The token goes in the captchaResponse field of /booking/reserve, /booking/customer, /booking/confirm and /booking/pay. For an account without the setting, send null.

The captcha uses Cliento's reCAPTCHA site key, and reCAPTCHA only issues tokens on domains registered for that key. Before your client goes live on an account with captcha, tell us in the chat at the bottom of the page which domains your booking UI runs on. Cliento registers them and gives you the site key. Then:

// Load https://www.google.com/recaptcha/api.js?render={siteKey}
const token = await grecaptcha.execute(siteKey, { action: 'confirm' });
// send as captchaResponse

Fetch a fresh token for every request: tokens are single use and short lived. The widget uses the action reserve for /booking/reserve, customer for /booking/customer and confirm for /booking/confirm and /booking/pay. A rejected token returns 400 with code 0 and the message Captcha failed.

Errors

Successful responses use 200, 201 or 204. Error responses use standard HTTP status codes. 400 responses have a JSON body with a numeric code, a message and details, for example {"code": 3, "message": "Reservation not found for uuid: …", "details": ""}. Other error responses have a short plain text body or no body at all.

StatusMeaning
400The request body or parameters are invalid, or the request was rejected by the captcha. The body is JSON with code, message and details
402Payment required or a payment result, see Payments
403Not allowed: a wrong PIN, an unknown reservation on /booking/pay, or a cancellation past the deadline. Usually an empty body
404Unknown account id or entity. Also a reservation that was released, or has expired and been removed
409Conflict, the operation is not possible in the current state
410From /booking/reserve, the slot is no longer available. From /booking/{cbUuid}/status, the reservation is gone: released, or expired and removed. For a reservation that is gone, /booking/pay answers 403 and the other calls answer 404
418The request was refused. From /booking/confirm and /booking/pay the reservation is gone as well: reserve a new slot
429Rate limited, see Rate limits

Endpoints

MethodPathDescription
GET/settings/Booking settings for the account
GET/ref-data/Services, resources and mappings
GET/custom-fields/resource/{resourceHashId}Custom form fields
GET/resources/slotsAvailable slots
POST/booking/reserveReserve a slot
POST/booking/releaseRelease a reservation
POST/booking/customerAdd customer details
POST/booking/confirmation-optionsGet confirmation options
POST/booking/confirmConfirm the booking
POST/booking/payment-providerChoose payment provider
POST/booking/payPay and confirm
POST/booking/{cbUuid}/statusBooking status
POST/klarna/sessionCreate a Klarna session
POST/booking/validate-voucherValidate a voucher
POST/booking/voucherApply or remove a voucher
GET/reviews/Reviews

The payment endpoints are only used when the account requires online payment, see Payments.

Two more endpoints retrieve and cancel an existing booking. They are not under the account base URL: the {ref} in the path identifies the booking by itself. See Retrieving and cancelling a booking.

MethodPathDescription
GEThttps://apibk.cliento.com/api/v2/booking/{ref}Retrieve a booking
DELETEhttps://apibk.cliento.com/api/v2/booking/{ref}Cancel a booking