Employees
Employees are the core resource in Zeitstrom. They represent the people in your organization whose working time is being tracked. You can create, update, archive, and manage check-ins and check-outs for employees.
The Employee Object
- Name
id- Type
- string (UUID)
- Description
Unique identifier for the employee.
- Name
created_at- Type
- string (ISO 8601)
- Description
Timestamp when the employee was created.
- Name
modified_at- Type
- string (ISO 8601)
- Description
Timestamp when the employee was last modified.
- Name
archived_at- Type
- string (ISO 8601) or null
- Description
Timestamp when the employee was archived, or
nullif active.
- Name
first_name- Type
- string
- Description
The employee's first name. Required.
- Name
last_name- Type
- string
- Description
The employee's last name. Required.
- Name
email- Type
- string
- Description
The employee's email address.
- Name
employee_group_id- Type
- string (UUID) or null
- Description
The ID of the employee group this employee belongs to.
- Name
employee_group_name- Type
- string or null
- Description
The name of the employee group, or
nullif the employee is not assigned to a group. Read-only.
- Name
external_id- Type
- string
- Description
An external identifier for integration with third-party systems.
- Name
external_uid- Type
- string
- Description
An external unique identifier.
- Name
project_id- Type
- string (UUID) or null
- Description
Default project assigned to this employee.
- Name
accounting_number- Type
- string
- Description
The employee's accounting or personnel number.
- Name
hourly_rate- Type
- decimal
- Description
The employee's hourly rate.
- Name
is_male- Type
- boolean
- Description
Gender indicator.
- Name
physical_token_id- Type
- string
- Description
RFID card or physical token identifier (the 10- or 17-digit number printed on the card, see Physical Tokens).
- Name
terminal_pin- Type
- string or null
- Description
PIN code for terminal authentication.
- Name
additional_fields- Type
- object
- Description
Custom key-value data attached to the employee.
- Name
username- Type
- string or null
- Description
The associated user account username, or
nullif the employee has no user account. Read-only.
- Name
user_account_id- Type
- string (UUID) or null
- Description
The ID of the user account linked to this employee, or
nullif none is linked. Read-only.
- Name
can_be_deleted- Type
- boolean
- Description
Whether the employee can be permanently deleted. This is only
trueonce the employee has been archived for at least the number of years given bydelete_after_archive_period; it is alwaysfalsefor active employees. Read-only.
- Name
delete_after_archive_period- Type
- integer
- Description
Number of years after archiving until the employee becomes permanently deletable. Currently always
2. Read-only.
List all Employees
Retrieve a paginated list of employees. By default, archived employees are excluded.
Query Parameters
- Name
q- Type
- string
- Description
Search by full name or token number.
- Name
employee_groups- Type
- string
- Description
Filter by employee group IDs, pipe-separated. Use
nullfor ungrouped employees.
- Name
archived- Type
- string
- Description
Filter by archive status:
true,false(default), orall. This filter only applies to the list endpoint — retrieving an employee by ID works regardless of archive state.
- Name
ids- Type
- string
- Description
Filter by employee IDs, pipe-separated UUIDs.
- Name
external_uids- Type
- string
- Description
Filter by external UIDs, pipe-separated.
- Name
token- Type
- string
- Description
Filter by RFID token, pipe-separated.
- Name
terminal_pins- Type
- string
- Description
Filter by terminal PINs, pipe-separated.
- Name
modified_at__gte- Type
- string (ISO 8601)
- Description
Return only employees modified after this timestamp.
- Name
verbosity- Type
- string
- Description
Response detail level:
device,minimal,absence, ordetail.
- Name
absence_count__gte- Type
- integer
- Description
Only return employees with at least this many absences. Only applies with
verbosity=absence.
- Name
absence_daterange- Type
- string
- Description
Only consider absences within this date range, formatted as
YYYY-MM-DD|YYYY-MM-DD. Either side may be left empty for an open-ended range (e.g.|2024-05-31or2024-05-01|). Only applies withverbosity=absence.
- Name
absence_missing_types- Type
- string
- Description
Only consider absences of the given types, pipe-separated (e.g.
sickday|holiday). Only applies withverbosity=absence.
- Name
limit- Type
- integer
- Description
Number of results per page. Defaults to
100, maximum is1000.
- Name
offset- Type
- integer
- Description
Number of results to skip for pagination.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/?archived=false&q=Mustermann" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2024-01-15T08:30:00",
"modified_at": "2024-06-20T14:22:00",
"archived_at": null,
"first_name": "Max",
"last_name": "Mustermann",
"email": "max@example.com",
"username": "max.mustermann",
"user_account_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"employee_group_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"employee_group_name": "Engineering",
"external_id": "EMP-001",
"external_uid": "EXT-001",
"project_id": null,
"accounting_number": "1001",
"hourly_rate": "25.00",
"is_male": true,
"physical_token_id": "0426835710",
"terminal_pin": "1234",
"can_be_deleted": false,
"delete_after_archive_period": 2,
"additional_fields": {}
}
]
}
Retrieve an Employee
Get details of a specific employee by their UUID.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Create an Employee
Create a new employee in your organization.
Required Parameters
- Name
first_name- Type
- string
- Description
The employee's first name.
- Name
last_name- Type
- string
- Description
The employee's last name.
Optional Parameters
- Name
email- Type
- string
- Description
Email address.
- Name
employee_group_id- Type
- string (UUID)
- Description
Assign to an employee group.
- Name
external_id- Type
- string
- Description
External identifier for third-party integration.
- Name
accounting_number- Type
- string
- Description
Personnel or accounting number.
- Name
hourly_rate- Type
- decimal
- Description
Hourly rate.
- Name
physical_token_id- Type
- string
- Description
RFID card identifier.
- Name
terminal_pin- Type
- string
- Description
PIN code for terminal access.
- Name
project_id- Type
- string (UUID)
- Description
Default project assignment.
- Name
additional_fields- Type
- object
- Description
Custom key-value data.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Erika",
"last_name": "Mustermann",
"email": "erika@example.com",
"employee_group_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"accounting_number": "1002"
}'
Update an Employee
Update an existing employee. With PATCH, only the fields you include in the request body will be changed. PUT is also supported for a full replacement, in which case all required fields must be present.
Request
curl -X PATCH "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"email": "max.mustermann@newdomain.com",
"hourly_rate": "30.00"
}'
Delete an Employee
Permanently delete an employee. This is only possible if can_be_deleted is true, which requires the employee to have been archived for at least two years (see delete_after_archive_period). Deleting an active or recently archived employee fails with a validation error. For most cases, use archiving instead.
Request
curl -X DELETE "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Archive an Employee
Archive an employee instead of deleting them. Archived employees are excluded from listings by default but their historical data is preserved.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Restore an Employee
Restore a previously archived employee back to active status.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/restore/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Reset an Employee Password
Generate a new initial password for the employee's linked user account. The request fails with a validation error if the employee is archived, and has no effect if the employee has no linked user account. Returns the employee object.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/reset-password/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Send an Invite
Send an invitation email to the employee so they can log in to Zeitstrom. The employee must have a linked user account (user_account_id is not null). success is false if the employee has no email address.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/send-invite/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"success": true
}
Check-in an Employee
Start tracking working time for an employee. You can optionally assign a project code to the check-in.
- Name
project_code- Type
- string
- Description
Optional project code to assign to this working session.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/checkin/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"project_code": "P-101"
}'
You can also check in by filter instead of by ID by calling POST /api/v2/employees/employees/checkin/ without an employee ID. Use query parameters like token or terminal_pins to select the employee. The filters must resolve to exactly one employee: the request fails with 400 if more than one employee matches and 404 if none matches.
Check-out an Employee
Stop tracking working time for an employee. This closes the current open timespan.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/checkout/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
A filter-based variant is available at POST /api/v2/employees/employees/checkout/ without an employee ID. As with the filter-based check-in, the query parameters must resolve to exactly one employee (400 if more than one matches, 404 if none matches).
Custom Check-out
Perform a manual check-out with a custom start and end time. The punchtime must be within 15 minutes in the past or 5 minutes in the future.
- Name
starttime- Type
- string (ISO 8601)
- Description
The check-in time to set. Required. Must be before
punchtime.
- Name
punchtime- Type
- string (ISO 8601)
- Description
The check-out time. Optional — defaults to the current server time when omitted. Must be close to the current time.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/custom-checkout/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"starttime": "2024-06-20T08:00:00",
"punchtime": "2024-06-20T16:30:00"
}'
A filter-based variant is available at POST /api/v2/employees/employees/custom-checkout/ without an employee ID. As with the filter-based check-in, the query parameters must resolve to exactly one employee (400 if more than one matches, 404 if none matches).
Employee Settings
Retrieve or update the settings that currently apply to a specific employee, such as their daily working times. Settings are grouped by category: both the response and the update payload use the nested structure {"<category>": {"<setting>": <value>}}.
To update settings, send a POST request with the same nested structure. The update replaces the employee-level settings as a whole: any employee-level setting not included in the payload is removed and falls back to the group or institution default. Always send the complete set of employee-level settings you want to keep.
Retrieve Settings
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/settings/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Update Settings
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/settings/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"working_session": {
"daily_working_times": [8, 8, 8, 8, 8, 0, 0]
}
}'
Response
{
"working_session": {
"daily_working_times": [8, 8, 8, 8, 8, 0, 0],
"public_holidays": "active",
"use_working_hour_balance": "active",
"weekly_working_time": 40
}
}
Unknown setting keys — including deprecated compatibility values such as weekly_working_time that appear in the retrieve response — are silently ignored on update. Only settings that exist in the current settings catalog are persisted.
Historical Settings
Retrieve all settings of an employee including values that are no longer or not yet applicable. Each setting is returned as a list of values with their validity range. Unlike other datetimes in this API, the valid_from and valid_before bounds are returned in UTC with a Z suffix.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/settings-historical/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"working_session": {
"daily_working_times": [
{
"valid_from": "2023-12-31T23:00:00Z",
"valid_before": "2024-05-31T22:00:00Z",
"value": [8, 8, 8, 8, 8, 0, 0]
},
{
"valid_from": "2024-05-31T22:00:00Z",
"valid_before": null,
"value": [6, 6, 6, 6, 6, 0, 0]
}
]
}
}
Employee Working Time
Retrieve the target working time of an employee for each day within a date range.
Query Parameters
- Name
daterange- Type
- string
- Description
The date range to compute, formatted as
YYYY-MM-DD|YYYY-MM-DD. Required. Either side may be left empty; empty sides default to today.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/working-time/?daterange=2024-06-20|2024-06-21" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
[
{
"date": "2024-06-20",
"target_time": 8.0,
"proportion": 1.0
},
{
"date": "2024-06-21",
"target_time": 8.0,
"proportion": 1.0
}
]
Setup Instructions
Retrieve login setup instructions for an employee as an HTML page. Pass ?output=pdf to receive the instructions as a PDF document instead, e.g. for printing and handing out to the employee.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/setup-instructions/?output=pdf" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-o setup-instructions.pdf
Employee Meta
Provide general information about the employees accessible to you. has_archived_employees contains the number of archived employees matching your filters; use it to decide whether to offer an archived view instead of listing with archived=all.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/employees/employees/meta/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"has_archived_employees": 3
}
Bulk Import (CSV)
Import or synchronize employees from a CSV file. Employees are matched by external_uid, which is the only mandatory field. New employees are created, existing ones are updated, and employees not present in the import will be archived. The field order must be declared in the first row (header); available fields are the same as for the JSON import below.
Modification Limits
The server processes at most 50 modifications (creations, updates, or archivals) per request. Send your complete employee list in a single request anyway: if the limit is reached, processing stops and the remaining field of the response reports the number of unprocessed employees. Resubmit the identical request until remaining is 0. This is typically only needed for initial imports.
Group Syncing
If any entry provides a group_id, archiving is restricted to employees within the submitted groups — employees in other groups are left untouched.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/synch/csv/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: text/csv" \
--data-binary @employees.csv
Response
{
"created": 5,
"updated": 12,
"untouched": 83,
"remaining": 0,
"archived": 2
}
The response fields are: created (newly created employees), updated (processed employees with changes), untouched (processed employees without changes), remaining (employees not yet processed in this request), and archived (employees archived by this request).
Bulk Import (JSON)
Import or synchronize employees using a JSON payload. Each entry requires an external_uid for matching: new employees are created, existing ones are updated, and employees not present in the import will be archived. The same modification limits and group syncing rules as for the CSV import apply — resubmit the identical request until the remaining field of the response is 0, and providing any group_id restricts archiving to the submitted groups. The response has the same format as the CSV import.
- Name
external_uid- Type
- string
- Description
Unique external identifier for matching. Required.
- Name
first_name- Type
- string
- Description
Employee's first name.
- Name
last_name- Type
- string
- Description
Employee's last name.
- Name
email- Type
- string
- Description
Employee's email address.
- Name
external_id- Type
- string
- Description
Additional external identifier.
- Name
accounting_number- Type
- string
- Description
Accounting or personnel number.
- Name
group_id- Type
- string (UUID)
- Description
Employee group to assign.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/employees/employees/synch/json/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '[
{
"external_uid": "EXT-001",
"first_name": "Max",
"last_name": "Mustermann",
"email": "max@example.com"
},
{
"external_uid": "EXT-002",
"first_name": "Erika",
"last_name": "Mustermann",
"email": "erika@example.com"
}
]'