Online booking for digital assistants
Use these public lookup endpoints to find treatments, employees and available appointments. Then give the customer a prefilled booking link. The customer selects a time, enters their personal details and confirms the booking on the booking page.
Download the OpenAPI description (JSON)
Recommended workflow
- Load treatments and packages using
gettreatments. Match the customer's requested treatment toNameHomepageand check its category and description. - Load employees using
getcontacts. If the customer requests Sarah, find Sarah in this response and use her currentId. If several entries match, ask which employee they mean. - Call
gettimeswith the selected treatment or package, the earliest search date and the chosen employee's ID. - Describe the returned times to the customer and provide a prefilled booking link with the same treatment, date and employee.
- The customer chooses a time and completes the booking. A lookup or a prefilled link does not reserve a time or create a booking.
Always use IDs returned by the current API responses. Example IDs below are illustrative;
employee 216 is not asserted to be Sarah. If no times are found for the requested employee,
report that result and ask before searching with a different employee.
API endpoints
The API base is the same origin as the booking page. For FACE & BODY Day Spa it is
https://www.dayspa.faceandbody.de. All three lookup endpoints use POST,
even though they only retrieve information. They do not require a booking login or Bearer token.
Send Accept: application/json.
1. Treatments and packages
POST /module/booksystem/calendaritems/gettreatments/ — no request parameters.
curl --request POST \
--header 'Accept: application/json' \
'https://www.dayspa.faceandbody.de/module/booksystem/calendaritems/gettreatments/'
The response is a JSON array. Abbreviated, illustrative example:
[
{
"Id": 22,
"Mode": 1,
"Category": "Facial treatments",
"NameHomepage": "Example facial treatment",
"PriceGross": 95.00,
"AttributeItems": "",
"DescriptionHomepage": "Example description",
"CategoryDescriptionHomepage": ""
}
]
Mode = 1 means a service; Mode = 2 means a package.
For availability, construct each item as Mode_Id:
service 22 becomes 1_22, package 22 becomes 2_22.
For booking links, these become t=22 and t=p22, respectively.
2. Employees
POST /module/booksystem/calendaritems/getcontacts/ — no request parameters.
curl --request POST \
--header 'Accept: application/json' \
'https://www.dayspa.faceandbody.de/module/booksystem/calendaritems/getcontacts/'
The response is a JSON array. Use Id for filtering and Name as the display name.
Names may include a surname or initial to distinguish employees with the same first name.
An abbreviated, illustrative response is:
[
{ "Id": 216, "Name": "Example employee", "Firstname": "Example", "Lastname": "Employee" }
]
Being listed here does not guarantee availability for every treatment. Query gettimes
with the chosen treatment and employee together.
3. Available appointments
POST /module/booksystem/calendaritems/gettimes/ — send a JSON object with
Content-Type: application/json:
| Field | Value |
|---|---|
Items | A nonempty array of Mode_Id strings, such as ["1_22"] or ["2_22"]. Multiple items are supported for the availability search. |
DateTime | Earliest search date. Use dd.MM.yyyy on this German booking installation, for example 09.12.2026. This API field differs from the ISO date used in booking links. |
PersonId | The employee's integer Id. Omit it or send null for any employee. Keep the specific ID when the customer requested an employee. |
curl --request POST \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"Items":["1_22"],"DateTime":"09.12.2026","PersonId":216}' \
'https://www.dayspa.faceandbody.de/module/booksystem/calendaritems/gettimes/'
This endpoint returns a JSON string containing a JSON array. Parse the HTTP response as JSON, then parse that string again. Illustrative response body as sent over HTTP:
"[{\"DateString\":\"09.12.2026\",\"DayString\":\"Mi\",\"TimeString\":\"10:00\"}]"
After the second parse:
[
{ "DateString": "09.12.2026", "DayString": "Mi", "TimeString": "10:00" }
]
These are local business dates and times, without a UTC offset. The response does not contain an employee ID;
retain the employee filter from your request. An empty result is the JSON string "[]".
Availability can change before the customer finishes booking.
Prefilled booking links
Append the following query parameters to the actual booking page URL:
| Parameter | Meaning |
|---|---|
t | One service ID, for example 22, or a package ID prefixed with p, for example p22. This differs from the API's Items format. |
date | Earliest search date in YYYY-MM-DD format. It starts the search on or after this date; it does not select an appointment. |
employee | Optional employee ID from getcontacts. Include it when the customer wants a specific employee. |
FACE & BODY example (replace the illustrative IDs with current results):
https://www.dayspa.faceandbody.de/de/online-buchen/?t=22&date=2026-12-09&employee=216
For a package, use ?t=p22&date=2026-12-09&employee=216.
A link prefills a single service or package. There is no supported time-selection parameter and no
multi-service link format. The customer selects a time and completes the booking in a JavaScript-enabled browser.
Other installations can have a different booking page path.
Response handling
Check HTTP status codes and validate the response shape. In particular, gettimes can return
an error message inside a JSON string even with HTTP status 200. A parsing error or an unexpected
response is a failed lookup, not evidence that no appointments exist.
async function findAppointments(baseUrl, serviceId, employeeId, earliestDate) {
const response = await fetch(new URL('/module/booksystem/calendaritems/gettimes/', baseUrl), {
method: 'POST',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({
Items: ['1_' + serviceId],
DateTime: earliestDate, // dd.MM.yyyy, for example '09.12.2026'
PersonId: employeeId
})
});
if (!response.ok) throw new Error('Availability lookup failed');
const encoded = await response.json();
if (typeof encoded !== 'string') throw new Error('Unexpected availability response');
const times = JSON.parse(encoded);
if (!Array.isArray(times) || !times.every(time =>
time && typeof time.DateString === 'string' &&
typeof time.DayString === 'string' && typeof time.TimeString === 'string'
)) throw new Error('Unexpected appointment data');
return times;
}
Field names are case-sensitive for clients reading the returned JSON: use Id, Name,
DateString, DayString and TimeString as shown.
Query the booking site's own origin. Browser integrations on other origins depend on that site's CORS policy.