Öffentliche API
REST-API (Version v1) für die eigene Website Ihres Betriebs, eine KI-Rezeption, Zapier, Make und andere Anbindungen. Antworten sind JSON mit dem Feld ok; bei Fehlern zusätzlich error. Die vollständige Beschreibung aller Pfade und Felder finden Sie in OpenAPI 3.1.
1. Anmeldung mit Schlüssel
Jede Anfrage muss den Header Authorization: Bearer rk_live_… enthalten. Den Schlüssel erstellen Sie in der Übersicht → API-Schlüssel. Der vollständige Schlüssel wird nur einmal angezeigt — speichern Sie ihn in Umgebungsvariablen oder einem Passwortmanager; bei uns wird nur sein Fingerabdruck gespeichert. Ein Schlüssel gehört zu einem Betrieb, daher wird der Betrieb in den Anfragen nicht angegeben.
curl "https://app.terminuj.com/api/v1/services" \
-H "Authorization: Bearer rk_live_XXXXXXXXXXXXXXXXXXXXXXXX"2. Berechtigungen des Schlüssels
Beim Erstellen des Schlüssels wählen Sie die Berechtigungen — geben Sie ihm nur die, die die Anbindung wirklich braucht.
| Berechtigung | Pfade (/api/v1/…) |
|---|---|
booking:read | GET /bookings, GET /bookings/{id}, GET /time-off |
booking:write | POST /bookings, PATCH /bookings/{id} (stornieren, verschieben, bestätigen), POST /time-off, DELETE /time-off/{id} |
customer:read | GET /customers |
service:read | GET /services, GET /availability |
webhook:manage | GET/POST /webhooks, GET/DELETE /webhooks/{id}, GET /webhooks/{id}/deliveries |
3. Häufigste Anwendungen
Freie Termine
Liefert für jeden Tag, ob geöffnet ist, und die freien Zeiten nach Abzug von Buchungen, freien Tagen und Pausen der Leistung; frühestens 2 Std. ab jetzt. from = Tag im Format JJJJ-MM-TT (Standard: heute), days 1–62 (Standard: 28), optional staff = ein bestimmter Mitarbeiter. Die Zeitzone ist Europe/Bratislava.
curl "https://app.terminuj.com/api/v1/availability?service=<id-sluzby>&from=2026-06-15&days=7" \
-H "Authorization: Bearer rk_live_XXXXXXXXXXXXXXXXXXXXXXXX"Buchung erstellen
startAt in UTC mit Z am Ende (12:00Z = 14:00 im Sommer in Bratislava). Die E-Mail des Kunden ist Pflicht; ohne sie nur mit "channel": "telefon" (telefonisch angenommener Termin — Name und Telefon genügen). Termine aus dem öffentlichen Formular Ihrer Website senden Sie mit "channel": "web"; wenn der Betrieb die Zustimmung zum Beginn der Leistung vor Ablauf der Widerrufsfrist verlangt, fügen Sie "serviceStartConsent": true entsprechend dem Kästchen hinzu, das der Kunde angekreuzt hat (sonst 422 consent_required). Optional preferredStaffId, customer.notes und locale (sk | en | cs | hu | de | es — Sprache der API-Meldungen und weiterer Nachrichten an den Kunden zu dieser Buchung; Standard ist die Sprache des Betriebs). Wird dieselbe Leistung und Zeit mit derselben E-Mail innerhalb von 10 Minuten erneut gesendet, kommt dieselbe Buchung zurück (Doppelklick, Netzwerkausfall).
Bei Buchungen über die API sendet Terminuj dem Kunden keine Bestätigungs-E-Mail — die Bestätigung sendet Ihre Anbindung. Der Inhaber wird gemäß den Einstellungen des Betriebs benachrichtigt. Die Buchung zählt zum monatlichen Kontingent des Tarifs.
curl -X POST "https://app.terminuj.com/api/v1/bookings" \
-H "Authorization: Bearer rk_live_XXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"serviceId": "<id-sluzby>",
"startAt": "2026-06-15T12:00:00Z",
"customer": {
"fullName": "Jana Nováková",
"email": "jana@example.com",
"phone": "+421900123456"
}
}'Buchung stornieren, verschieben oder bestätigen
Ein Pfad, abhängig vom Feld action: {"action": "cancel", "reason": "…"}, {"action": "reschedule", "startAt": "…Z"} oder {"action": "confirm"} (nur ein Termin, der auf eine Anzahlung wartet). Bei einer Stornierung erhält der Kunde eine E-Mail; bei Verschiebung und Bestätigung, wenn der Betrieb Bestätigungs-E-Mails aktiviert hat.
curl -X PATCH "https://app.terminuj.com/api/v1/bookings/<id-rezervacie>" \
-H "Authorization: Bearer rk_live_XXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ "action": "cancel", "reason": "Zákazník neprišiel" }'Kunden suchen
search sucht in Name, E-Mail und Telefonnummer.
curl "https://app.terminuj.com/api/v1/customers?search=jana&limit=10" \
-H "Authorization: Bearer rk_live_XXXXXXXXXXXXXXXXXXXXXXXX"Weitere Pfade (Buchungsliste mit dem Filter from/to/status/createdFrom, Leistungen, Zeit blockieren mit /time-off, Webhooks) sind in OpenAPI beschrieben.
4. Seitenweise Abfrage
Listen haben die Parameter ?limit=25&cursor=<id>. Standard 25, höchstens 100 pro Seite (Buchungen, Kunden, Webhook-Zustellungen); Leistungen Standard 50, höchstens 200. Die Antwort enthält { pagination: { nextCursor, hasMore, limit } }.
# Erste Seite
curl "https://app.terminuj.com/api/v1/bookings?limit=25" -H "Authorization: Bearer rk_live_…"
# Nächste Seite (nextCursor aus der vorherigen Antwort)
curl "https://app.terminuj.com/api/v1/bookings?limit=25&cursor=<nextCursor>" -H "Authorization: Bearer rk_live_…"5. Anfragelimit
Das Limit wird pro Schlüssel in einem gleitenden Fenster von 1 Minute gezählt:
- Lesen (booking:read, customer:read, service:read): 600 Anfragen pro Minute
- Schreiben (booking:write, webhook:manage): 60 Anfragen pro Minute
Bei Überschreitung kommt 429 rate_limit_exceeded mit dem Header Retry-After (nach wie vielen Sekunden Sie es erneut versuchen sollen) und dem Feld retryAfterSeconds. Die Header X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset werden bei der Ablehnung mitgesendet.
6. Fehlercodes
| HTTP | error | Bedeutung |
|---|---|---|
| 401 | missing_or_invalid_authorization | Der Header Authorization fehlt oder der Schlüssel hat nicht die Form rk_live_ + 24 Zeichen |
| 401 | invalid_api_key | Ein solcher Schlüssel existiert nicht |
| 401 | api_key_revoked | Der Schlüssel wurde in der Übersicht widerrufen |
| 401 | api_key_expired | Der Schlüssel ist abgelaufen (expiresAt) |
| 402 | trial_ended | Die Testphase des Betriebs ist beendet — 14 Tage ab Registrierung (resetAt = Ende der Testphase); neue Buchungen erst nach Wahl eines Tarifs |
| 402 | monthly_limit_exceeded | Der Betrieb hat das monatliche Buchungskontingent seines Partnertarifs ausgeschöpft (used, limit, resetAt) |
| 403 | insufficient_scope | Dem Schlüssel fehlt die nötige Berechtigung (required, have) |
| 403 | manual_requires_app | „manual: true“ darf nur eine in der Terminuj-App angemeldete Person senden, kein API-Schlüssel |
| 404 | not_found | Buchung, freier Tag oder Webhook existiert in diesem Betrieb nicht (auch service_not_found) |
| 409 | slot_conflict | Der Termin ist inzwischen belegt; beim Erstellen werden auch suggestedAlternatives mitgeliefert |
| 409 | already_cancelled | Der Status der Buchung lässt die Änderung nicht zu (auch already_completed, cannot_cancel, not_reschedulable, already_confirmed, cannot_confirm) |
| 422 | invalid_body | Der Anfragetext entspricht nicht dem Schema — Einzelheiten in detail |
| 422 | consent_required | Der Betrieb verlangt die Zustimmung zum Beginn der Leistung vor Ablauf der Widerrufsfrist, und serviceStartConsent: true fehlt |
| 422 | start_in_past | Der Beginn liegt in der Vergangenheit (auch outside_working_hours = außerhalb der Öffnungszeiten) |
| 429 | rate_limit_exceeded | Anfragelimit des Schlüssels überschritten — siehe Abschnitt 5 |
| 429 | daily_cap_reached | Der Betrieb hat die tägliche Obergrenze öffentlicher Buchungen erreicht (letzte 24 Std.) — Schreiben per Schlüssel zählt genauso wie das Formular |
7. Webhooks
Wenn Terminuj Sie selbst über eine neue, stornierte oder verschobene Buchung informieren soll, siehe /docs/webhooks — HMAC-SHA-256-Signatur, Wiederholungen nach 1 Min., 5 Min., 30 Min. und 2 Std., Codebeispiele.
Webhooks lassen sich auch über die API verwalten: GET/POST /api/v1/webhooks, GET/DELETE /api/v1/webhooks/{id} und GET /api/v1/webhooks/{id}/deliveries (Zustellprotokoll).
8. Support
Fehler oder Wunsch nach einer neuen Funktion: podpora@terminuj.com.