Each item — Absence request as serialized by the V1 `TempusTransactionResource`. Backed by
a single `TempusTransaction` ledger row, this object represents an employee
absence (legal holiday, home office, illness, special leave, overtime balance)
together with its approval status and requested period.
This object documents the exact keys returned by the resource, not the raw
database columns. Several values are remapped from internal storage to the API
contract: the internal `approved`, `rejected`, and `cancelled` statuses are
exposed as `accepted`, `rejected`, and `canceled`; the internal `absence` type
is exposed as `legal`. Other status and type values pass through unchanged.
`employee_id` is the canonical id of the employee the request belongs to.
Several identifier fields are intentionally redundant for client convenience:
`requester_id` and `creator_id` both return that same employee id, and
`absence_request_id` mirrors `id`. `ext_id` is a different value - the
employee's extension id (see below). `holiday_id` is reserved for future use
and is always null.
id*string · uuid
Unique absence request (transaction) identifier.
read-only
example: 550e8400-e29b-41d4-a716-446655440000
mxvp_user_id*string | null · uuid
Identifier of the Pbx (tenant) that owns this absence request. Mirrors the
transaction's `pbx_id`. Null for records not bound to a specific tenant.
example: 550e8400-e29b-41d4-a716-446655440001
employee_id*string · uuid
Canonical identifier of the Tempus employee this request belongs to. This
is the value the `filter[employee_id]` query parameter matches against.
example: 550e8400-e29b-41d4-a716-446655440002
requester_id*string · uuid
Identifier of the Tempus employee the absence belongs to. Returns the same
value as `employee_id` and `creator_id`.
example: 550e8400-e29b-41d4-a716-446655440002
creator_id*string · uuid
Identifier of the Tempus employee who owns the absence. Returns the same
value as `requester_id` (the owning employee, not the acting principal).
example: 550e8400-e29b-41d4-a716-446655440002
ext_id*string | null
External system identifier of the employee, resolved from the linked
employee record. Null when the employee has no external mapping.
example: EXT-10293
company_id*string | null · uuid
Identifier of the Tempus company the absence is attributed to. Null when
the request is not scoped to a specific company.
example: 550e8400-e29b-41d4-a716-446655440003
absence_request_id*string · uuid
Alias of `id`, provided for clients that reference absence requests by this
field name. Always equal to `id`.
read-only
example: 550e8400-e29b-41d4-a716-446655440000
holiday_id*string | null · uuid
Reserved for a future link to a public-holiday record. Always null in the
current API version.
status*string | null
Approval status of the absence request, remapped for the API: internal
`approved` is returned as `accepted` and internal `cancelled` as `canceled`.
`pending` awaits validation, `pending_removal` and `removed` track removal
of a previously approved absence. Null only for records with no status set.
enum: pending accepted rejected canceled pending_removal removed
example: pending
type*string
Category of the absence. The internal `absence` type is remapped to `legal`
(legal holiday). `home_office` is a remote-work day, `illness` is sick
leave, `special` is special leave, and `overtime_balance` is an
overtime-balance adjustment.
enum: legal home_office illness special overtime_balance
example: legal
sub_type*string | null
Optional sub-classification of the absence (for example `removal` for a
removal request, or a computed/rollover marker for ledger adjustments).
Null when the request carries no sub-type.
example: removal
start*string | null · date-time
Start of the absence period as an ISO 8601 timestamp. Null when the request
has no start date.
example: 2024-03-01T00:00:00+00:00
end*string | null · date-time
End of the absence period as an ISO 8601 timestamp. Null when the request
has no end date.
example: 2024-03-05T00:00:00+00:00
requested_time*object | null
Per-day breakdown of the requested time, stored as a map of date strings to
durations in seconds. Used to compute the effective amount while the request
is pending. Null when no per-day breakdown was supplied.
Seconds are the employee's own scheduled day, not a nominal 8h: a part-timer on
a 4h day books `14400` for a full day off, and a half of that day is `7200`.
Only working days appear: a weekend, public holiday or company special holiday
inside the range is omitted.
Rows written before that was true carry a `0` entry for each such day, and rows
created over this API before it carried a flat `28800` regardless of shift. So
do **not** count these keys to get the length of a request and do not assume the
seconds match the shift on historical rows: read `working_days` and
`workshift_seconds_per_day`, which normalize both shapes.
example: {"2024-03-01":28800,"2024-03-04":28800,"2024-03-05":14400}
working_days*number
How long the request is, in working days the employee actually consumes:
weekends, public holidays, company special holidays and days already taken by
another absence are excluded, and each remaining day is measured against that
employee's own scheduled day. A part-timer's 4h day therefore counts as `1`,
while 4h out of an 8h day counts as `0.5`.
This is the same figure the approval debits from the employee's balance, so it
never disagrees with the amount charged. Prefer it over deriving a length from
`start`/`end`: that difference is exclusive (Aug 3 → Aug 7 is 5 days, not 4) and
counts days nobody works.
Whole counts serialize without a fractional part (`5`, not `5.0`); half days
appear as `.5`.
example: 4.5
total_seconds*integer · int32
Sum of the booked seconds in `requested_time`, i.e. the same period expressed as
time rather than days. `0` when the request has no per-day breakdown.
example: 129600
workshift_seconds_per_day*integer · int32
What one full working day is worth for this employee, in seconds. It is the yardstick
every booked day is measured against. `28800` on a standard 8h shift, `14400` for
somebody contracted to 4h days. Use it to render a booking as a fraction of a day
without assuming 8h.
example: 28800
is_half_day*boolean
True when either end of the request is a half day. The single flag a list badge
needs; `starts_half_day` / `ends_half_day` say which end.
example: 1
starts_half_day*boolean
True when the first day is a half day: the employee works that morning and
leaves. `start_time` then carries the hour they leave.
example: 1
ends_half_day*boolean
True when the last day is a half day: the absence covers that morning and the
employee is back after it. `end_time` then carries the hour they return.
On a single-day half day both this and `starts_half_day` are true, and both hours
are filled in.
example:
start_time*string | null
Local wall-clock hour (`HH:MM`) the absence begins on a half-day start. Null when
the request does not start on a half day. Taken from the request's own stored
time when it has one, otherwise the tenant's configured AM/PM split
(`TEMPUS_HALF_DAY_SPLIT`, default `12:00`).
example: 14:00
end_time*string | null
Local wall-clock hour (`HH:MM`) the absence ends on a half-day end. Null when the
request does not end on a half day. Same source as `start_time`.
example: 18:00
working_day_details*array<object>
Per-day breakdown of the request, working days only, in date order. The same
days as `requested_time` with the half-day verdict and hours resolved per day.
Hours only ever land on the two ends: a day in the middle of a range has no clock
time of its own, and a single-day request is both ends at once.
date*string · date
The day, as `YYYY-MM-DD`.
example: 2026-08-03
seconds*integer · int32
Seconds booked off on this day, scaled to the employee's own scheduled day.
example: 14400
is_half_day*boolean
True when this day's booked seconds fall short of a full day for this
employee (see `workshift_seconds_per_day`), allowing 15 minutes of
tolerance for lunch and rounding.
example: 1
start_time*string | null
Hour (`HH:MM`) the absence starts on this day. Non-null only on a half-day
first day (or a single-day half day).
example: 12:00
end_time*string | null
Hour (`HH:MM`) the absence ends on this day. Non-null only on a half-day
last day (or a single-day half day).
comment*string | null
Free-form note attached to the absence request (mirrors the transaction's
`note`). Null when no comment was provided.
example: Family event, returning Wednesday afternoon.
accepted_by*array<object>
Every validator that must sign off on this request, with their individual
decision. One entry per approval record; empty when the request has no
assigned validators yet. A request is fully accepted only once every entry
reports `accepted`.
employee_id*string | null · uuid
Identifier of the Tempus employee acting as validator for this
approval.
example: 550e8400-e29b-41d4-a716-446655440004
status*string
This validator's decision. `pending` awaits their action; `accepted`
and `rejected` record the outcome.
enum: pending accepted rejected
example: pending
next_availabilityobject
When an employee is next at work **if the request carrying this object goes through**,
next to what the general next-availability answer says today. The validator's view of a
request: no second call, and no cache between the queue and the date.
It is deliberately not the same question as `GET /user/{employee_id}/next-availability`:
- **Anchored at the request, not at today**, so it reports the day *this* booking frees
rather than the next free day counting from now.
- **Counts what has been decided plus this one request.** The base is what has been
signed off (accepted, plus an accepted absence somebody has asked to cancel — still
time off until that cancellation is approved). Other queued requests are left out:
they may be refused, and a date that moves because of a request this validator has not
seen is not one they can act on. (`current` does count every pending row — that
difference is intentional.)
- **A removal reads as a reduction**, so its answer moves *earlier*, often into the past
(`in_past`), which is the signal that the employee is already back.
Absence, illness, special leave and legal holiday only. Home office never carries it: a
home office day is governed by a weekly limit, not time off that moves an availability
date. Neither does a request that can no longer move a date — `rejected`, `canceled` and
`removed`.
**Where it appears:** the absence lists (`/absences`, `/user/{employee_id}/absences`), the
absence-request reads and writes (`/absence-requests`, `/user/{employee_id}/absence-requests`
and its `POST`/`PUT`), `POST /user/{employee_id}/absence-removal-requests`, and both
validator queues (`/validator/pending-requests` — on each `absence_requests[]` /
`absence_removals[]` entry — and v2 `pending-requests/absences`). It is **not** on the
cancel responses (`POST .../absence-requests/{id}/cancel`), which report the outcome of an
employee's own action rather than something a validator is weighing up.
On the resource-backed payloads the key is **omitted** when there is nothing to say; on
the v1 validator queue, whose entries are built by hand, it is always present and `null`
in that case. Both mean the same thing.
if_approved*object
Availability as it would stand with this request applied.
absent_from*string | null · date
First day, today or later, that this request itself takes off. Null when it takes
nothing off in the future: a removal request, or days that have all been and gone.
example: 2026-08-13
next_available_date*string | null · date
The day the employee is back at work under this scenario. Null only when no
working day was found within the search horizon — an employee with no work shift,
or one whose contract has ended.
example: 2026-08-17
next_available_at*string | null
Exact moment they are back (`YYYY-MM-DD HH:MM:SS`) when a half day pins one down;
null when only the date is meaningful.
available_now*boolean
Whether the employee is at work right now under this scenario. True together with
a future `absent_from` is the ordinary case for a request that starts later.
example: 1
in_past*boolean
True when `next_available_date` is already behind us, i.e. approving this would
not keep anybody away from now on. Render it as "already available" rather than as
a return date.
example:
extends_current_absence*boolean
True when this request starts on the very day the employee would otherwise have
come back, so it lengthens the absence already in place rather than opening a
separate one. False for a request with working days in between — show
`absent_from` as well as the return date in that case, or the return date reads as
a contradiction of `available_now`.
example:
message*string | null
Ready-to-display line, already covering the three cases: `Available on
2026-08-17`, `Off from 2026-08-13, available on 2026-08-17`, or `Already available
(was back on 2026-08-03)`. Show it as returned.
example: Off from 2026-08-13, available on 2026-08-17
current*object
Today's general answer, unchanged — the same figure
`GET /user/{employee_id}/next-availability` returns, so the two screens never disagree.
next_available_date*string | null · date
Next day the employee is available, counting from now. Null when they are
available right now.
example: 2026-08-12
message*string | null
Ready-to-display line, or null while the employee is available.
example: Back on 2026-08-12
created*string | null · date-time
Timestamp when the absence request was created, as an ISO 8601 string. Null
when not set.
read-only
example: 2024-02-15T10:00:00+00:00
modified*string | null · date-time
Timestamp when the absence request was last updated, as an ISO 8601 string.
Null when not set.
read-only
example: 2024-02-16T09:30:00+00:00