Employees
The /api/v1/employees endpoint group covers the full employee synchronization cycle with external HR and payroll systems: creating employee records, updating personal data, maintaining historical tables for employments, positions, and compensations, and archiving terminated employees.
Core employee operations
Section titled “Core employee operations”Create an employee
Section titled “Create an employee”POST /api/v1/employeesCreates a new employee record. Email is not required at creation time.
Required fields:
| Field | Type | Description |
|---|---|---|
first_name | string | First name |
last_name | string | Last name |
date_effective_from | string (date) | Hire date |
Optional fields:
| Field | Description |
|---|---|
middle_name | Middle name |
division_id | Division ID |
department_id | Department ID |
position_id | Position ID |
position_level_id | Grade / level ID |
location_id | Location ID |
legal_entity_id | Legal entity ID |
reporting_to_id | Manager ID |
employment_contract_id | Employment contract type ID |
employment_type_id | Employment type ID |
employment_work_pattern_id | Work pattern ID |
base_salary_gross | Gross salary |
base_salary_net | Net salary |
currency | Currency code (ISO 4217) |
per_type | Period: hourly, weekly, monthly, yearly |
Request example:
{ "first_name": "John", "last_name": "Smith", "date_effective_from": "2024-01-15", "department_id": 42, "position_id": 7, "base_salary_gross": "150000", "currency": "USD", "per_type": "monthly"}Get employee details
Section titled “Get employee details”GET /api/v1/employees/{employee_id}Returns the full employee profile including current position, employment, compensation, and custom fields (custom_fields).
Search employees
Section titled “Search employees”POST /api/v1/employees/searchReturns a page of employees. Filter by text, employee_ids, manager_ids, department_ids, division_ids, location_ids, job_profile_ids, job_role_ids, employment_type_ids, employment_contract_ids, employee_lifecycle_statuses and is_manager. page_size is capped at 500.
Related blocks are not loaded by default - each one must be listed in employee_fields, otherwise its field comes back empty:
| Value | Fills | Contents |
|---|---|---|
position_job_title, position_division, position_department, position_location, position_level, position_reporting_to, position_comment, position_change_reason | employee_position | Current position. Any one of these loads the whole block |
employment_employment_type, employment_employment_contract, employment_legal_entity, employment_work_pattern, employment_termination_reason | employee_employment | Current employment |
compensation, compensation_change_reason | employee_compensation | Current salary: base_salary_gross, base_salary_net, currency, per_type |
lifecycle_status | lifecycle_status | Lifecycle status |
custom_fields | custom_fields | Custom fields with values and permissions |
time_off | time_off | Leave the employee is on today - see below |
custom_tables | custom_tables | Custom table rows - see below |
additional_compensations | additional_compensations | Payments of the current month - see below |
Request example:
{ "page_number": 1, "page_size": 100, "employee_fields": [ "position_job_title", "position_department", "compensation", "custom_fields", "additional_compensations" ]}time_off
Section titled “time_off”Filled only when the employee is on leave on the day of the request - the date is not a parameter. For everybody else it is null.
{ "date_from": "2024-03-04", "date_to": "2024-03-15", "category": { "id": 3, "title": "Annual leave" }, "balance_requested": "10.00"}To find out who is off over a period, use POST /api/v1/time-off/availability/search instead.
custom_tables
Section titled “custom_tables”One entry per table. A historical table returns its current row only; for the full history read the rows through the table endpoints.
[{ "table_id": 42, "rows": [{ "id": 5, "date_effective_from": "2024-01-01", "is_current": true, "cells": [{ "field": { "slug": "bonus_amount" }, "value": { "value_float": 5000 } }] }]}]additional_compensations
Section titled “additional_compensations”Only the payments whose date_effective_from falls in the current month (UTC). For the whole history use GET /api/v1/employees/{employee_id}/additional-compensations.
[{ "id": 1, "date_effective_from": "2024-03-01", "compensation_type": { "id": 7, "title": "Bonus" }, "amount": "500.00", "amount_gross": "500.00", "amount_net": null, "currency": "USD", "description": "Q1 bonus", "comment": null}]Employees the caller has no employee_additional_compensation view permission for come back with an empty list.
Update personal data
Section titled “Update personal data”PUT /api/v1/employees/{employee_id}Updates personal data and custom fields in a single request.
Required fields: first_name, last_name
Optional fields:
| Field | Description |
|---|---|
email | Work email |
email_personal | Personal email |
phone | Work phone |
phone_personal | Personal phone |
date_birth | Date of birth |
gender | Gender |
personnel_number | Personnel number |
address_1, address_2, city, state, zip | Address fields |
country_id | Country ID |
custom_fields | dict {slug: value} - employee custom field values |
Request example:
{ "first_name": "John", "last_name": "Smith", "personnel_number": "EMP-001", "custom_fields": { "tax_id": "123456789" }}Archive an employee
Section titled “Archive an employee”DELETE /api/v1/employees/{employee_id}Soft-deletes the employee (termination). All data is preserved.
Position history
Section titled “Position history”A position record captures department, job title, manager, and location at a specific effective date.
Add a position record
Section titled “Add a position record”POST /api/v1/employees/{employee_id}/positions| Field | Type | Description |
|---|---|---|
date_effective_from | string (date) | Effective start date |
division_id | integer | Division ID |
department_id | integer | Department ID |
position_id | integer | Position ID |
position_level_id | integer | Grade/level ID |
reporting_to_id | integer | Manager ID |
legal_entity_id | integer | Legal entity ID |
location_id | integer | Location ID |
comment | string | Comment |
Update / delete a position record
Section titled “Update / delete a position record”PUT /api/v1/employees/{employee_id}/positions/{id}DELETE /api/v1/employees/{employee_id}/positions/{id}Search position history
Section titled “Search position history”POST /api/v1/employees/{employee_id}/positions/searchReturns a paginated list of position records with full nested objects: department, division, position, manager, legal_entity, location.
Employment history
Section titled “Employment history”An employment record captures contract type, employment type, work pattern, and the employment period.
Get employment history
Section titled “Get employment history”GET /api/v1/employees/{employee_id}/employmentsReturns the full list of employment records (current and past).
Add an employment record
Section titled “Add an employment record”POST /api/v1/employees/{employee_id}/employments| Field | Type | Description |
|---|---|---|
date_effective_from | string (date) | Start date (hire date) |
date_effective_to | string (date) | End date / termination date |
employment_type_id | integer | Employment type ID |
employment_contract_id | integer | Contract type ID |
work_pattern_id | integer | Work pattern ID |
date_probation_ends | string (date) | Probation end date |
comment | string | Comment |
Update / delete an employment record
Section titled “Update / delete an employment record”PUT /api/v1/employees/{employee_id}/employments/{id}DELETE /api/v1/employees/{employee_id}/employments/{id}Compensation history
Section titled “Compensation history”A compensation record is a version of the employee’s compensation package effective from date_effective_from until date_effective_to (the day before the next version starts, null for the current one). The package holds the regular amounts: base salary, allowances, deductions, and employer contributions. One-time payments are additional compensations.
Add a compensation record
Section titled “Add a compensation record”POST /api/v1/employees/{employee_id}/compensations| Field | Type | Description |
|---|---|---|
date_effective_from | string (date) | Effective start date |
base_salary_gross | number | Gross salary |
base_salary_net | number | Net salary |
currency | string | Currency (ISO 4217) |
per_type | string | hourly, weekly, monthly, yearly |
change_reason_id | integer | Change reason ID |
comment | string | Comment |
This method writes the base salary only. Allowances and other package lines are managed in Skailer.
Search compensation history
Section titled “Search compensation history”POST /api/v1/employees/{employee_id}/compensations/searchReturns a paginated list of package versions. Each version carries lines - every regular amount of the package:
{ "id": 812, "date_effective_from": "2026-01-15", "date_effective_to": null, "base_salary_gross": "3000.00", "currency": "USD", "per_type": "monthly", "lines": [ { "id": 1540, "compensation_type": { "id": 1, "title": "Basic salary", "is_archived": false }, "amount_gross": "3000.00", "amount_net": null, "currency": "USD", "per_type": "monthly", "description": null, "kind": "earning", "is_included_in_gross": true, "is_payable_to_employee": true, "is_included_in_total_cost": true, "rate_type": "fixed_amount", "percent": null }, { "id": 1541, "compensation_type": { "id": 2, "title": "Housing allowance", "is_archived": false }, "amount_gross": "500.00", "amount_net": null, "currency": "USD", "per_type": "monthly", "description": null, "kind": "earning", "is_included_in_gross": true, "is_payable_to_employee": true, "is_included_in_total_cost": true, "rate_type": "fixed_amount", "percent": null } ]}| Line field | Description |
|---|---|
compensation_type | Compensation component. The same id comes in compensation_type.id of additional compensations |
amount_gross, amount_net | Amounts as strings |
currency, per_type | Currency and period of the line |
kind | earning, deduction, or employer_contribution |
is_included_in_gross | The line counts towards gross |
is_payable_to_employee | The line is paid to the employee |
is_included_in_total_cost | The line counts towards the employer’s total cost |
rate_type, percent | fixed_amount, or a percent line with its rate; for a percent line the amounts are already calculated |
lines is null when the API user has no employee_compensation_lines field permission. Off-payroll payments are not returned.
Update / delete a compensation record
Section titled “Update / delete a compensation record”PUT /api/v1/employees/{employee_id}/compensations/{id}DELETE /api/v1/employees/{employee_id}/compensations/{id}Additional compensations
Section titled “Additional compensations”Additional compensations are one-time payments: bonuses, premiums, expense reimbursements. Each payment has a single date, date_effective_from, and no end date. Regular allowances are lines of the compensation package.
Get all additional compensations
Section titled “Get all additional compensations”GET /api/v1/employees/{employee_id}/additional-compensationsCreate an additional compensation
Section titled “Create an additional compensation”POST /api/v1/employees/{employee_id}/additional-compensations| Field | Type | Description |
|---|---|---|
compensation_type_id | integer | Compensation component ID (required) |
date_effective_from | string (date) | Payment date (required) |
amount_gross | number | Gross amount |
amount_net | number | Net amount |
amount | number | Deprecated: written to amount_gross when amount_gross is not passed |
currency | string | Currency code |
description | string | Description |
comment | string | Comment |
custom_fields | object | Custom column values by column slug |
The former fields type, frequency_type, and date_effective_to are ignored: every record is saved as a one-time payment.
Update / delete an additional compensation
Section titled “Update / delete an additional compensation”PUT /api/v1/employees/{employee_id}/additional-compensations/{id}DELETE /api/v1/employees/{employee_id}/additional-compensations/{id}Custom table rows
Section titled “Custom table rows”Write rows to custom tables linked to an employee (e.g. “Accrued Bonuses”, “Payment Details”). Get the list of available tables and their field slugs via GET /api/v1/custom-fields/tables.
Add a row
Section titled “Add a row”POST /api/v1/employees/{employee_id}/field-tables/{table_id}/rows| Field | Type | Description |
|---|---|---|
date_effective_from | string (date) | Effective date of this row |
cells | object | {slug: value} - cell values |
Supported value types in cells:
text/textarea/email/phone- stringnumber/currency/percentage- numberdate- stringYYYY-MM-DDdatetime- ISO 8601 stringselect- option IDswitch- booleanemployee_reference- integer (employee ID)
Request example:
{ "date_effective_from": "2024-01-01", "cells": { "bonus_amount": 5000, "bonus_currency": 1, "bonus_comment": "Q1 performance bonus" }}Update / delete a row
Section titled “Update / delete a row”PUT /api/v1/employees/{employee_id}/field-tables/{table_id}/rows/{id}DELETE /api/v1/employees/{employee_id}/field-tables/{table_id}/rows/{id}Organization structure
Section titled “Organization structure”Reference lists for the department_id, division_id and team fields of employees and jobs.
Departments
Section titled “Departments”GET /api/v1/departments/allReturns every department, archived included: id, title, emoji, image_url, parent_id, manager (the full employee or null), employees_count and is_archived.
Requires any of: settings_roles_permissions, settings_departments, manage_jobs, manage_leave_policies, manage_approval_policy, see_departments_structure, employee_position_department.
Divisions
Section titled “Divisions”GET /api/v1/divisions/allReturns every division, archived included: id, title and is_archived.
Requires any of: settings_roles_permissions, settings_divisions, manage_jobs, manage_leave_policies, manage_approval_policy, employee_position_division.
POST /api/v1/teams/search| Field | Type | Description |
|---|---|---|
text | string | Search by team title |
employee_ids | array[integer] | Teams that include these employees |
page_number | integer | Page number, starts at 1 |
Returns a paginated list sorted by title. Each team carries id, title, description, emoji, background_url, links (title, url) and members (id, employee, role, sort, description).
Requires any of: manage_teams >= view, settings_roles_permissions, manage_leave_policies, manage_approval_policy.
Typical integration scenario
Section titled “Typical integration scenario”Full new-hire sync from an HR/payroll system:
- Create the employee -
POST /api/v1/employeeswith basic data and hire date. - Update personal data -
PUT /api/v1/employees/{id}with email, phone, and custom fields. - Record employment -
POST /api/v1/employees/{id}/employmentswith contract type. - Record compensation -
POST /api/v1/employees/{id}/compensationswith salary. - Write custom table rows -
POST /api/v1/employees/{id}/field-tables/{table_id}/rowsfor bonuses, payment details, etc.
On termination:
- Close the employment record -
PUT /api/v1/employees/{id}/employments/{id}(adddate_effective_to). - Archive the employee -
DELETE /api/v1/employees/{id}.