Eine REST-API mit JSON, persönliche API-Tokens und signierte Webhooks. Die Referenz ist öffentlich; zum Ausprobieren brauchen Sie ein Floowa-Konto.
Ein Administrator legt unter Einstellungen → API-Zugänge ein Token an, wählt die Rechte je Funktion und ein Ablaufdatum (30, 90 oder 365 Tage oder unbegrenzt). Das Token wird nur einmal angezeigt.
Authorization: Bearer <token>
Accept: application/json
Basis-URL: https://www.floowa.de/api/v1
| Rate-Limit | 120 Anfragen pro Minute und Token; darüber antwortet die API mit HTTP 429. |
|---|---|
| Listen | Listen kommen seitenweise; mit per_page holen Sie bis zu 100 Einträge pro Seite. |
| Sicher wiederholen | Mit dem Header Idempotency-Key liefert eine wiederholte Anfrage 24 Stunden lang dieselbe Antwort, statt etwas doppelt anzulegen. |
| API-Stand | Jede Antwort trägt den Header Floowa-Api-Revision mit dem Datum der letzten API-Änderung. |
Jede Zustellung ist ein POST mit JSON an Ihre HTTPS-Adresse, mit den Headern X-Floowa-Event, X-Floowa-Delivery und X-Floowa-Signature.
Die Signatur hat die Form t=<Zeitstempel>,v1=<Signatur>. v1 ist ein HMAC-SHA256 über „<Zeitstempel>.<Rohdaten>“ mit Ihrem Signatur-Schlüssel. Vergleichen Sie zeitkonstant und verwerfen Sie alte Zeitstempel.
Antwortet Ihr Server nicht mit einem 2xx-Status, versucht Floowa es nach 1, 5 und 30 Minuten und nach 2 Stunden erneut. Nach 20 Fehlversuchen in Folge wird der Webhook deaktiviert.
{
"id": "8f2c3a1e-5b7d-4c1a-9e2f-0a1b2c3d4e5f",
"event": "absence.requested",
"created_at": "2026-10-28T09:15:00+01:00",
"data": {
"id": "01a1…",
"employee_id": "01a0…",
"absence_type_id": "01a0…",
"start_date": "2026-11-02",
"end_date": "2026-11-06",
"half_day_start": false,
"half_day_end": false,
"days": 5,
"status": "pending"
}
}
$header = $_SERVER["HTTP_X_FLOOWA_SIGNATURE"] ?? "";
parse_str(str_replace(",", "&", $header), $parts);
$body = file_get_contents("php://input");
$expected = hash_hmac("sha256", $parts["t"] . "." . $body, $secret);
if (! hash_equals($expected, $parts["v1"] ?? "") || abs(time() - (int) $parts["t"]) > 300) {
http_response_code(400);
exit;
}
| Ereignis | Wann | Technischer Name |
|---|---|---|
| Mitarbeiter angelegt | Ein Mitarbeiter wird angelegt – von Hand, per Import oder über die API. | employee.created |
| Mitarbeiter geändert | Die Stammdaten eines Mitarbeiters ändern sich. | employee.updated |
| Mitarbeiter gelöscht | Ein Mitarbeiter wird gelöscht. | employee.deleted |
| Abwesenheit beantragt | Jemand beantragt Urlaub oder eine andere Abwesenheit. | absence.requested |
| Abwesenheit genehmigt | Ein Antrag wird genehmigt oder eine Abwesenheit direkt eingetragen. | absence.approved |
| Abwesenheit abgelehnt | Ein Antrag wird abgelehnt. | absence.rejected |
| Abwesenheit storniert | Ein Antrag oder eine Abwesenheit wird zurückgezogen. | absence.cancelled |
| Zeit erfasst | Ein Zeiteintrag entsteht – beim Einstempeln, beim Nachtragen oder am Terminal. | time_entry.created |
| Zeit geändert | Ein Zeiteintrag ändert sich, zum Beispiel beim Ausstempeln. | time_entry.updated |
| Zeit gelöscht | Ein Zeiteintrag wird gelöscht. | time_entry.deleted |
| Monat abgeschlossen | Ein Monat wird in der Lohnvorbereitung abgeschlossen. | payroll.closed |
| Monat wieder geöffnet | Ein abgeschlossener Monat wird für Korrekturen wieder geöffnet. | payroll.reopened |
| Schicht veröffentlicht | Eine Schicht wird mit dem Schichtplan veröffentlicht. | shift.published |
| Schicht geändert | Eine veröffentlichte Schicht ändert sich. | shift.changed |
| Schicht gestrichen | Eine veröffentlichte Schicht wird gelöscht. | shift.deleted |
Alle Änderungen an der API mit Datum und Hinweis auf nicht abwärtskompatible Änderungen. Maschinenlesbar unter GET /api/v1/changelog.
GET /employeesGET /employees/{id}POST /employeesPUT /employees/{id}
GET /qualificationsGET /employees/{id}/qualificationsGET /inventory-items/{id}
POST /absences/{id}/cancelGET /absences
POST /time-projectsPUT /time-projects/{id}
POST /time-entriesPUT /time-entries/{id}GET /time-allocations
GET /org-unitsPOST /org-unitsPUT /org-units/{id}
PUT /employees/{id}/time-allocations/{date}
GET /time-allocationsPUT /employees/{id}/time-allocations/{date}
GET /payroll/{month}
GET /payroll/{month}
GET /absencesGET /reports/payroll
GET /changelog