VetTime Public API v1
Die API liefert die aktuell veröffentlichten Schichtzuweisungen eines Mandanten über einen Kalenderzeitraum. Entwürfe, interne Mitarbeiter-IDs, Abwesenheiten, Verträge, Lohn- und Zeiterfassungsdaten werden nicht ausgeliefert.
Protokoll: HTTPS, JSON, UTF-8. Zielgruppe: Backend- und Praxis-Management-System-Entwickler.
Basis-URL und Authentifizierung
https://app.vettime.de/api/public/v1Jeder Request muss den mandantenbezogenen API-Key als HTTP-Bearer-Token übergeben:
Authorization: Bearer vt_live_...GET /shifts
Liefert alle Zuweisungen, die den angefragten inklusiven Zeitraum überschneiden, aus dem jeweils zuletzt veröffentlichten Plan pro Standort und Planungsperiode.
Query-Parameter
| Name | Typ | Pflicht | Regeln |
|---|---|---|---|
| from | date | Ja | Erstes lokales Datum, inklusive; YYYY-MM-DD. |
| to | date | Ja | Letztes lokales Datum, inklusive; YYYY-MM-DD; nicht vor from. |
| location_id | positive integer | Nein | Begrenzt das Ergebnis auf einen Standort des Mandanten. |
| limit | integer | Nein | Seitengröße, 1 bis 250; Standard 100. |
| cursor | string | Nein | Undurchsichtiger meta.next_cursor der vorherigen Seite. |
Der maximale Zeitraum beträgt 366 Kalendertage. Datumsangaben beziehen sich auf Europe/Berlin inklusive Sommerzeitumstellung. Eine Schicht überschneidet den Zeitraum, wenn:
shift.starts_at < Beginn des Tages nach `to`
und
shift.ends_at > Beginn von `from`Beispiel-Request
curl --fail-with-body \
--get 'https://app.vettime.de/api/public/v1/shifts' \
--header "Authorization: Bearer ${VETTIME_API_KEY}" \
--data-urlencode 'from=2026-08-17' \
--data-urlencode 'to=2026-08-31' \
--data-urlencode 'limit=100'Erfolgreiche Antwort
{
"data": [
{
"id": "1f0eb3ea-29cf-4f1e-97b8-0ef39e7a6225",
"local_date": "2026-08-17",
"starts_at": "2026-08-17T06:00:00.000Z",
"ends_at": "2026-08-17T14:00:00.000Z",
"timezone": "Europe/Berlin",
"employee": {
"external_id": "PMS-EMP-148",
"first_name": "Anna",
"last_name": "Beispiel",
"display_name": "Anna Beispiel",
"active": true,
"role": {
"id": "e04bbef6-1cab-4d30-ad1a-b9b3b96ab0ac",
"name": "Tierärztin"
},
"skills": [
{
"id": "77cabf7f-2ba7-49f9-b91e-bb8d7f6aa6b4",
"name": "Ultraschall",
"source": "manual"
}
]
},
"shift_type": {
"id": "33f17d45-16ba-4be1-a116-11d53192dbdb",
"name": "Sprechstunde",
"color": "#3B82F6",
"required_skills": []
},
"location": {
"id": 12,
"name": "Praxis Berlin-Mitte",
"slug": "berlin-mitte"
},
"publication": {
"schedule_id": "cf7bf85c-d676-4101-aafc-897748185894",
"published_at": "2026-08-14T15:42:10.000Z"
},
"updated_at": "2026-08-14T15:41:50.000Z"
}
],
"meta": {
"tenant": { "id": 839204, "name": "Tierarztpraxis Beispiel" },
"from": "2026-08-17",
"to": "2026-08-31",
"timezone": "Europe/Berlin",
"limit": 100,
"has_more": false,
"next_cursor": null,
"generated_at": "2026-08-17T12:05:31.420Z"
}
}Hinweise zu den Feldern
employee.external_id ist eine undurchsichtige, case-sensitive Zeichenkette, die der Mandant passend zu seinem Datensatz im angebundenen System konfiguriert. Ist keine Zuordnung hinterlegt, ist der Wert null. Die interne VetTime-Mitarbeiter- oder Benutzer-ID wird nie ausgeliefert; ein Abgleich über Namen als Fallback ist nicht zulässig.
employee.role kann null sein. location kann bei einem älteren mandantenweiten Plan null sein. publication.published_at und updated_at können bei Altdaten null sein.
Paginierung und Synchronisation
Zeilen sind nach starts_at und anschließend nach Zuweisungs-id sortiert. Solange meta.has_more den Wert true hat, ruft ihr denselben Endpunkt mit meta.next_cursor auf und lasst alle übrigen Parameter unverändert. Cursor sind als undurchsichtig zu behandeln.
Die Antwort ist ein aktueller Snapshot, kein Event-Stream. Holt alle Seiten, stellt den vollständigen Zeitraum bereit, upsertet die gelieferten Zuweisungen, entfernt zuvor importierte Zuweisungen, die im vollständigen Snapshot fehlen, und committet atomar. Zuweisungs-IDs und publication.schedule_id können sich nach erneutem Veröffentlichen ändern, deshalb ist ein regelmäßiger vollständiger Abgleich notwendig.
Fehler
{
"error": {
"code": "invalid_request",
"message": "from must use the YYYY-MM-DD format.",
"details": { "field": "from" }
}
}| HTTP | Code | Bedeutung |
|---|---|---|
| 400 | invalid_request | Ungültiges Datum, ungültiger Zeitraum, Limit, Standort oder Cursor. |
| 401 | invalid_api_key | Fehlender, fehlerhafter, widerrufener Key oder inaktiver Mandant. |
| 429 | rate_limit_exceeded | Anfragelimit überschritten; Retry-After beachten. |
| 500 | internal_error | Vorübergehender Serverfehler; mit Backoff und Jitter erneut versuchen. |
X-Request-Id. Gebt diesen Wert zusammen mit der UTC-Anfragezeit an, wenn ihr den Support kontaktiert. Sendet niemals den API-Key mit.Limits und Kompatibilität
Authentifizierte Keys sind auf 120 Requests pro Minute begrenzt. Fehlgeschlagene Authentifizierungsversuche sind separat auf 30 pro IP pro 15 Minuten begrenzt.
Clients müssen unbekannte JSON-Felder ignorieren. Innerhalb von v1 können additive Felder eingeführt werden; Breaking Changes erhalten einen neuen versionierten Pfad.
OpenAPI 3.1
Der maschinenlesbare Vertrag steht als YAML bereit:
openapi-public-v1.yaml