Skip to content
Log in Request a demo

Time Off

The /api/v1/time-off endpoint group lets you read the organization’s leave policy configuration, the accrual/usage history for each employee, and their current balance as of any date.

GET /api/v1/time-off/categories

Returns all time-off policies/categories configured for the organization.

Response fields (per category):

FieldTypeDescription
idintegerCategory ID
titlestringName
descriptionstringDescription
category_typestringType: manual, accrues_time, flexible
paid_typestringPaid/unpaid classification
period_track_typestringTracking unit: hours or days
emojistringEmoji icon
colorstringColor
policies_countintegerNumber of attached policies
is_archivedbooleanWhether the category is archived
is_parental_leavebooleanWhether this is a parental leave category

Response example:

[
{
"id": 3,
"title": "Annual Paid Leave",
"category_type": "accrues_time",
"paid_type": "paid",
"period_track_type": "days",
"policies_count": 2,
"is_archived": false,
"is_parental_leave": false
}
]

POST /api/v1/time-off/logs/search

Returns a paginated list of leave records - accruals, usages, expirations, and adjustments.

Request parameters:

FieldTypeDescription
employee_idintegerEmployee ID (required)
page_numberintegerPage number
category_idsarray[integer]Filter by category IDs
action_typesarray[string]Types: accrual, used, expired, adjustment
request_statusesarray[string]Filter by approval request statuses
date_fromstring (date)Keep only records overlapping the period
date_tostring (date)Keep only records overlapping the period

date_from and date_to are independent - you may pass either one alone. A record is kept when its own period overlaps the requested one, so a leave that starts before date_from and ends inside the period is still returned. Passing date_from later than date_to returns 422.

Response fields (per record):

Each record contains two objects: time_off_log and, when a request exists, approval_request_details.

time_off_log:

FieldTypeDescription
idintegerRecord ID
date_adjustmentstring (date)Adjustment date
employee_idintegerEmployee ID
categoryobjectTime-off category
balancestringBalance change
actionstringAction type
balance_typestringBalance type
date_fromstringLeave period start
date_tostringLeave period end
date_expirestringAccrual expiration date
commentstringComment
filesarrayAttached files

approval_request_details (when a request exists):

FieldTypeDescription
idintegerRequest ID
typestringRequest type
statusstringRequest status
confirmationsarrayList of approvals
datetime_created_atstringCreation timestamp

Request example:

{
"employee_id": 123,
"page_number": 1,
"action_types": ["used", "accrual"],
"category_ids": [3, 5],
"date_from": "2026-01-01",
"date_to": "2026-12-31"
}

POST /api/v1/time-off/employee/balance

Returns the balance for all time-off categories the employee is enrolled in, as of the specified date.

Request parameters:

FieldTypeDescription
employee_idintegerEmployee ID (required)
date_balancestring (date)Date for which to retrieve the balance (required)

Response fields (per category):

FieldTypeDescription
idintegerCategory ID
titlestringCategory name
category_typestringCategory type
period_track_typestringTracking unit
balance.available_balancestringAvailable balance
balance.total_booked_amountstringBooked amount (approved requests)
is_archivedbooleanWhether the category is archived

Request example:

{
"employee_id": 123,
"date_balance": "2024-06-30"
}

Response example:

[
{
"id": 3,
"title": "Annual Paid Leave",
"category_type": "accrues_time",
"period_track_type": "days",
"balance": {
"available_balance": "12.5",
"total_booked_amount": "3.0"
},
"is_archived": false
}
]

POST /api/v1/time-off/availability/search

Returns the individual dates on which employees are on time off within the requested period. Multi-day leaves are expanded into separate days and clipped to the period, so you do not have to intersect intervals yourself.

Only occupied dates are returned. Free days, weekends and public holidays are not included, and part-time schedules are not taken into account - a day that is absent from the response simply has no leave booked on it.

Request parameters:

FieldTypeDescription
date_fromstring (date)Start of the period (required)
date_tostring (date)End of the period (required)
employee_idsarray[integer]Filter by employee IDs
category_idsarray[integer]Filter by time-off category IDs
department_idsarray[integer]Filter by departments
team_idsarray[integer]Filter by teams
division_idsarray[integer]Filter by divisions
location_idsarray[integer]Filter by locations

The period must not exceed 366 days, and date_from must not be later than date_to; otherwise the request returns 422.

Response fields (per employee):

FieldTypeDescription
employee_idintegerEmployee ID
daysarrayDays the employee is on time off, ascending

days[]:

FieldTypeDescription
datestring (date)The date the employee is on time off
time_off_category_idintegerCategory of that leave - join it with GET /api/v1/time-off/categories
is_pendingbooleantrue while the request is still awaiting approval

Request example:

{
"date_from": "2026-05-01",
"date_to": "2026-05-07",
"department_ids": [5]
}

Response example:

[
{
"employee_id": 123,
"days": [
{ "date": "2026-05-04", "time_off_category_id": 3, "is_pending": false },
{ "date": "2026-05-05", "time_off_category_id": 3, "is_pending": false }
]
}
]

Employees with no leave in the period come back with an empty days array, which is how you tell “available all period” apart from “not visible to this token”.

Note: is_pending: true means the leave is booked but not approved yet, so it may still be rejected. Treat such days as occupied only if your scenario should respect unapproved requests.

Requires permission access_to_leave_timeline=edit. Employees the token has no access to are omitted from the response rather than causing an error, so an empty list may mean the service account lacks the permission.

Passing category_ids also narrows the set of employees: those without leave of the requested categories drop out of the response entirely.


Holiday calendars hold public holidays, moved working days and compensation days off. Every employee gets a calendar from the location, department and division of the current position. All three methods require permission manage_holidays=edit.

GET /api/v1/calendar-holidays

Returns every calendar of the company: id, title and country (id, title, or null).

POST /api/v1/calendar-holidays/dates/search
FieldTypeDescription
date_fromstring (date)Start of the period, inclusive (required)
date_tostring (date)End of the period, inclusive (required)
calendar_holiday_idsarray[integer]Calendars to read; empty or omitted returns all calendars

The period is limited to 366 days, and date_from must not be later than date_to - otherwise 422.

[
{
"id": 3051,
"calendar_holiday_id": 4,
"date": "2026-01-01",
"title": "New Year's Day",
"type": "non_working"
}
]
typeMeaning
non_workingPublic holiday, a day off
workingWorking day moved onto a weekend
compensatedDay off moved from a public holiday that fell on a weekend
POST /api/v1/calendar-holidays/employees/search
FieldTypeDescription
employee_idsarray[integer]Employees to resolve; omitted returns all employees
page_numberintegerPage number, starts at 1
page_sizeintegerPage size, 1-500, default 20

Each item returns employee_id and calendar_holiday_id. calendar_holiday_id is null when no calendar applies to the employee.

The calendar is resolved from the current position and is not historical: after a relocation, past dates are resolved by the new calendar.


Goal: periodically sync leave data with a payroll system.

  1. Get categories (once, cache the result):

    GET /api/v1/time-off/categories
  2. Fetch history for the period for each employee:

    POST /api/v1/time-off/logs/search

    Filter by action_types: ["used", "accrual"] and the relevant category_ids.

  3. Get the current balance as of the end of the pay period:

    POST /api/v1/time-off/employee/balance

    Pass date_balance as the cutoff date.

Tip: use date_adjustment from time_off_log for incremental sync - only fetch records with an adjustment date later than your last successful sync.


Goal: build a calendar or schedule that knows when a person is on leave.

  1. Get categories (once, cache the result) to resolve time_off_category_id into a title:

    GET /api/v1/time-off/categories
  2. Fetch the occupied days for the whole team in one request:

    POST /api/v1/time-off/availability/search

    Pass the period and, optionally, department_ids or employee_ids.

  3. Look up a specific date in the returned days array. A date that is not there has no leave booked on it.

  4. Skip public holidays if the calendar needs them: resolve each employee’s calendar with POST /api/v1/calendar-holidays/employees/search and read its dates with POST /api/v1/calendar-holidays/dates/search. See Public holidays.