API - Zeiterfassung & Urlaub Admin

📕 Für Administratoren und Entwickler.

Die Zeiterfassungs-API erlaubt den vollständigen Zugriff auf Zeiteinträge sowie das Verwalten von Urlaubsantraegen und Krankmeldungen. Zeiteinträge können gelesen, erstellt, aktualisiert und gelöscht werden. Für Urlaubsantraege und Krankmeldungen stehen Lese- und Erstellendpunkte bereit.


Zeiteinträge (Time Entries)

Basis-Pfad: /api/v1/time-entries

Zeiteinträge auflisten

GET /api/v1/time-entries

Scope: time_entries:read

Query-Parameter

ParameterTypPflichtStandardBeschreibung
userIdLongNeinNach Benutzer filtern
projectIdLongNeinNach Projekt filtern
startDateStringNeinStartdatum (YYYY-MM-DD)
endDateStringNeinEnddatum (YYYY-MM-DD)
pageIntegerNein0Seitennummer (0-basiert)
sizeIntegerNein50Einträge pro Seite (max. 100)

Antwort-Felder

FeldTypBeschreibung
idnumberEindeutige ID
userIdnumberID des Benutzers
userDisplayNamestringAnzeigename des Benutzers
projectIdnumber oder nullID des Projekts (null bei allgemeinen Aufgaben)
projectNamestring oder nullName des Projekts
taskIdnumber oder nullID der verknuepften Aufgabe
taskTitlestring oder nullTitel der verknuepften Aufgabe
datestringDatum des Eintrags (YYYY-MM-DD)
startTimestring oder nullStartzeit (HH:mm)
endTimestring oder nullEndzeit (HH:mm)
durationMinutesnumberDauer in Minuten
durationHoursnumberDauer in Dezimalstunden
descriptionstring oder nullBeschreibung
billablebooleanAbrechenbar
billedbooleanBereits abgerechnet
hourlyRatenumber oder nullStundensatz zum Zeitpunkt des Eintrags
revenuenumber oder nullBerechneter Umsatz
approvalStatusstringPENDING, APPROVED oder REJECTED
entryTypestringWORK, TRAVEL, BREAK oder FLAT_FEE
externalReferencestring oder nullExterne Referenz (z.B. ERP-Nummer)
archivedbooleanArchiviert (gelöscht)
createdAtstringErstellungszeitpunkt (ISO 8601, UTC)
updatedAtstringLetzter Aenderungszeitpunkt (ISO 8601, UTC)

cURL-Beispiel

curl "https://app.spiritflow.team/api/v1/time-entries?startDate=2025-03-01&endDate=2025-03-31&projectId=5" \
  -H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Einzelnen Zeiteintrag abrufen

GET /api/v1/time-entries/{id}

Scope: time_entries:read

Pfad-Parameter

ParameterTypBeschreibung
idLongID des Zeiteintrags

Antwort (200 OK)

Einzelnes Zeiteintrag-Objekt mit gleicher Struktur wie in der Liste.

cURL-Beispiel

curl "https://app.spiritflow.team/api/v1/time-entries/1042" \
  -H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Zeiteintrag erstellen

POST /api/v1/time-entries

Scope: time_entries:write

Request-Body

FeldTypPflichtBeschreibung
userIdnumberJaID des Benutzers
projectIdnumberNeinID des Projekts
taskIdnumberNeinID der Aufgabe
datestringJaDatum (YYYY-MM-DD)
startTimestringNeinStartzeit (HH:mm)
endTimestringNeinEndzeit (HH:mm)
durationMinutesnumberNeinDauer in Minuten (min. 1)
descriptionstringNeinBeschreibung (max. 2000 Zeichen)
billablebooleanNeinAbrechenbar (Standard: true)
entryTypestringNeinWORK (Standard), TRAVEL, BREAK oder FLAT_FEE
externalReferencestringNeinExterne Referenz (max. 255 Zeichen)

Hinweis: Entweder durationMinutes oder startTime + endTime müssen angegeben werden. Bei Angabe von Start- und Endzeit wird die Dauer automatisch berechnet.

Antwort (201 Created)

Gleiche Felder wie bei der Zeiteintragsliste.

cURL-Beispiel

curl -X POST "https://app.spiritflow.team/api/v1/time-entries" \
  -H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": 2,
    "projectId": 5,
    "taskId": 42,
    "date": "2025-03-15",
    "durationMinutes": 120,
    "description": "Frontend-Entwicklung: Kontaktformular",
    "billable": true
  }'

Zeiteintrag aktualisieren

PUT /api/v1/time-entries/{id}

Scope: time_entries:write

Alle Felder sind optional — nur die angegebenen Felder werden geändert. Die Struktur des Request-Bodys entspricht dem Erstell-Endpunkt.

Hinweis: Bereits abgerechnete Zeiteinträge (billed: true) können nicht mehr geändert werden.

Pfad-Parameter

ParameterTypBeschreibung
idLongID des Zeiteintrags

Antwort (200 OK)

Aktualisiertes Zeiteintrag-Objekt.


Zeiteintrag löschen (archivieren)

DELETE /api/v1/time-entries/{id}

Scope: time_entries:write

Pfad-Parameter

ParameterTypBeschreibung
idLongID des Zeiteintrags

Antwort

204 No Content

Hinweis: Bereits abgerechnete Zeiteinträge können nicht gelöscht werden.


Urlaub (Vacation Requests)

Basis-Pfad: /api/v1/vacation-requests

Urlaubsantraege umfassen regulaeren Urlaub, Sonderurlaub und unbezahlten Urlaub. Krankmeldungen werden über einen separaten Endpunkt verwaltet und erscheinen nicht in dieser Liste.

Status-Werte für Urlaubsantraege

StatusBedeutung
PENDINGAusstehend, noch nicht entschieden
APPROVEDGenehmigt
REJECTEDAbgelehnt
CANCELLEDStorniert

Urlaubsantraege auflisten

GET /api/v1/vacation-requests

Scope: vacation:read

Query-Parameter

ParameterTypPflichtBeschreibung
statusstringNeinFilter: PENDING, APPROVED, REJECTED oder CANCELLED
ownerIdLongNeinNach Benutzer filtern

Antwort-Felder

FeldTypBeschreibung
idnumberEindeutige ID
titlestringTitel des Antrags
typestringVACATION, SPECIAL_LEAVE oder UNPAID_LEAVE
statusstringAktueller Status
ownerIdnumberID des Antragstellers
ownerNamestringName des Antragstellers
startDatestringStartdatum (YYYY-MM-DD)
endDatestringEnddatum (YYYY-MM-DD)
daysCountnumberAnzahl der Urlaubstage
reasonstring oder nullBegruendung
createdAtstringErstellungszeitpunkt (ISO 8601, UTC)
updatedAtstringLetzter Aenderungszeitpunkt (ISO 8601, UTC)

Hinweis: Krankmeldungen (SICK) werden nicht über diesen Endpunkt zurückgegeben — dafür den separaten Endpunkt /api/v1/sick-leaves verwenden.


Urlaubsantrag erstellen

POST /api/v1/vacation-requests

Scope: vacation:write

Request-Body

FeldTypPflichtBeschreibung
ownerIdnumberJaID des Benutzers
typestringNeinVACATION (Standard), SPECIAL_LEAVE oder UNPAID_LEAVE
startDatestringJaStartdatum (YYYY-MM-DD)
endDatestringJaEnddatum (YYYY-MM-DD)
reasonstringNeinBegruendung
titlestringNeinTitel (wird automatisch generiert, falls leer)
autoApprovebooleanNeinAutomatisch genehmigen (Standard: false)

Fehler-Codes

HTTP-StatusCodeBeschreibung
409CONFLICTÜberlappung mit bereits genehmigtem Urlaub

cURL-Beispiel

curl -X POST "https://app.spiritflow.team/api/v1/vacation-requests" \
  -H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "ownerId": 5,
    "startDate": "2025-07-14",
    "endDate": "2025-07-25",
    "reason": "Sommerurlaub"
  }'

Krankmeldungen (Sick Leaves)

Basis-Pfad: /api/v1/sick-leaves

DSGVO-Hinweis: Krankmeldungen sind Gesundheitsdaten und unterliegen besonderem Datenschutz gemäß Art. 9 DSGVO. Der Zugriff erfordert separate Scopes (sick_leave:read / sick_leave:write), die unabhängig vom Urlaubs-Scope vergeben werden. Vergeben Sie diese Scopes nur an API-Keys, die sie wirklich benötigen.

Krankmeldungen auflisten

GET /api/v1/sick-leaves

Scope: sick_leave:read

Query-Parameter

ParameterTypPflichtBeschreibung
ownerIdLongNeinNach Benutzer filtern

Antwort

Gleiche Felder wie bei Urlaubsantraegen, jedoch mit type: "SICK".

cURL-Beispiel

curl "https://app.spiritflow.team/api/v1/sick-leaves?ownerId=5" \
  -H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Krankmeldung erstellen

POST /api/v1/sick-leaves

Scope: sick_leave:write

Request-Body

FeldTypPflichtBeschreibung
ownerIdnumberJaID des Benutzers
startDatestringJaErster Krankheitstag (YYYY-MM-DD)
endDatestringJaLetzter Krankheitstag (YYYY-MM-DD)
reasonstringNeinOptionaler Hinweis

Besonderes Verhalten

  • Krankmeldungen werden automatisch genehmigt (Status direkt APPROVED)
  • Bereits genehmigte Urlaubsantraege, die sich mit dem Krankmeldungszeitraum überschneiden, werden automatisch storniert

Antwort (201 Created)

Krankmeldungs-Objekt mit gleicher Struktur wie bei Urlaubsantraegen (mit type: "SICK").

cURL-Beispiel

curl -X POST "https://app.spiritflow.team/api/v1/sick-leaves" \
  -H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "ownerId": 5,
    "startDate": "2025-03-10",
    "endDate": "2025-03-12"
  }'