Authentication
- Header
Authorization: Bearer tiveo_…on every call - Format:
tiveo_plus 43 characters; Tiveo stores only the SHA-256 value - At most 5 active keys per company, revocable at any time
- No CORS: meant for servers, never for the browser
For developers
from Business
Bring employees, absences, time and shifts from Tiveo into your own systems.
Three steps to your first response.
Owners or administrators: Settings › Integrations › API. Choose scopes, optionally an expiry date. Store the key right away, because it is shown only once.
/v1/me needs no particular scope and shows what the key may do.
curl https://api.tiveo.de/v1/me \
-H "Authorization: Bearer tiveo_…" Company, scopes, limits and modules. Then carry on with the reference below.
{
"data": {
"beta": true,
"company": {
"id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"name": "Tischlerei Muster GmbH",
"country": "DE",
"region": "NW",
"time_zone": "Europe/Berlin"
},
"key": {
"id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"name": "Lohnbüro",
"scopes": [
"employees:read",
"absences:read"
],
"expires_on": null
},
"limits": {
"per_minute": 60,
"per_day": 10000,
"max_page_size": 200
},
"modules": {
"time_tracking": true,
"shift_planning": false,
"vehicle_logbook": false
},
"write_access": false
}
} Authorization: Bearer tiveo_… on every calltiveo_ plus 43 characters; Tiveo stores only the SHA-256 valuedata and next_cursorlimit sets the page size: default 50, at most 200cursor = next_cursor, until it is nullupdated_since returns only changes, for example when syncing/v1/me under limitsRetry-After says when to continueRateLimit-LimitRateLimit-RemainingRateLimit-ResetX-Daily-LimitX-Daily-RemainingRetry-After/v1, fields and endpoints are only added/v2; /v1 then stays for at least six monthsabsences:read_sensitive, otherwise “absent”Each key carries only the scopes you choose when creating it.
| Scope | Allows | Status |
|---|---|---|
employees:read | Read employees and units (departments, teams, locations). | available |
absences:read | Read absences, absence types, leave balances and holidays. Sickness and other sensitive types appear only as “absent”. | available |
absences:read_sensitive | Additionally read the type of sensitive absences (e.g. sickness) — health data under Art. 9 GDPR. Only grant if the receiving system is allowed to process it. | available |
time:read | Read clock events, daily time sheets, projects and project times (time tracking module). | available |
shifts:read | Read published shifts and shift types (shift planning module). | available |
vehicles:read | Read vehicles, trips, vehicle costs and approved mileage allowances (vehicle logbook module). Never the route. | available |
employees:write | Planned: create employees and change master data. | planned |
absences:write | Planned: create, approve, reject and cancel absences. | planned |
time:write | Planned: record working time. | planned |
shifts:write | Planned: assign shifts. | planned |
Errors come as application/problem+json as per RFC 9457. What counts is code; type points to the row here.
{
"type": "https://tiveo.de/entwickler/#fehler-insufficient-scope",
"title": "API key lacks the required scope",
"status": 403,
"code": "insufficient_scope",
"detail": "This API key needs the scope \"time:read\"."
} | Code | Status | Meaning |
|---|---|---|
invalid_parameter | 400 | A parameter is missing or wrong; detail names it. |
invalid_key | 401 | No API key or an unknown one. |
key_revoked | 401 | The key was revoked. |
key_expired | 401 | The key has expired. |
insufficient_scope | 403 | The key lacks the required scope. |
plan_required | 403 | The API is available from the Business plan. |
api_paused | 403 | The API is paused for this company. |
company_locked | 403 | The company account is locked or closed. |
module_not_active | 403 | The company does not use this module. |
write_not_available_in_beta | 403 | Writing is not available during the beta. |
not_found | 404 | Unknown path or id. |
method_not_allowed | 405 | GET only. |
rate_limited | 429 | Too many requests per minute; Retry-After says when to continue. |
daily_limit_reached | 429 | The daily limit of the company is reached. |
too_many_failed_attempts | 429 | Too many invalid keys from this address; Retry-After says when to continue (up to 15 minutes). |
internal_error | 500 | Error on our side; retry later. |
server_busy | 503 | The API is busy or the request took too long; honour Retry-After, narrow the period. |
All paths under https://api.tiveo.de/v1. GET only.
GET /v1/me
Scope: any valid key
Company, scopes and limits of this key — the first call of every integration.
No parameters.
| Name | Type | Meaning |
|---|---|---|
beta | boolean | The API is in beta. |
company | object | The company of the key. |
company.id | string · uuid | Company id. |
company.name | string | Name. |
company.country | string | Country (DE, AT, CH). |
company.region | string or null | Default region for holidays. |
company.time_zone | string | Time zone. |
key | object | The key. |
key.id | string · uuid | Key id. |
key.name | string | Name given by the company. |
key.scopes | array<string> | Scopes. |
key.expires_on | string · date or null | Expires (valid through this day). |
limits | object | Limits of the company. |
limits.per_minute | integer | Requests per minute. |
limits.per_day | integer | Requests per day. |
limits.max_page_size | integer | Largest page (limit). |
modules | object | Which modules the company uses. |
modules.time_tracking | boolean | Time tracking. |
modules.shift_planning | boolean | Shift planning. |
modules.vehicle_logbook | boolean | Vehicle logbook. |
write_access | boolean | Writing possible — always false during the beta. |
{
"data": {
"beta": true,
"company": {
"id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"name": "Tischlerei Muster GmbH",
"country": "DE",
"region": "NW",
"time_zone": "Europe/Berlin"
},
"key": {
"id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"name": "Lohnbüro",
"scopes": [
"employees:read",
"absences:read"
],
"expires_on": null
},
"limits": {
"per_minute": 60,
"per_day": 10000,
"max_page_size": 200
},
"modules": {
"time_tracking": true,
"shift_planning": false,
"vehicle_logbook": false
},
"write_access": false
}
} GET /v1/employees GET /v1/employees/{id}
Scope: employees:read
All employees of the company, including records without an account and leavers. Without sample persons and admin-only accounts.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
status | string | Only this status. Values: record_only invited active inactive left |
unit_id | string · uuid | Only this unit (main unit). |
updated_since | string · date-time | Only what changed since this moment (ISO 8601 with offset) — for syncing. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id of the person in this company. |
personnel_number | string or null | Personnel number. |
display_name | string | Display name. |
first_name | string or null | First name (from the account, else null). |
last_name | string or null | Last name (from the account, else null). |
email | string or null | Email address. |
role | string | Role in Tiveo. Values: owner admin hr manager employee |
status | string | record_only = record without account, invited, active, inactive = on hold, left. Values: record_only invited active inactive left |
unit_id | string · uuid or null | Main unit. |
additional_unit_ids | array<uuid> | Additional units. |
region | string or null | Region for holidays, if different. |
entry_date | string · date or null | Entry date. |
exit_date | string · date or null | Exit date. |
weekly_hours | number or null | Weekly hours of today’s working model. |
created_at | string · date-time | Created. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"personnel_number": "00042",
"display_name": "Anna Achter",
"first_name": "Anna",
"last_name": "Achter",
"email": "anna.achter@example.com",
"role": "employee",
"status": "active",
"unit_id": "8c0e4f7a-2d1b-4c3e-9a55-6f7e8d9c0b1a",
"additional_unit_ids": [],
"region": null,
"entry_date": "2024-01-01",
"exit_date": null,
"weekly_hours": 40,
"created_at": "2026-03-02T08:14:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/units GET /v1/units/{id}
Scope: employees:read
Divisions, departments, teams and locations as a tree (parent_id), with leads.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
parent_id | string · uuid or null | Parent unit. |
name | string | Name. |
type | string | Kind. Values: division department team location |
region | string or null | Region for holidays. |
active | boolean | Active. |
sort_order | integer or null | Sort order. |
leads | array<object> | Leads and deputies. |
leads[].employee_id | string · uuid | Employee. |
leads[].kind | string | Lead or deputy. Values: lead deputy |
created_at | string · date-time | Created. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "8c0e4f7a-2d1b-4c3e-9a55-6f7e8d9c0b1a",
"parent_id": null,
"name": "Werkstatt",
"type": "team",
"region": null,
"active": true,
"sort_order": 10,
"leads": [
{
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"kind": "lead"
}
],
"created_at": "2026-03-02T08:14:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/absence-types GET /v1/absence-types/{id}
Scope: absences:read
Leave, sickness, remote work and the company’s own types.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
key | string | Key (urlaub, krankheit … or custom). |
name | object | Name in German and English. |
name.de | string | German. |
name.en | string | English. |
short_name | string | Short name (1–3 characters). |
color | string | Colour (#rrggbb). |
text_color | string | Text colour (#rrggbb). |
counts_against_allowance | boolean | Counts against the leave allowance. |
requires_approval | boolean | Requires approval. |
requires_certificate | boolean | Requires a certificate. |
half_days_allowed | boolean | Half days allowed. |
sensitive | boolean | Sensitive (e.g. sickness): masked without absences:read_sensitive. |
active | boolean | Active. |
sort_order | integer or null | Sort order. |
{
"data": [
{
"id": "b7d1e2f3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
"key": "urlaub",
"name": {
"de": "Urlaub",
"en": "Annual leave"
},
"short_name": "U",
"color": "#1a7d57",
"text_color": "#ffffff",
"counts_against_allowance": true,
"requires_approval": true,
"requires_certificate": false,
"half_days_allowed": true,
"sensitive": false,
"active": true,
"sort_order": 10
}
],
"next_cursor": null
} GET /v1/absences GET /v1/absences/{id}
Scope: absences:read
Requests and recorded absences, without drafts and without free text. Without absences:read_sensitive, sensitive types are masked (masked: true, type_id: null).
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
from | string · date | Only absences ending on or after this day. |
to | string · date | Only absences starting on or before this day. |
employee_id | string · uuid | Only this employee. |
status | string | Only this status. Values: requested partially_approved approved rejected cancellation_requested cancelled |
updated_since | string · date-time | Only what changed since this moment (ISO 8601 with offset) — for syncing. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
employee_id | string · uuid | Employee. |
type_id | string · uuid or null | Absence type; null if masked. |
masked | boolean | Type hidden (sensitive, scope missing). |
start_date | string · date | First day. |
end_date | string · date | Last day. |
start_day_part | string | First day full or half. Values: full morning afternoon |
end_day_part | string | Last day full or half. Values: full morning afternoon |
working_days | number | Working days the absence takes. |
status | string | Request status. Values: requested partially_approved approved rejected cancellation_requested cancelled |
created_at | string · date-time | Created. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"type_id": "b7d1e2f3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
"masked": false,
"start_date": "2026-08-03",
"end_date": "2026-08-14",
"start_day_part": "full",
"end_day_part": "full",
"working_days": 10,
"status": "approved",
"created_at": "2026-03-02T08:14:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/leave-balances
Scope: absences:read
Per employee and year: entitlement, taken, requested, remaining and carry-over — calculated live as in the app. Pages by employee.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page (an employee id). |
year | integer | Year, default the current one. from 2000 to 2100 |
employee_id | string · uuid | Only this employee. |
| Name | Type | Meaning |
|---|---|---|
employee_id | string · uuid | Employee. |
year | integer | Year. |
entitlement | number or null | Entitlement in days (incl. carry-over). |
approved | number or null | Approved. |
requested | number or null | Requested, pending. |
remaining | number or null | Remaining. |
carry_over | number or null | Carry-over from last year. |
carry_over_remaining | number or null | Of which still open. |
carry_over_expires_on | string · date or null | Carry-over expires on. |
expiring | number or null | About to expire. |
expired | number or null | Expired. |
paid_out | number or null | Paid out. |
{
"data": [
{
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"year": 2026,
"entitlement": 30,
"approved": 18,
"requested": 2,
"remaining": 10,
"carry_over": 3,
"carry_over_remaining": 0,
"carry_over_expires_on": "2026-03-31",
"expiring": 0,
"expired": 0,
"paid_out": 0
}
],
"next_cursor": null
} GET /v1/holidays
Scope: absences:read
Public holidays (by country and region) and company days off of one year, by date. No paging.
| Name | Type | Meaning |
|---|---|---|
year | integer | Year, default the current one. from 2000 to 2100 |
region | string | Region like NW or BY, default the company’s region. |
| Name | Type | Meaning |
|---|---|---|
date | string · date | Day. |
name | string | Name. |
kind | string | Public or set by the company. Values: public_holiday company_day_off |
region | string or null | Region. |
unit_id | string · uuid or null | Only for this unit (days off). |
value | number | 1 full, 0.5 half day. |
deducted_from_leave | boolean | Deducted from leave. |
{
"data": [
{
"date": "2026-12-25",
"name": "1. Weihnachtstag",
"kind": "public_holiday",
"region": "NW",
"unit_id": null,
"value": 1,
"deducted_from_leave": false
}
],
"next_cursor": null
} GET /v1/time-entries
Scope: time:read time recording only
Clock-in, clock-out and breaks as they stand: without cancelled and replaced entries. Period at most 93 days.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
from required | string · date | First day (YYYY-MM-DD). |
to required | string · date | Last day, inclusive. |
employee_id | string · uuid | Only this employee. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
employee_id | string · uuid | Employee. |
kind | string | Kind. Values: clock_in clock_out break_start break_end |
timestamp | string · date-time | Moment. |
work_date | string · date | Work day the entry belongs to. |
source | string | Source. Values: app terminal manual correction import automatic sample |
location | string or null | Location. Values: on_site remote |
recorded_at | string · date-time | Recorded at. |
{
"data": [
{
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"kind": "clock_in",
"timestamp": "2026-10-19T06:58:00Z",
"work_date": "2026-10-19",
"source": "app",
"location": "on_site",
"recorded_at": "2026-10-19T06:58:02Z"
}
],
"next_cursor": null
} GET /v1/timesheets
Scope: time:read time recording only
Per employee and day: work, break, target and balance in minutes — calculated like “My times”. Period at most 62 days; limit counts employees (default 10, max 25).
| Name | Type | Meaning |
|---|---|---|
limit | integer | Employees per page, default 10. |
cursor | string · uuid | next_cursor of the previous page (an employee id). |
from required | string · date | First day; at most 62 days to to. |
to required | string · date | Last day, inclusive. |
employee_id | string · uuid | Only this employee. |
| Name | Type | Meaning |
|---|---|---|
employee_id | string · uuid | Employee. |
date | string · date | Day. |
recorded | boolean | There are entries. |
start | string · date-time or null | Start. |
end | string · date-time or null | End. |
work_minutes | integer or null | Work. |
break_minutes | integer or null | Break. |
deducted_break_minutes | integer or null | Break deducted by the break rule. |
target_minutes | integer or null | Target. |
credit_minutes | integer or null | Credit (leave, sickness, holiday). |
balance_minutes | integer or null | Balance of the day. Empty while the day is still running, or if the company keeps open days separate and the clock-out is missing (open). |
open | boolean or null | Incomplete (e.g. clock-out missing). |
running | boolean or null | Running right now. |
violations | array<string> | Working time act notices (codes). |
absent | boolean | Absent that day (without type). |
{
"data": [
{
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"date": "2026-10-19",
"recorded": true,
"start": "2026-10-19T06:58:00Z",
"end": "2026-10-19T15:31:00Z",
"work_minutes": 483,
"break_minutes": 30,
"deducted_break_minutes": 0,
"target_minutes": 480,
"credit_minutes": 0,
"balance_minutes": 3,
"open": false,
"running": false,
"violations": [],
"absent": false
}
],
"next_cursor": null
} GET /v1/projects GET /v1/projects/{id}
Scope: time:read time recording only
Projects employees book time on.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
number | string or null | Project number. |
title | string | Title. |
link | string or null | Link. |
contact_employee_id | string · uuid or null | Contact person. |
active | boolean | Active. |
created_at | string · date-time | Created. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
"number": "P-2026-014",
"title": "Dachstuhl Hauptstraße",
"link": null,
"contact_employee_id": null,
"active": true,
"created_at": "2026-03-02T08:14:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/project-times
Scope: time:read time recording only
Booked minutes per employee, day and project. Period at most 93 days.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
from required | string · date | First day (YYYY-MM-DD). |
to required | string · date | Last day, inclusive. |
employee_id | string · uuid | Only this employee. |
project_id | string · uuid | Only this project. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
employee_id | string · uuid | Employee. |
date | string · date | Day. |
project_id | string · uuid or null | Project; null for free text. |
text | string or null | Free text instead of a project. |
minutes | integer | Minutes. |
note | string or null | Note. |
recorded_at | string · date-time | Recorded at. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "d5e6f7a8-b9c0-4d1e-8f2a-3b4c5d6e7f80",
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"date": "2026-10-19",
"project_id": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
"text": null,
"minutes": 240,
"note": null,
"recorded_at": "2026-10-19T15:40:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/shift-types GET /v1/shift-types/{id}
Scope: shifts:read shift planning only
Early, late, on-call and other types with times.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
unit_id | string · uuid or null | Unit. |
name | string | Name. |
short_name | string | Short name. |
color | string | Colour (#rrggbb). |
start_time | string · time or null | Start (local time). |
end_time | string · time or null | End (local time). |
break_minutes | integer | Break. |
kind | string | Kind. Values: shift on_call_duty standby training appointment |
active | boolean | Active. |
sort_order | integer or null | Sort order. |
{
"data": [
{
"id": "f7a8b9c0-d1e2-4f3a-9b4c-5d6e7f8a9b0c",
"unit_id": "8c0e4f7a-2d1b-4c3e-9a55-6f7e8d9c0b1a",
"name": "Frühdienst",
"short_name": "F",
"color": "#2563eb",
"start_time": "06:00:00",
"end_time": "14:00:00",
"break_minutes": 30,
"kind": "shift",
"active": true,
"sort_order": 10
}
],
"next_cursor": null
} GET /v1/shifts
Scope: shifts:read shift planning only
Published shifts, including dropped and cancelled ones; no drafts, no notes. Period at most 93 days.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
from required | string · date | First day (YYYY-MM-DD). |
to required | string · date | Last day, inclusive. |
employee_id | string · uuid | Only this employee. |
unit_id | string · uuid | Only this unit. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
employee_id | string · uuid or null | Employee; null for an open shift. |
unit_id | string · uuid | Unit. |
shift_type_id | string · uuid or null | Shift type. |
date | string · date | Day. |
start | string · date-time | Start. |
end | string · date-time | End. |
break_minutes | integer | Break. |
status | string | Status. Values: published dropped cancelled |
dropped_reason | string or null | Reason for a dropped shift; “sickness” only with absences:read_sensitive, else “absence”. Values: leave sickness absence company |
published_at | string · date-time or null | Published at. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"unit_id": "8c0e4f7a-2d1b-4c3e-9a55-6f7e8d9c0b1a",
"shift_type_id": "f7a8b9c0-d1e2-4f3a-9b4c-5d6e7f8a9b0c",
"date": "2026-10-20",
"start": "2026-10-20T04:00:00Z",
"end": "2026-10-20T12:00:00Z",
"break_minutes": 30,
"status": "published",
"dropped_reason": null,
"published_at": "2026-10-01T09:00:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/vehicles GET /v1/vehicles/{id}
Scope: vehicles:read vehicle logbook only
Company vehicles (pool and assigned cars) and employees’ own cars used for mileage allowance, including retired ones.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
license_plate | string | License plate. |
name | string or null | Name. |
kind | string | Company vehicle or an employee’s own car. Values: company private |
usage | string or null | Pool vehicle or assigned car; null for an own car. Values: pool assigned |
private_use | boolean | Private trips allowed. |
drive | string | Drive. Values: combustion hybrid electric |
list_price | number or null | Gross list price in euros. |
first_registration | string · date or null | First registration. |
start_odometer | integer | Odometer at the start of the logbook. |
logbook_from | string · date | Logbook from. |
inspection_due | string · date or null | Vehicle inspection due. |
safety_check_due | string · date or null | Safety check due. |
owner_employee_id | string · uuid or null | Owner for an own car. |
unit_id | string · uuid or null | Location unit. |
retired_on | string · date or null | Retired from. |
created_at | string · date-time | Created. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"license_plate": "D-AB 123",
"name": "Caddy",
"kind": "company",
"usage": "pool",
"private_use": false,
"drive": "combustion",
"list_price": 38500,
"first_registration": "2024-03-01",
"start_odometer": 12500,
"logbook_from": "2026-11-01",
"inspection_due": "2027-05-31",
"safety_check_due": null,
"owner_employee_id": null,
"unit_id": null,
"retired_on": null,
"created_at": "2026-03-02T08:14:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/trips
Scope: vehicles:read vehicle logbook only
Trips in their current version, without cancelled ones. Private trips and commutes only with day and kilometres. Protected business partners only as a number. Never the route. Period at most 93 days.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
from required | string · date | First day (YYYY-MM-DD). |
to required | string · date | Last day, inclusive. |
employee_id | string · uuid | Only this employee. |
vehicle_id | string · uuid | Only this vehicle. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Trip id (the same across all versions). |
version | integer | Version; every change is a new one. |
journey_id | string · uuid | Journey: parts of a mixed trip share it. |
split_from_id | string · uuid or null | Split off from this trip. |
vehicle_id | string · uuid | Vehicle. |
employee_id | string · uuid | Driver. |
category | string | Business, private or commute. Values: business private commute |
date | string · date | Day (local time). |
start | string · date-time or null | Start; null for private trips and commutes. |
end | string · date-time or null | End; null while running and for private trips and commutes. |
odometer_start | integer or null | Odometer at the start. |
odometer_end | integer or null | Odometer at the end. |
distance_km | integer or null | Kilometres driven. |
origin | string or null | Origin; protected partners as “Nr. 17”. |
destination | string or null | Destination; protected partners as “Nr. 17”. |
purpose | string or null | Purpose. |
business_partner | string or null | Business partner visited; protected partners as “Nr. 17”. |
detour | string or null | Detour and reason. |
project_id | string · uuid or null | Project. |
status | string | Running, open (can still be completed) or closed. Values: running open closed |
incomplete | boolean | Details are missing. |
changed | boolean | Changed after recording (history in Tiveo). |
late_entry | boolean | Added later or recorded after the deadline. |
recorded_at | string · date-time or null | Recorded at (first version); null for private trips and commutes. |
updated_at | string · date-time or null | This version recorded at; null for private trips and commutes. |
{
"data": [
{
"id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
"version": 2,
"journey_id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
"split_from_id": null,
"vehicle_id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"category": "business",
"date": "2026-11-03",
"start": "2026-11-03T07:40:00Z",
"end": "2026-11-03T08:25:00Z",
"odometer_start": 12500,
"odometer_end": 12542,
"distance_km": 42,
"origin": "Werkstatt",
"destination": "Kunde Meier, Hauptstraße 1, 40210 Düsseldorf",
"purpose": "Wartung Heizung",
"business_partner": "Herr Meier",
"detour": null,
"project_id": null,
"status": "closed",
"incomplete": false,
"changed": false,
"late_entry": false,
"recorded_at": "2026-11-03T07:40:05Z",
"updated_at": "2026-11-03T08:26:10Z"
}
],
"next_cursor": null
} GET /v1/vehicle-costs
Scope: vehicles:read vehicle logbook only
Costs per vehicle, without note and without the receipt (only whether there is one). Period at most 366 days.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
from required | string · date | First day (YYYY-MM-DD). |
to required | string · date | Last day, inclusive. |
vehicle_id | string · uuid | Only this vehicle. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id. |
vehicle_id | string · uuid | Vehicle. |
date | string · date | Day. |
kind | string | Kind. Values: fuel charging workshop tyres insurance tax leasing financing depreciation tolls_parking cleaning other |
amount_gross | number | Gross amount in euros. |
amount_net | number or null | Net amount in euros. |
quantity | number or null | Quantity (litres or kWh). |
odometer | integer or null | Odometer. |
has_receipt | boolean | A receipt is stored in Tiveo. |
recorded_at | string · date-time | Recorded at. |
updated_at | string · date-time | Last changed. |
{
"data": [
{
"id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
"vehicle_id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"date": "2026-11-04",
"kind": "fuel",
"amount_gross": 71.4,
"amount_net": 60,
"quantity": 38.2,
"odometer": 12542,
"has_receipt": true,
"recorded_at": "2026-11-04T16:02:00Z",
"updated_at": "2026-10-01T12:30:00Z"
}
],
"next_cursor": null
} GET /v1/mileage-allowances
Scope: vehicles:read vehicle logbook only
Approved mileage allowance for business trips with an own car: the latest version per employee and month.
| Name | Type | Meaning |
|---|---|---|
limit | integer | Items per page, default 50, at most the company’s page size (usually 200). |
cursor | string · uuid | next_cursor of the previous page. |
year | integer | Year, default the current one. from 2000 to 2100 |
employee_id | string · uuid | Only this employee. |
| Name | Type | Meaning |
|---|---|---|
id | string · uuid | Id of this approval. |
employee_id | string · uuid | Employee. |
month | string · date | Month (the first day). |
version | integer | Version; a new approval replaces the old one. |
distance_km | integer | Kilometres. |
rate | number | Rate per kilometre in euros. |
amount | number | Amount in euros. |
trip_count | integer | Trips. |
approved_at | string · date-time | Approved at. |
{
"data": [
{
"id": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b",
"employee_id": "3f2a9c1e-7b4d-4e8a-9f61-2c5d8e0b1a74",
"month": "2026-10-01",
"version": 1,
"distance_km": 420,
"rate": 0.3,
"amount": 126,
"trip_count": 18,
"approved_at": "2026-11-02T09:15:00Z"
}
],
"next_cursor": null
} Planned and already described. During the beta these always answer 403 write_not_available_in_beta.
| Name | Scope | Meaning |
|---|---|---|
POST /v1/absences | absences:write | Create an absence (planned) Records an absence or files a request — with the app’s rules (approval, blackout periods, licence). |
POST /v1/absences/{id}/approve | absences:write | Approve a request (planned) Approves a pending request. |
POST /v1/absences/{id}/reject | absences:write | Reject a request (planned) Rejects a pending request. |
POST /v1/absences/{id}/cancel | absences:write | Cancel an absence (planned) Cancels an absence. |
POST /v1/time-entries | time:write | Record working time (planned) Records clock-in, clock-out or a break. |
POST /v1/employees | employees:write | Create an employee (planned) Creates an employee record. |
PATCH /v1/employees/{id} | employees:write | Update master data (planned) Changes name, personnel number, unit, entry or exit. |
The full description to import into Postman, Insomnia or a code generator.
As a beta, the API is a voluntary extra and not part of the agreed scope of services; we may change or discontinue it (Terms § 4 (8)). As long as /v1 exists, the version rule above applies to it.