> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stampfactory.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# API-Referenz

> REST API für die Stampfactory Zeiterfassungs- und Personalverwaltungsplattform

## Überblick

Die Stampfactory API ist eine REST API und stellt alle Funktionen der Zeiterfassungs- und
Personalverwaltungsplattform bereit. Sie ist mandantenfähig: jeder Mandant hat eine eigene
Datenbank, und jede Anfrage wird über die Subdomain dem richtigen Mandanten zugeordnet.

## Basis-URL

Jeder Mandant erreicht die API über seine eigene Subdomain. Der Pfad-Präfix ist immer
`/rest`.

```
https://{tenant}.stamp.eu/rest
```

Für den Beispielmandanten `demo` lautet die Basis-URL also `https://demo.stamp.eu/rest`.
Eigene Domains werden unterstützt; auch dort bleibt der Präfix `/rest` unverändert.

## Authentifizierung

Die API nutzt Bearer-Token (Laravel Sanctum). Den Token liefert der Login-Endpunkt. Er
muss bei allen weiteren Anfragen im Header `Authorization` mitgeschickt werden.

### Token beziehen

```bash theme={null}
curl -X POST https://demo.stamp.eu/rest/login \
  -H "Content-Type: application/json" \
  -d '{"code": "admin", "password": "geheim1234"}'
```

### Token verwenden

```bash theme={null}
curl -H "Authorization: Bearer {token}" \
  https://demo.stamp.eu/rest/employees
```

Mit `DELETE /rest/login` wird der Token wieder ungültig, `GET /rest/login` liefert die
angemeldete Person, und `PUT /rest/login` ändert das eigene Passwort.

<Note>
  Der Terminal-Endpunkt `POST /rest/terminal/{code}` ist bewusst ohne Token erreichbar,
  damit Hardware-Terminals ohne Anmeldung stempeln können.
</Note>

## Datenformate

Die folgenden Formate gelten verbindlich für die gesamte API.

| Typ                                               | Format                                               | Beispiel                                 |
| ------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------- |
| Dauer (Anzeige)                                   | String `HH:MM:SS.mmm`, Feldname ohne Suffix          | `"08:00:00.000"`                         |
| Dauer (Rohwert)                                   | Ganzzahl in Millisekunden, Feldname mit Suffix `_ms` | `28800000`                               |
| Datum                                             | ISO 8601 (`YYYY-MM-DD`)                              | `"2026-07-25"`                           |
| Fachliche Zeitstempel (Stempelungen, Korrekturen) | ISO 8601 in der Zeitzone des Mandanten               | `"2026-07-25T08:00:00+02:00"`            |
| Technische Metadaten (`created_at`, `updated_at`) | ISO 8601 in UTC                                      | `"2026-07-25T06:00:00+00:00"`            |
| IDs                                               | UUID beziehungsweise TypeID als String               | `"9d3f8c1a-4b2e-4f7d-9a11-2c5e8b0d1f34"` |
| Arbeitszeit-Flags                                 | Ganzzahlige Bitmaske im Feld `flags`                 | `512` steht für Feiertag                 |
| Monats-Perioden                                   | `YYYY-MM`                                            | `"2026-07"`                              |

<Note>
  Dauerwerte gibt es je nach Feld in zwei Varianten. Für Anzeigen eignet sich der
  formatierte String, für Berechnungen der Millisekundenwert mit dem Suffix `_ms`. Beide
  beschreiben denselben Wert.
</Note>

### Arbeitszeit-Flags

Das Feld `flags` fasst die Eigenschaften eines Arbeitstags als Bitmaske zusammen. Ein Tag
kann mehrere Eigenschaften gleichzeitig tragen, etwa halber Urlaubstag und Feiertag. Die
Prüfung erfolgt per bitweisem UND:

```js theme={null}
const VACATION = 1 << 2; // 4
const isVacation = (day.flags & VACATION) !== 0;
```

## Antwortformat

Erfolgreiche Antworten liefern die fachliche Nutzlast unter `data`. Ausgenommen sind die
Stempel-Endpunkte `POST /rest/terminal/{code}` und `/rest/mobile`, die aus
Kompatibilitätsgründen ein flaches Objekt zurückgeben.

Listen sind, sofern sie paginiert werden, im Laravel-Paginator-Format aufgebaut und
enthalten neben `data` zusätzlich `links` und `meta`.

```json theme={null}
{
  "data": [ ],
  "links": { "first": "…", "last": "…", "prev": null, "next": "…" },
  "meta": { "current_page": 1, "per_page": 25, "total": 137 }
}
```

## Fehlerformat

Alle Fehler mit Status 4xx und 5xx nutzen denselben Envelope. Das Feld `type` verweist auf
die passende Stelle in der Fehlerreferenz.

```json theme={null}
{
  "request_id": "9f1c2f7e-5b3c-4a11-9a1d-2f0a5c7d3e88",
  "timestamp": "2026-07-25T06:00:00Z",
  "message": "Das Feld Code ist erforderlich.",
  "field_errors": {
    "code": ["Das Feld Code ist erforderlich."]
  },
  "errors": [
    {
      "title": "Validation Error",
      "detail": "The given data was invalid.",
      "type": "https://docs.stampfactory.eu/errors#validation_error",
      "_meta": {
        "path": "/rest/employees",
        "fields": { "code": ["Das Feld Code ist erforderlich."] }
      }
    }
  ]
}
```

`field_errors` erscheint nur bei Validierungsfehlern (Status 422). Endpunktspezifische
Zusatzdaten wie `warnings`, `earliest` oder `code` stehen kanonisch in `errors[0]._meta`;
gleichlautende Felder auf oberster Ebene sind eine Übergangslösung für ältere Clients.

Die `request_id` entspricht dem Response-Header `X-Request-Id` und hilft dem Support
dabei, eine konkrete Anfrage wiederzufinden.

<Card title="Fehlerreferenz" icon="triangle-exclamation" href="/errors">
  Alle Fehlercodes mit Bedeutung, typischen Auslösern und Beispielantworten.
</Card>

## Berechtigungsmodell

Die API verwendet rollenbasierte Zugriffskontrolle. Jede Benutzerin und jeder Benutzer
erhält genau eine Rolle, die bestimmt, auf welche Funktionen Zugriff besteht.

### Systemrollen

| Rolle                   | Beschreibung                                                                    |
| ----------------------- | ------------------------------------------------------------------------------- |
| **Workspace Admin**     | Vollzugriff auf alle Ressourcen. Kann nicht gelöscht oder eingeschränkt werden. |
| **HR Admin**            | Verwaltung von Mitarbeitenden, Abwesenheiten und Berichten.                     |
| **Lohnbuchhaltung**     | Zugriff auf Lohndaten, Zeiterfassungs-Export und Berichte.                      |
| **Zeiterfassung Admin** | Verwaltung von Arbeitszeiten, Arbeitszeitmodellen und Feiertagskalendern.       |
| **Mitarbeitende**       | Eigene Stempelungen (Web, Mobil, Terminal) und eigene Benachrichtigungen.       |

Zusätzlich lassen sich über `POST /rest/roles` eigene Rollen mit individuellen
Berechtigungen anlegen.

### Berechtigungen

Berechtigungen sind in Funktionsbereiche gegliedert:

| Bereich                | Berechtigungen                                                                                                                                                 |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Mitarbeitende**      | `employees:view`, `employees:manage`, `employees:assign_roles`                                                                                                 |
| **Zeiterfassung**      | `time-tracking:view`, `time-tracking:correct`, `time-tracking:export`, `time-tracking:clock-web`, `time-tracking:clock-mobile`, `time-tracking:clock-terminal` |
| **Abwesenheiten**      | `absences:view`, `absences:manage`, `absences:approve`                                                                                                         |
| **Arbeitszeitmodelle** | `schedule-models:view`, `schedule-models:manage`                                                                                                               |
| **Feiertagskalender**  | `holidays:view`, `holidays:manage`                                                                                                                             |
| **Organisation**       | `org:manage`                                                                                                                                                   |
| **Projekte**           | `projects:view`, `projects:manage`                                                                                                                             |
| **Lohnabrechnung**     | `payroll:view`, `payroll:manage`                                                                                                                               |
| **Berichte**           | `reports:view`                                                                                                                                                 |
| **Einstellungen**      | `settings:manage`                                                                                                                                              |
| **Benachrichtigungen** | `notifications:own`, `notifications:department`                                                                                                                |

### Sichtbarkeit

Die Sichtbarkeit von Mitarbeitenden richtet sich nach der zugewiesenen Rolle:

* **Workspace Admin**: sieht alle Mitarbeitenden.
* **Rollen mit `employees:view` oder `employees:manage`**: sehen Mitarbeitende der eigenen
  Organisationseinheit und aller untergeordneten Einheiten.
* **Rollen ohne diese Berechtigungen**: sehen nur die eigenen Daten.

## Module

Funktionen lassen sich pro Mandant als Modul aktivieren. Ist ein Modul deaktiviert,
antworten die zugehörigen Endpunkte mit Status 403 und dem Code `forbidden`. Welche Module
ein Mandant nutzt, liefert `GET /rest/` in den Feldern `modules` und `available_modules`.

| Modul                | Beschreibung                                   |
| -------------------- | ---------------------------------------------- |
| `leave_requests`     | Abwesenheitsverwaltung                         |
| `overtime_accounts`  | Überstundenkonten                              |
| `projects`           | Projektzeiterfassung                           |
| `locations`          | Standortverwaltung                             |
| `departments`        | Abteilungsstruktur                             |
| `cost_centers`       | Kostenstellenverwaltung                        |
| `short_work`         | Kurzarbeit                                     |
| `shift_roster`       | Dienstplan                                     |
| `payroll`            | Lohnabrechnung und Monatsabschluss             |
| `datev_payroll`      | DATEV Lohn und Gehalt                          |
| `export`             | Zeitwirtschafts-Export                         |
| `nfc_clock`          | Stempeln per NFC-Tag                           |
| `geo_clock`          | Standortprüfung beim Stempeln                  |
| `mobile_app`         | Mobile App                                     |
| `terminals`          | Hardware-Terminals                             |
| `employee_documents` | Digitale Personalakte                          |
| `eau`                | Elektronische Arbeitsunfähigkeitsbescheinigung |
| `dls_import`         | Import aus Lohnprogrammen                      |
| `webhooks`           | Webhooks                                       |
| `mood`               | Stimmungsbarometer                             |
| `custom_domain`      | Eigene Domain                                  |

<Note>
  Die Prüfungen nach Arbeitszeitgesetz sind kein Modul. Sie laufen für jeden Mandanten
  automatisch mit und lassen sich nicht abschalten.
</Note>
