Reviews

Reviews run a set of automated compliance and plausibility checks over the workmonths of your employees — for example missing checkouts, undocumented absences, overlapping workdays, or violations of German working-time law (ArbZG). Each problem the checks detect is reported as a finding, so you can resolve suspicious data before payroll. Findings are computed on the fly from the current data and are never stored: re-running a review after a correction immediately reflects the fix.

The Finding Object

A finding is one concrete problem detected by one check on one employee's workmonth. Findings are read-only computation results — they have no ID and cannot be modified through the API.

  • Name
    code
    Type
    string
    Description

    Identifier of the check that produced the finding, e.g. insufficient-break. The authoritative list of codes active for your organization is returned by the checks endpoint.

  • Name
    group
    Type
    string
    Description

    The finding group the check belongs to: missing-data, conflicts, legal-violations, or anomalies. See the groups endpoint for display labels.

  • Name
    severity
    Type
    string
    Description

    Either error or warning. All built-in checks currently report error.

  • Name
    date
    Type
    string (YYYY-MM-DD) or null
    Description

    The day within the workmonth the finding refers to. null is possible in the schema for month-level findings, but every built-in check sets a date.

  • Name
    references
    Type
    array of [type, id] pairs
    Description

    The records the finding is based on, each as a two-element array of an object type and its UUID. The first entry always references the employee, the second the workmonth, followed by the specific records that triggered the finding (e.g. workday or timespan entries).

  • Name
    context
    Type
    object
    Description

    Check-specific machine-readable values behind the finding, e.g. required_break_seconds for insufficient-break. Empty object for checks without additional data.

  • Name
    details
    Type
    string
    Description

    Human-readable German summary with the concrete values interpolated, e.g. Arbeitszeit: 9h 15min · Pause: 15min (gefordert: 45min). Empty string for checks whose title already says everything.


GET/api/v2/reviews/reviews/

Run a Review

Run all configured checks over the workmonths of a given calendar month and return the resulting findings. The review covers every employee of your organization that has a workmonth for the requested month; employees without tracked data in that month produce no findings. Findings are sorted by date, severity, and code.

The response is not paginated — findings always contains the complete result. Both query parameters are required; omitting either returns 400 Bad Request.

Query Parameters

  • Name
    year
    Type
    integer
    Description

    Calendar year of the workmonths to review, e.g. 2026. Required.

  • Name
    month
    Type
    integer
    Description

    Calendar month of the workmonths to review, 112. Required.

Request

curl -X GET "https://api.zeitstrom.com/api/v2/reviews/reviews/?year=2026&month=5" \
  -H "Authorization: Token <YOUR_API_TOKEN>"

Response

{
  "year": 2026,
  "month": 5,
  "findings": [
    {
      "code": "incomplete-workday",
      "group": "missing-data",
      "severity": "error",
      "date": "2026-05-12",
      "references": [
        ["employee", "508d5250-7399-4b65-a574-3da53d9ddc25"],
        ["workmonth", "1d5be0ea-9f0c-4b0e-8a2f-64c7013274e8"],
        ["workday", "c9a3f1de-20b6-4a8e-b1d4-7e2f90a6c315"]
      ],
      "context": {},
      "details": ""
    },
    {
      "code": "insufficient-break",
      "group": "legal-violations",
      "severity": "error",
      "date": "2026-05-15",
      "references": [
        ["employee", "508d5250-7399-4b65-a574-3da53d9ddc25"],
        ["workmonth", "1d5be0ea-9f0c-4b0e-8a2f-64c7013274e8"],
        ["workday", "f4b8c2a1-6d3e-49f7-8c05-1a9e6b2d4c73"]
      ],
      "context": {
        "net_working_seconds": 33300,
        "actual_break_seconds": 900,
        "required_break_seconds": 2700
      },
      "details": "Arbeitszeit: 9h 15min · Pause: 15min (gefordert: 45min)"
    }
  ]
}

GET/api/v2/reviews/reviews/checks/

List Checks

List the check definitions active for your organization. This is the authoritative source for valid finding codes: by default all built-in checks run, but organizations can configure a subset (and per-check options), in which case this endpoint reflects exactly the checks a review executes.

The built-in checks are incomplete-workday, unfiled-absence, pending-absence-application, overlapping-workdays, unbalanced-worktime, future-workday, insufficient-break, excessive-daily-hours, insufficient-rest-period, excessive-weekly-hours, zero-duration-timespan, and excessive-session-fragmentation.

Each entry contains:

  • Name
    value
    Type
    string
    Description

    The check identifier — the same value findings carry in their code field.

  • Name
    group
    Type
    string
    Description

    The finding group the check belongs to.

  • Name
    title
    Type
    string
    Description

    Short German display label of the check.

  • Name
    description
    Type
    string
    Description

    Long-form German explanation of what the check detects.

  • Name
    config
    Type
    object
    Description

    Organization-specific configuration options for the check. Empty object unless your organization has customized the check.

Request

curl -X GET "https://api.zeitstrom.com/api/v2/reviews/reviews/checks/" \
  -H "Authorization: Token <YOUR_API_TOKEN>"

Response

{
  "checks": [
    {
      "value": "incomplete-workday",
      "group": "missing-data",
      "title": "Unvollständiger Arbeitstag",
      "description": "An einem vergangenen Arbeitstag fehlt die Abmeldung. Der Mitarbeiter hat sich nicht ausgestempelt, sodass die Arbeitszeit für diesen Tag nicht abgeschlossen werden kann.",
      "config": {}
    },
    {
      "value": "insufficient-break",
      "group": "legal-violations",
      "title": "Unzureichende Pausenzeit",
      "description": "An einem Arbeitstag wurde die gesetzlich vorgeschriebene Mindestpause gemäß §4 Arbeitszeitgesetz nicht eingehalten (30 Minuten ab 6 Stunden Arbeit, 45 Minuten ab 9 Stunden).",
      "config": {}
    }
  ]
}

GET/api/v2/reviews/reviews/groups/

List Finding Groups

List the four finding groups with their German display labels. Groups categorize findings by the kind of problem: missing data, conflicting records, suspected legal violations, and statistical anomalies.

Request

curl -X GET "https://api.zeitstrom.com/api/v2/reviews/reviews/groups/" \
  -H "Authorization: Token <YOUR_API_TOKEN>"

Response

{
  "groups": [
    {
      "value": "missing-data",
      "title": "Fehlende Daten",
      "description": "Fehlende oder unvollständige Erfassungen, die nicht ohne manuelle Nacharbeit ausgewertet werden können."
    },
    {
      "value": "conflicts",
      "title": "Konflikte",
      "description": "Erfassungen, die sich gegenseitig widersprechen oder zeitlich überlappen und vor der Lohnabrechnung aufgelöst werden müssen."
    },
    {
      "value": "legal-violations",
      "title": "Gesetze",
      "description": "Erfassungen, die mutmaßlich gegen gesetzliche Vorgaben verstoßen (z. B. Arbeitszeitgesetz) und arbeitsrechtlich geprüft werden sollten."
    },
    {
      "value": "anomalies",
      "title": "Auffälligkeiten",
      "description": "Statistisch ungewöhnliche Erfassungsmuster, die auf Tipp- oder Gerätefehler hindeuten und manuell überprüft werden sollten."
    }
  ]
}

The Suppression Object

A suppression is a stored rule saying "hide findings of this check code, for this employee (or all employees), in this date range". The Zeitstrom app creates one when an administrator dismisses a finding.

  • Name
    id
    Type
    string (UUID)
    Description

    Unique identifier for the suppression rule. Read-only.

  • Name
    code
    Type
    string
    Description

    The check code the rule suppresses, e.g. insufficient-break. Must be one of the registered check codes — any built-in code is accepted, even if your organization is configured to run only a subset of checks (see the checks endpoint); unknown codes return a 400 validation error.

  • Name
    employee_id
    Type
    string (UUID) or null
    Description

    UUID of the employee the rule is limited to, or null for an organization-wide rule that applies to all employees.

  • Name
    valid_from
    Type
    string (YYYY-MM-DD)
    Description

    First day the rule applies to, inclusive. Required.

  • Name
    valid_to
    Type
    string (YYYY-MM-DD) or null
    Description

    Last day the rule applies to, inclusive. null makes the rule permanent. Must not be before valid_from.

  • Name
    created_at
    Type
    string (ISO 8601, local time)
    Description

    When the rule was created. Read-only.

  • Name
    modified_at
    Type
    string (ISO 8601, local time)
    Description

    When the rule was last modified. Read-only.


GET/api/v2/reviews/suppressions/

List all Suppressions

Retrieve a paginated list of your organization's suppression rules. API tokens see every rule of the organization. To filter the findings of a monthly review, request the rules overlapping that month, e.g. ?daterange=2026-05-01|2026-05-31.

Query Parameters

  • Name
    ids
    Type
    string
    Description

    Filter by rule IDs (UUIDs), pipe-separated. Invalid UUIDs are ignored.

  • Name
    daterange
    Type
    string
    Description

    Two dates separated by a pipe, YYYY-MM-DD|YYYY-MM-DD. Returns only rules whose validity interval overlaps the given range. Either side may be empty (2026-05-01| or |2026-05-31). Permanent rules (valid_to is null) are treated as open-ended.

  • Name
    valid_from__lte
    Type
    string (YYYY-MM-DD)
    Description

    Only rules whose valid_from is on or before the given date.

  • Name
    valid_until__gte
    Type
    string (YYYY-MM-DD)
    Description

    Only rules whose valid_to is on or after the given date. Permanent rules (valid_to is null) are always included.

  • Name
    limit
    Type
    integer
    Description

    Number of results per page. Defaults to 100, maximum 1000.

  • Name
    offset
    Type
    integer
    Description

    Number of results to skip for pagination. Defaults to 0.

Request

curl -X GET "https://api.zeitstrom.com/api/v2/reviews/suppressions/?daterange=2026-05-01|2026-05-31" \
  -H "Authorization: Token <YOUR_API_TOKEN>"

Response

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "7f3d2a10-5b7e-4c93-9a41-2f8c6de01b57",
      "code": "insufficient-break",
      "employee_id": "508d5250-7399-4b65-a574-3da53d9ddc25",
      "valid_from": "2026-05-15",
      "valid_to": "2026-05-15",
      "created_at": "2026-05-16T09:21:05",
      "modified_at": "2026-05-16T09:21:05"
    },
    {
      "id": "a1c94b7e-08d2-4f65-b3a9-5e716c20d848",
      "code": "excessive-session-fragmentation",
      "employee_id": null,
      "valid_from": "2026-04-01",
      "valid_to": null,
      "created_at": "2026-04-03T14:04:12",
      "modified_at": "2026-04-03T14:04:12"
    }
  ]
}

GET/api/v2/reviews/suppressions/:id/

Retrieve a Suppression

Get a single suppression rule by its ID.

Request

curl -X GET "https://api.zeitstrom.com/api/v2/reviews/suppressions/7f3d2a10-5b7e-4c93-9a41-2f8c6de01b57/" \
  -H "Authorization: Token <YOUR_API_TOKEN>"

POST/api/v2/reviews/suppressions/

Create a Suppression

Create a new suppression rule. Creation is idempotent on (code, employee_id, valid_from): if a rule with the same combination already exists, the API returns the existing rule with status 200 instead of creating a duplicate — the existing rule's valid_to is preserved and the submitted valid_to is ignored. A newly created rule returns status 201.

  • Name
    code
    Type
    string
    Description

    One of the registered check codes. Required.

  • Name
    employee_id
    Type
    string (UUID) or null
    Description

    Employee to limit the rule to; omit or pass null for an organization-wide rule.

  • Name
    valid_from
    Type
    string (YYYY-MM-DD)
    Description

    First day the rule applies to, inclusive. Required.

  • Name
    valid_to
    Type
    string (YYYY-MM-DD) or null
    Description

    Last day the rule applies to, inclusive. Omit or pass null for a permanent rule.

Request

curl -X POST "https://api.zeitstrom.com/api/v2/reviews/suppressions/" \
  -H "Authorization: Token <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "insufficient-break",
    "employee_id": "508d5250-7399-4b65-a574-3da53d9ddc25",
    "valid_from": "2026-05-15",
    "valid_to": "2026-05-15"
  }'

Response

{
  "id": "7f3d2a10-5b7e-4c93-9a41-2f8c6de01b57",
  "code": "insufficient-break",
  "employee_id": "508d5250-7399-4b65-a574-3da53d9ddc25",
  "valid_from": "2026-05-15",
  "valid_to": "2026-05-15",
  "created_at": "2026-05-16T09:21:05",
  "modified_at": "2026-05-16T09:21:05"
}

PATCH/api/v2/reviews/suppressions/:id/

Update a Suppression

Update individual fields of an existing suppression rule. Only PATCH is supported; full PUT replacement returns 405 Method Not Allowed.

Request

curl -X PATCH "https://api.zeitstrom.com/api/v2/reviews/suppressions/7f3d2a10-5b7e-4c93-9a41-2f8c6de01b57/" \
  -H "Authorization: Token <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "valid_to": "2026-05-31"
  }'

DELETE/api/v2/reviews/suppressions/:id/

Delete a Suppression

Delete a suppression rule. Previously suppressed findings become visible again in clients that apply the rules. On success, the API returns status 204 with no content.

Request

curl -X DELETE "https://api.zeitstrom.com/api/v2/reviews/suppressions/7f3d2a10-5b7e-4c93-9a41-2f8c6de01b57/" \
  -H "Authorization: Token <YOUR_API_TOKEN>"

Was this page helpful?