REST-API Referenz
Alle Aufrufe mit Parametern, Statuscodes und Schemas.
Diese Seite beschreibt die Schnittstelle vollständig. Wenn Sie die API zum ersten Mal einrichten, beginnen Sie besser mit der Schritt-für-Schritt-Anleitung.
Die Basisadresse ist /api auf Ihrer eigenen Installation, in den Beispielen also https://example.com/api.
Alle Aufrufe erfolgen von Ihrem Server aus, nicht aus dem Browser Ihrer Kunden: Es werden keine CORS-Kopfzeilen gesendet, und das Token darf nicht in eine Website oder App eingebaut werden.
Auf dieser Seite
- Authentifizierung
- GET /schedules
- GET /reasons
- GET /days
- GET /slots
- GET /forms
- POST /bookings
- Schemas
- Gemeinsame Fehlerantworten
- Maschinenlesbare Beschreibung
Authentifizierung
Jeder Aufruf benötigt ein Token. Sie erzeugen es im Administrationsbereich unter Konfiguration → API.
Das Token beginnt mit apm_, gefolgt von 64 Zeichen, und wird nur ein einziges Mal angezeigt.
Es gibt genau ein Token pro Installation: Ein neues Token entwertet das bisherige sofort.
Authorization: Bearer apm_ihr-token
Ohne gültiges Token antwortet jeder Aufruf mit 401 {"error":"Unauthorized"}.
Ist die API im Administrationsbereich nicht aktiviert, antwortet sie mit 503 API disabled.
GET/schedules
Liefert alle Terminkalender der Installation. Die zurückgegebenen id-Werte verwenden Sie in allen weiteren Aufrufen als Parameter schedule.
Statuscodes
| Status | Bedeutung |
|---|---|
| 200 | Liste der Terminkalender |
| 401 | Token fehlt oder ist ungültig |
| 429 | Anfragelimit erreicht |
| 503 | Die API ist nicht aktiviert oder die Installation ist noch nicht abgeschlossen |
Antwort 200
{
"data": [
{ "id": 1, "name": "Hauptstandort" },
{ "id": 2, "name": "Filiale" }
]
}
Aufruf mit curl
curl -H "Authorization: Bearer apm_ihr-token" \
https://example.com/api/schedules
GET/reasons
Liefert die Termingründe (Leistungen) eines Terminkalenders. Sind für den Kalender keine Termingründe eingerichtet, ist data ein leeres Array. duration ist die Dauer in Sekunden.
Query-Parameter
| Name | Typ | Pflicht | Beschreibung | Beispiel |
|---|---|---|---|---|
schedule |
integer ≥ 1 | Pflicht | Nummer des Terminkalenders aus GET /schedules |
1 |
Statuscodes
| Status | Bedeutung |
|---|---|
| 200 | Liste der Termingründe (kann leer sein) |
| 401 | Token fehlt oder ist ungültig |
| 404 | Terminkalender nicht gefunden |
| 429 | Anfragelimit erreicht |
| 503 | Die API ist nicht aktiviert oder die Installation ist noch nicht abgeschlossen |
Antwort 200
{
"data": [
{
"id": 1,
"name": "Beratungsgespräch",
"description": "Standardberatung",
"duration": 1800
},
{
"id": 2,
"name": "Folgetermin",
"description": "",
"duration": 900
}
]
}
Aufruf mit curl
curl -H "Authorization: Bearer apm_ihr-token" \
"https://example.com/api/reasons?schedule=1"
GET/days
Liefert die Tage, an denen für diesen Terminkalender und Termingrund mindestens eine Uhrzeit frei ist. Das Format ist JJJJ-MM-TT. Wie weit die Liste in die Zukunft reicht, bestimmen die Einstellungen des Terminkalenders.
Query-Parameter
| Name | Typ | Pflicht | Beschreibung | Beispiel |
|---|---|---|---|---|
schedule |
integer ≥ 1 | Pflicht | Nummer des Terminkalenders | 1 |
reason |
integer ≥ 1 | Pflicht | Nummer des Termingrunds aus GET /reasons |
1 |
Statuscodes
| Status | Bedeutung |
|---|---|
| 200 | Liste der Tage mit freien Terminen |
| 401 | Token fehlt oder ist ungültig |
| 404 | Terminkalender oder Termingrund nicht gefunden |
| 429 | Anfragelimit erreicht |
| 503 | Die API ist nicht aktiviert oder die Installation ist noch nicht abgeschlossen |
Antwort 200
{
"data": ["2026-05-23", "2026-05-24", "2026-05-26"]
}
Aufruf mit curl
curl -H "Authorization: Bearer apm_ihr-token" \
"https://example.com/api/days?schedule=1&reason=1"
GET/slots
Liefert die freien Uhrzeiten eines Tages. Die Zeitangaben sind Ortszeiten der Installation, das Format ist JJJJ-MM-TT HH:MM:SS. Ist an dem Tag nichts mehr frei, ist data ein leeres Array.
Query-Parameter
| Name | Typ | Pflicht | Beschreibung | Beispiel |
|---|---|---|---|---|
schedule |
integer ≥ 1 | Pflicht | Nummer des Terminkalenders | 1 |
reason |
integer ≥ 1 | Pflicht | Nummer des Termingrunds | 1 |
day |
string | Pflicht | Tag im Format JJJJ-MM-TT aus GET /days |
2026-05-23 |
Statuscodes
| Status | Bedeutung |
|---|---|
| 200 | Liste der freien Uhrzeiten (kann leer sein) |
| 401 | Token fehlt oder ist ungültig |
| 404 | Terminkalender, Termingrund oder Tag nicht gefunden |
| 429 | Anfragelimit erreicht |
| 503 | Die API ist nicht aktiviert oder die Installation ist noch nicht abgeschlossen |
Antwort 200
{
"data": [
"2026-05-23 09:00:00",
"2026-05-23 09:30:00",
"2026-05-23 10:00:00"
]
}
Aufruf mit curl
curl -H "Authorization: Bearer apm_ihr-token" \
"https://example.com/api/slots?schedule=1&reason=1&day=2026-05-23"
GET/forms
Liefert die Formularfelder, die für die Buchung dieser Uhrzeit ausgefüllt werden müssen. Die Feldnamen verwenden Sie als Schlüssel im Objekt submission von POST /bookings. Fragen Sie die Felder immer ab, statt sie im eigenen Programm fest einzutragen. Das Feld password wird nie ausgegeben.
Query-Parameter
| Name | Typ | Pflicht | Beschreibung | Beispiel |
|---|---|---|---|---|
schedule |
integer ≥ 1 | Pflicht | Nummer des Terminkalenders | 1 |
reason |
integer ≥ 1 | Pflicht | Nummer des Termingrunds | 1 |
slot |
string | Pflicht | Uhrzeit im Format JJJJ-MM-TT HH:MM:SS. Das Leerzeichen muss als %20 kodiert werden. |
2026-05-23%2009:00:00 |
Statuscodes
| Status | Bedeutung |
|---|---|
| 200 | Formularfelder, nach Feldnamen geschlüsselt |
| 401 | Token fehlt oder ist ungültig |
| 404 | Terminkalender, Termingrund oder Uhrzeit nicht gefunden |
| 429 | Anfragelimit erreicht |
| 503 | Die API ist nicht aktiviert oder die Installation ist noch nicht abgeschlossen |
Antwort 200
{
"data": {
"first_name": {
"form_type": "textbox",
"input_type": "text",
"label": "Vorname",
"required": true,
"value": ""
},
"last_name": {
"form_type": "textbox",
"input_type": "text",
"label": "Nachname",
"required": true,
"value": ""
},
"email": {
"form_type": "textbox",
"input_type": "email",
"label": "E-Mail-Adresse",
"required": false,
"value": ""
},
"phone": {
"form_type": "textbox",
"input_type": "tel",
"label": "Telefonnummer",
"required": false,
"value": ""
}
}
}
Aufruf mit curl
curl -H "Authorization: Bearer apm_ihr-token" \
"https://example.com/api/forms?schedule=1&reason=1&slot=2026-05-23%2009:00:00"
POST/bookings
Legt einen Termin an. Fragen Sie zuerst die Formularfelder über GET /forms ab und senden Sie deren Werte im Objekt submission. Der Kopfbereich muss Content-Type: application/json enthalten.
Felder im Request Body
| Name | Typ | Pflicht | Beschreibung | Beispiel |
|---|---|---|---|---|
schedule |
integer ≥ 1 | Pflicht | Nummer des Terminkalenders | 1 |
reason |
integer ≥ 1 | Pflicht | Nummer des Termingrunds | 1 |
slot |
string | Pflicht | Uhrzeit im Format JJJJ-MM-TT HH:MM:SS, genau 19 Zeichen |
2026-05-23 09:00:00 |
submission |
object | Pflicht | Werte zu den Feldnamen aus GET /forms |
Request Body
{
"schedule": 1,
"reason": 1,
"slot": "2026-05-23 09:00:00",
"submission": {
"first_name": "Hans",
"last_name": "Pitt",
"email": "hans.pitt@example.com",
"phone": "+49 30 1234567"
}
}
Statuscodes
| Status | Bedeutung |
|---|---|
| 201 | Der Termin wurde angelegt |
| 400 | Ungültige Anfrage, fehlendes Pflichtfeld oder ungültiges JSON |
| 401 | Token fehlt oder ist ungültig |
| 404 | Terminkalender, Termingrund oder Uhrzeit nicht gefunden |
| 415 | Content-Type: application/json fehlt |
| 429 | Anfragelimit erreicht |
| 500 | Kundendatensatz oder Termin konnte nicht gespeichert werden |
| 503 | Die API ist nicht aktiviert oder die Installation ist noch nicht abgeschlossen |
Antwort 201
{
"booking_id": 142,
"booking_details_id": "a3f8c2d1e5b6",
"user_id": 87,
"slot": "2026-05-23T09:00:00Z"
}
Antwort 400 bei einem fehlenden Pflichtfeld
{
"error": "Field is required",
"field": "email"
}
Aufruf mit curl
curl -X POST https://example.com/api/bookings \
-H "Authorization: Bearer apm_ihr-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"
}
}'
Schemas
Die Datenstrukturen, die in den Antworten vorkommen.
Schedule
{
"id": integer,
"name": string
}
Reason
{
"id": integer,
"name": string,
"description": string,
"duration": integer // Sekunden
}
FormField
{
"form_type": string,
"input_type": string,
"label": string,
"required": boolean,
"value": any
}
BookingRequest
{
"schedule": integer,
"reason": integer,
"slot": "JJJJ-MM-TT HH:MM:SS",
"submission": {
"<feldname>": <wert>
}
}
BookingResponse
{
"booking_id": integer,
"booking_details_id": string,
"user_id": integer,
"slot": "2026-05-23T09:00:00Z" // UTC, ISO 8601
}
Error / BookingError
{
"error": string,
"field": string // optional
}
Gemeinsame Fehlerantworten
Diese Antworten können bei allen Aufrufen auftreten.
| Status | Bedeutung | Erläuterung |
|---|---|---|
| 401 | Unauthorized | Das Token fehlt, ist falsch oder wurde durch ein neues ersetzt. Manche Server entfernen den Authorization-Kopfbereich; fragen Sie im Zweifel Ihren Provider. |
| 404 | Not Found | Der angefragte Terminkalender, Termingrund, Tag oder die Uhrzeit ist nicht (mehr) verfügbar. Auch ein fehlender oder falsch formatierter Parameter erzeugt 404, nicht 400. |
| 429 | Too Many Requests | Das Limit von 300 Anfragen pro Minute und Token ist erreicht. Der Kopfbereich Retry-After nennt die Wartezeit in Sekunden. |
| 503 | Service Unavailable | Die API ist im Administrationsbereich nicht aktiviert (API disabled) oder die Installation ist noch nicht abgeschlossen (Not configured). Beide Fälle betreffen alle Aufrufe. |
Fehler werden immer als JSON ausgegeben und haben stets dieselbe Form:
{ "error": "Beschreibung des Fehlers" }
Bei der Buchung nennt ein Validierungsfehler zusätzlich das betroffene Feld:
{ "error": "Field is required", "field": "email" }
Die vollständige Liste der Fehlertexte je Aufruf finden Sie in der Anleitung.
Maschinenlesbare Beschreibung
Alle Aufrufe sind zusätzlich als OpenAPI-Datei nach Version 3.1 beschrieben. Damit erzeugen Sie Client-Bibliotheken oder laden die Schnittstelle in Werkzeuge wie Postman, Insomnia oder Swagger UI.
In der Datei ist unter servers die Adresse /api eingetragen. Das ist bewusst eine relative Angabe,
damit die Datei auf jeder Installation gültig ist. Tragen Sie in Ihrem Werkzeug daher die Adresse Ihres eigenen Terminplaners ein,
zum Beispiel https://example.com/api. Dieselbe Datei liegt auch in Ihrer Installation unter /api/openapi.json.
Zurück zur Anleitung oder zur Übersicht: Modul "API (Schnittstelle)".