Live Tracking
The live tracking API controls an employee's running clock in real time: read the currently active timespan, punch in and out, and edit the comment and project assignments of the running timespan. It powers stopwatch-style tracking clients.
If your API token is restricted to specific permissions, it needs the
tracking-employees:add-current-timestamp scope for the
Add a Timestamp, Switch Timespans,
and Update a Timespan endpoints. Requests without the
required permission return 403 Forbidden. All other endpoints on this page
only require a valid token.
Overview
There are three ways to track time via the API:
- App Timestamps - Create durable punch events with client-generated IDs and idempotent retries via the Time Tracking endpoints. This is the recommended approach for external time clocks that may work offline.
- Employee Check-in/Check-out - Simple state transitions on the Employees endpoint, including filter-based selection by RFID token or terminal PIN.
- Live Tracking (this page) - Interactive, per-employee control of the running clock. Unlike the other two approaches, live tracking lets you inspect the active timespan before and after punching, returns the affected timespan directly from a punch, and can update the comment and project/tag assignments of a timespan while the clock is running.
All three approaches write to the same underlying time records, so timespans created here also appear in the Timespans and Workdays endpoints.
The Tracked Employee Object
The list and retrieve endpoints return a minimal employee representation. The
id is the same employee UUID used by the Employees endpoint;
use it for the per-employee actions below. The live tracking state itself is
read via the active timespan and
recent timespan endpoints.
- Name
id- Type
- string (UUID)
- Description
Unique identifier for the employee. Read-only.
The Live Timespan Object
The punch and timespan endpoints on this page return this compact timespan representation.
- Name
id- Type
- string (UUID)
- Description
Unique identifier for the timespan.
- Name
checkin- Type
- object
- Description
The check-in timestamp:
id(UUID),time(local time, no timezone suffix),time_utc(the same instant in UTC), andcreator(one ofadmin,online,device, orsystem). Punches created through this API have the creatoronline.
- Name
checkout- Type
- object or null
- Description
The check-out timestamp with the same fields as
checkin, ornullwhile the timespan is still running.
- Name
employee_comment- Type
- string or null
- Description
Free-text comment of the employee for this timespan.
- Name
project_id- Type
- string (UUID) or null
- Description
Legacy single-project assignment. New integrations should use
tag_assignmentsinstead. Read-only in this representation.
- Name
tag_assignments- Type
- array
- Description
Project/tag assignments of the timespan. Each entry contains
tag_id(the project UUID),type(relativeorabsolute), andvalue(decimal string). Arelativevalue is a percentage of the timespan's duration; anabsolutevalue is a fixed number of seconds.
List all Tracked Employees
Retrieve a paginated list of the employees available for live tracking. API tokens see all employees of the organization.
Query Parameters
- Name
ids- Type
- string
- Description
Restrict the result set to specific employees by passing a pipe-separated list of employee UUIDs. Invalid UUIDs are silently ignored.
- 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/tracking/employees/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
}
]
}
Retrieve a Tracked Employee
Get a single tracked employee. Returns 404 Not Found if the ID is not a
valid UUID or the employee does not belong to your organization.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Get the Active Timespan
Return the employee's currently running timespan as a
live timespan object. A timespan counts as
active while it has no check-out and its check-in is no further in the past
than the employee's working_session:maximum_working_time setting (in
hours). If the employee is not checked in, the endpoint responds with
200 OK and an empty body.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/active-timespan/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"checkin": {
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"time": "2026-07-03T08:00:00",
"time_utc": "2026-07-03T06:00:00",
"creator": "online"
},
"checkout": null,
"employee_comment": "Preparing the quarterly report",
"project_id": null,
"tag_assignments": [
{
"tag_id": "e5f6a7b8-c9d0-1234-efab-567890123456",
"type": "relative",
"value": "100.00000"
}
]
}
Get the Recent Timespan
Return the employee's most recent timespan, whether it is still running or
already closed. This is useful to render a tracking widget that shows either
the running clock or the last completed session. timespan is null if the
employee has no timespans yet. is_active is true only while the timespan
has no check-out and its check-in is within the employee's maximum working
time.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/recent-timespan/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"timespan": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"checkin": {
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"time": "2026-07-02T08:00:00",
"time_utc": "2026-07-02T06:00:00",
"creator": "online"
},
"checkout": {
"id": "8a4c2e9b-1d3f-4b6a-9c8e-2f5a7d1b3e6c",
"time": "2026-07-02T16:30:00",
"time_utc": "2026-07-02T14:30:00",
"creator": "online"
},
"employee_comment": "Customer visit in Hamburg",
"project_id": null,
"tag_assignments": []
},
"is_active": false
}
Add a Timestamp
Record a punch for the employee and return the affected
live timespan object: checking in returns the
newly started timespan with checkout: null, checking out returns the
completed timespan. A checkout punch while no timespan is open fails with a
400 validation error.
- Name
stamp_type- Type
- string
- Description
checkinorcheckout. If omitted (or any other value), the punch is resolved automatically: an open timespan within the maximum working time is closed, otherwise a new timespan is started.
- Name
description- Type
- string or null
- Description
Employee comment for the affected timespan. The comment is always overwritten; omitting the field clears it.
- Name
tag_assignments- Type
- array
- Description
Project/tag assignments applied when the punch starts a new timespan. Each entry contains
tag_id(a project UUID of your organization, required),type(relativeorabsolute, defaults torelative), andvalue(decimal, defaults to100). Cannot be combined withproject_id.
- Name
project_id- Type
- string (UUID)
- Description
Legacy single-project assignment applied when the punch starts a new timespan. Prefer
tag_assignments. Cannot be combined withtag_assignments.
- Name
meta- Type
- object
- Description
Optional punch metadata.
meta.tracked_time(formatYYYY-MM-DDTHH:MM:SS, local time) records the punch at the given time instead of the current server time.meta.location(string) is stored in the timestamp's note.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/add-timestamp/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"stamp_type": "checkout",
"description": "Customer visit in Hamburg"
}'
Response
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"checkin": {
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"time": "2026-07-03T08:00:00",
"time_utc": "2026-07-03T06:00:00",
"creator": "online"
},
"checkout": {
"id": "8a4c2e9b-1d3f-4b6a-9c8e-2f5a7d1b3e6c",
"time": "2026-07-03T16:30:00",
"time_utc": "2026-07-03T14:30:00",
"creator": "online"
},
"employee_comment": "Customer visit in Hamburg",
"project_id": null,
"tag_assignments": [
{
"tag_id": "e5f6a7b8-c9d0-1234-efab-567890123456",
"type": "relative",
"value": "100.00000"
}
]
}
Switch Timespans
Close the employee's current timespan and immediately start a new one at the
same moment. Use this to switch between projects without a gap while the
employee stays checked in. On success, the endpoint responds with 200 OK
and an empty body.
- Name
description- Type
- string or null
- Description
Employee comment stored on the timespan being closed.
- Name
project_id- Type
- string (UUID) or null
- Description
Project assigned to the timespan being closed.
- Name
next_project_id- Type
- string (UUID) or null
- Description
Project assigned to the newly started timespan.
Only call this endpoint while the employee is checked in. If no timespan is running, the first punch starts a timespan and the second one immediately closes it again, leaving a zero-length timespan.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/add-timestamps/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"description": "Finished the morning shift",
"project_id": "e5f6a7b8-c9d0-1234-efab-567890123456",
"next_project_id": "d0e1f2a3-b4c5-6789-defa-901234567890"
}'
Update the Active Comment
Set the employee comment and, optionally, a single project assignment on the
employee's currently active timespan. Both values are always overwritten:
omitting description clears the comment, and omitting project_id removes
all project/tag assignments from the timespan. If the employee is not checked
in, the request is a no-op. The endpoint responds with 200 OK and an empty
body.
- Name
description- Type
- string or null
- Description
Employee comment for the active timespan. Omitting the field clears the comment.
- Name
project_id- Type
- string (UUID) or null
- Description
A project of your organization, assigned as a single
relativeassignment of100. Returns404 Not Foundfor unknown projects. Omitting the field removes all assignments.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/update-comment/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"description": "Preparing the quarterly report",
"project_id": "e5f6a7b8-c9d0-1234-efab-567890123456"
}'
Update Comment and Tag Assignments
Like Update the Active Comment, but with full
control over the tag assignments of the active timespan. The comment and the
assignment list are always replaced: omitting description clears the
comment, and omitting tag_assignments (or passing an empty list) removes
all assignments. If the employee is not checked in, the request is a no-op.
The endpoint responds with 200 OK and an empty body.
- Name
description- Type
- string or null
- Description
Employee comment for the active timespan. Omitting the field clears the comment.
- Name
tag_assignments- Type
- array
- Description
Replacement list of assignments. Each entry contains
tag_id(a project UUID of your organization, required),type(relativeorabsolute, defaults torelative), andvalue(decimal, defaults to100).
Request
curl -X POST "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/update-comment-and-tag-assignments/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"description": "Preparing the quarterly report",
"tag_assignments": [
{ "tag_id": "e5f6a7b8-c9d0-1234-efab-567890123456", "type": "relative", "value": 60 },
{ "tag_id": "d0e1f2a3-b4c5-6789-defa-901234567890", "type": "relative", "value": 40 }
]
}'
Update a Timespan
Update the comment and project/tag assignments of a specific timespan,
addressed by the ID of one of its timestamps (for example the checkin.id or
checkout.id from a previous punch response). Unlike the
update-comment endpoints, fields are only changed when they are present in
the request body. If no timespan exists for the given timestamp, the request
is silently ignored. The endpoint responds with 200 OK and an empty body.
- Name
timestamp_id- Type
- string (UUID)
- Description
ID of a check-in or check-out timestamp of the timespan to update. Required.
- Name
description- Type
- string or null
- Description
New employee comment. Only applied if the field is present.
- Name
tag_assignments- Type
- array
- Description
Replacement list of assignments in the same format as above. Only applied if the field is present. Cannot be combined with
project_id.
- Name
project_id- Type
- string (UUID) or null
- Description
Legacy single-project assignment. The project must exist in your organization. Passing
nullremoves all assignments. Only applied if the field is present. Cannot be combined withtag_assignments.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/tracking/employees/a1b2c3d4-e5f6-7890-abcd-ef1234567890/update-timespan/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"timestamp_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"description": "Customer visit in Hamburg",
"tag_assignments": [
{ "tag_id": "e5f6a7b8-c9d0-1234-efab-567890123456" }
]
}'