Set Up and Use the REST API
Query free appointments and book appointments – straight from your own application.
The API works with JSON and is called through the address https://example.com/api.
The booking process consists of six calls that build on each other: calendar, appointment reason, day, time, form fields and finally the booking.
All calls are made from your server, not from your customers' browsers.
Step 1: Activate the API and generate a token
The API is switched off on delivery. You activate it in the admin area.
- Click Configuration in the navigation bar.
- Click General settings in the subnavigation bar.
- Click API in the list.
- Switch on API enabled. The change is saved immediately.
- Click Generate New Token to create the access token for the API.
- Copy the token that is shown right away and keep it safe, it is not displayed again.
The token starts with apm_, followed by 64 characters, and is shown only once. Only a hash is stored in the system, the token itself cannot be read out later.
There is exactly one token per installation: if you generate a new token, the previous one loses its validity immediately.
You send the token in the header of every request:
Authorization: Bearer apm_your-token
Step 2: Check the connection and query the appointment calendars
The first call checks the connection and returns the numbers of your appointment calendars.
curl -H "Authorization: Bearer apm_your-token" \
https://example.com/api/schedules
Response:
{
"data": [
{ "id": 1, "name": "Main location" },
{ "id": 2, "name": "Branch" }
]
}
You use the id of the calendar you want as the parameter schedule in all further calls.
Step 3: Query the appointment reasons
curl -H "Authorization: Bearer apm_your-token" \
"https://example.com/api/reasons?schedule=1"
Response:
{
"data": [
{
"id": 1,
"name": "Consultation",
"description": "Standard consultation",
"duration": 1800
},
{
"id": 2,
"name": "Follow-up appointment",
"description": "",
"duration": 900
}
]
}
duration is the duration in seconds (1800 seconds are 30 minutes).
You use the id as the parameter reason. If no appointment reasons are set up for a calendar, data is empty.
Step 4: Query the days with free appointments
curl -H "Authorization: Bearer apm_your-token" \
"https://example.com/api/days?schedule=1&reason=1"
Response:
{
"data": ["2026-05-23", "2026-05-24", "2026-05-26"]
}
Only days on which at least one appointment time is free are returned. How far the list reaches into the future is determined by the settings of your appointment calendar.
Step 5: Query the free times of a day
curl -H "Authorization: Bearer apm_your-token" \
"https://example.com/api/slots?schedule=1&reason=1&day=2026-05-23"
Response:
{
"data": [
"2026-05-23 09:00:00",
"2026-05-23 09:30:00",
"2026-05-23 10:00:00"
]
}
The times are local times of your installation, the format is always YYYY-MM-DD HH:MM:SS.
Step 6: Query the form fields of the booking
Which fields are needed for a booking is up to you in the scheduler. Always query the fields instead of hard-coding them in your own program.
The blank in the parameter slot must be encoded as %20.
curl -H "Authorization: Bearer apm_your-token" \
"https://example.com/api/forms?schedule=1&reason=1&slot=2026-05-23%2009:00:00"
Response:
{
"data": {
"first_name": {
"form_type": "textbox",
"input_type": "text",
"label": "First name",
"required": true,
"value": ""
},
"last_name": {
"form_type": "textbox",
"input_type": "text",
"label": "Last name",
"required": true,
"value": ""
},
"email": {
"form_type": "textbox",
"input_type": "email",
"label": "Email address",
"required": false,
"value": ""
}
}
}
All fields with "required": true must be filled in for the booking. The field password is never returned by the API.
Step 7: Book the appointment
The booking is the only call that uses the POST method. The header must contain Content-Type: application/json.
In submission you enter the values for the field names from step 6.
curl -X POST https://example.com/api/bookings \
-H "Authorization: Bearer apm_your-token" \
-H "Content-Type: application/json" \
-d '{
"schedule": 1,
"reason": 1,
"slot": "2026-05-23 09:00:00",
"submission": {
"first_name": "Hans",
"last_name": "Pitt",
"email": "hans.pitt@example.com"
}
}'
Response on success (status 201):
{
"booking_id": 142,
"booking_details_id": "a3f8c2d1e5b6",
"user_id": 87,
"slot": "2026-05-23T09:00:00Z"
}
booking_id– the number of the appointment for your own recordsbooking_details_id– the identifier your customer uses to call up the appointment detailsuser_id– the customer record created with the bookingslot– the start of the appointment, here in UTC as per ISO 8601
The appointment is now entered in the scheduler. The notification emails are sent just like for any other booking.
Error messages
Errors are returned as JSON as well, for example {"error":"Unauthorized"}.
- 400 Invalid request –
scheduleorreasonis not a number,slotdoes not have the formatYYYY-MM-DD HH:MM:SSorsubmissionis missing. - 400 Invalid JSON – the data sent is not valid JSON.
- 400 Required field empty – a required field from step 6 is missing. The field concerned is named in
field. - 401 Unauthorized – the token is missing, wrong or has been replaced by a new one. Some servers strip the
Authorizationheader; ask your provider if in doubt. - 404 Schedule/Reason/Day/Slot not found – the requested number, day or time is no longer available.
- 404 Not found – the address is wrong, or a parameter is missing or has the wrong format. Missing parameters therefore produce error 404, not 400.
- 415 Unsupported Media Type –
Content-Type: application/jsonis missing in the booking call. - 429 Too Many Requests – the limit of 300 requests per minute is reached. The header
Retry-Afternames the waiting time in seconds. - 500 Failed to create user/appointment – the appointment could not be saved.
- 503 API disabled – the API is not activated (see step 1).
- 503 Not configured – the installation is not yet complete.
Notes
- The order of the calls is binding: every call returns the value the next one needs.
- Times are sent in local time, the response of the booking contains the appointment in UTC.
- Between querying a free time and the booking, the appointment can be taken by someone else. In that case (error 404 Slot not found) query the free times again.
- Calendars and appointment reasons change rarely and can be cached. Free days and times should be queried fresh each time.
- The API is meant for communication between servers. No CORS headers are sent, so a call directly from the browser is not possible. The token must not be built into a website or an app.
- Every booking creates a customer record. Appointments made through the API are marked with the source
apiin the scheduler. - Not included at the moment: cancelling and rescheduling appointments, reading existing appointments and paginated output. For automatic messages to external systems please use the Webhooks module.
- The complete technical reference with all parameters, status codes and schemas is available under REST API Reference, the machine-readable description as per OpenAPI 3.1 as openapi.json. Both files are also part of your own installation, under
https://example.com/api/docs.htmlandhttps://example.com/api/openapi.json.