Object reference
Every object carries an object field naming its type, so a payload is
self-describing even after it has been passed through your own code.
Money is a decimal string, never a JSON number — 1234567.89 is not
exactly representable in a float64, and a client that parses pay as one
eventually produces a payslip that is a cent wrong. Date-only fields are
calendar dates (2026-03-01); timestamps are RFC 3339 in UTC.
Announcement
A notice to the workspace. Who it reaches is decided by target_type and an audience the API does not expose; the attachment is not exposed either.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | announcement | No | Always announcement. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
category_id | string | Yes | The category it belongs to. |
title | string | No | Headline. |
body | string | No | The announcement text. |
priority | string | No | How prominently it is shown. |
target_type | string | No | Whether it goes to everyone or to a selected audience. |
is_pinned | boolean | No | Whether it stays at the top. |
publish_at | timestamp | Yes | When it becomes visible. |
expires_at | timestamp | Yes | When it stops being shown. |
send_email | boolean | No | Whether it was also emailed. |
status | string | No | Draft, published, or archived. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AnnouncementCategory
A grouping for announcements.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | announcement_category | No | Always announcement_category. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
color | string | No | Hex colour used to render it. |
created_at | timestamp | No | When the record was created. |
Application
One candidate against one opening, and where they are in the process.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | application | No | Always application. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
candidate_id | string | No | The candidate. |
job_opening_id | string | No | The opening applied for. |
stage | string | No | Where they are in the pipeline. |
source | string | No | How they arrived. |
source_detail | string | Yes | More about the source. |
applied_at | timestamp | No | When they applied. |
screened_at | timestamp | Yes | When they were screened. |
rejected_at | timestamp | Yes | When they were rejected. |
rejection_reason | string | Yes | Why they were rejected. |
withdrawn_at | timestamp | Yes | When they withdrew. |
hired_at | timestamp | Yes | When they were hired. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Asset
One piece of company property. current_assignment_id points at who holds it now, and is null when it is back in stock.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | asset | No | Always asset. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
category_id | string | No | The kind of asset. |
asset_tag | string | No | The workspace’s own tag, unique within it. |
name | string | No | What it is. |
serial_number | string | Yes | Manufacturer's serial. |
purchase_date | date | Yes | When it was bought. |
purchase_cost | string | Yes | What it cost. |
warranty_expiry | date | Yes | When the warranty runs out. |
vendor | string | Yes | Who supplied it. |
condition | string | No | Physical condition. |
status | string | No | Whether it is issued, in stock, or retired. |
current_assignment_id | string | Yes | The assignment holding it now. Null when unassigned. |
notes | string | Yes | Free-text note. |
deleted | boolean | No | True for a retired asset. Hidden by default; pass include_deleted to see them, which a client mirroring assets needs in order to observe a removal at all. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AssetAssignment
One issue-and-return cycle. A returned assignment is kept, so the history of who held what survives the return.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | asset_assignment | No | Always asset_assignment. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
asset_id | string | No | The asset. |
employee_id | string | No | The employee this record belongs to. |
issued_at | timestamp | No | When it was handed over. |
issued_condition | string | Yes | Condition at issue. |
issued_notes | string | Yes | Note taken at issue. |
expected_return_date | date | Yes | When it is due back. |
returned_at | timestamp | Yes | When it came back. Null while still held. |
returned_condition | string | Yes | Condition on return. |
returned_notes | string | Yes | Note taken on return. |
status | string | No | Whether the assignment is open or closed. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AssetCategory
A kind of company asset — laptops, phones, vehicles.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | asset_category | No | Always asset_category. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
description | string | Yes | What belongs in it. |
is_active | boolean | No | Whether it is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AttendancePunch
A single clock-in or clock-out event. Punches are an append-only log: every punch is kept, including ones that changed no attendance record.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | attendance_punch | No | Always attendance_punch. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
punch_time | timestamp | No | When the punch happened. |
punch_type | in · out | No | Direction of the punch. |
source | string | No | Where the punch came from. API-recorded punches are api. |
device_id | string | Yes | Identifier of the device that captured the punch. |
ip_address | string | Yes | Address the punch was submitted from. |
created_at | timestamp | No | When the record was created. |
AttendanceRecord
One employee's attendance for one calendar day. There is at most one per (employee, date), so writing the same day twice replaces it rather than adding a second record.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | attendance_record | No | Always attendance_record. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
date | date | No | The calendar day, in the workspace timezone. An overnight shift is attributed to the day it started. |
status | string (enum) | No | How the day is counted for pay. |
clock_in | timestamp | Yes | First punch of the day. |
clock_out | timestamp | Yes | Last punch inside the valid checkout window. |
late_minutes | integer | No | Minutes past the shift start, after the grace period. |
early_leaving_minutes | integer | No | Minutes the employee left before the shift ended. |
overtime_minutes | integer | No | Overtime credited for the day. Zero while an overtime request is still pending, in a workspace that requires approval. |
working_hours | string | No | Hours worked, net of the shift's unpaid break. |
shift_id | string | Yes | Shift in effect on this date. |
source | string (enum) | No | What wrote the row. manual covers deliberate marks including this API's, auto the auto-present job, regularization an approved correction, and biometric / geo / api a punch of that origin. |
is_manual_override | boolean | No | When true the status is pinned and the late-threshold recompute will not change it, however the punches land. |
remarks | string | Yes | Free-text note. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AttendanceRegularization
A request to correct one day's attendance. Approving one overwrites the attendance record for that date and marks it as coming from a regularisation, which protects it from later automatic recomputation.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | attendance_regularization | No | Always attendance_regularization. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
date | date | No | The day being corrected. |
requested_status | string (enum) | No | Status the employee is asking for. |
clock_in | timestamp | Yes | Corrected clock-in. |
clock_out | timestamp | Yes | Corrected clock-out. |
previous_status | string | Yes | What the day looked like at the moment of the decision. Null while the request is pending — the record it would replace can still change. |
previous_clock_in | timestamp | Yes | Clock-in before the decision. |
previous_clock_out | timestamp | Yes | Clock-out before the decision. |
reason | string | No | Why the correction is being asked for. |
status | pending · approved · rejected | No | Where the request stands. |
approved_at | timestamp | Yes | When it was approved or rejected. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AttendanceSettings
How the workspace grades attendance. Read-only here, and published because without it the minutes and statuses on an attendance record cannot be interpreted — a late_minutes of 20 means nothing until you know the grace period was 15.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | attendance_settings | No | Always attendance_settings. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
grace_period_minutes | integer | No | Lateness forgiven entirely. A shift may carry its own grace period, which wins wherever it is set. |
late_threshold_1_minutes | integer | No | Minutes late at which the first action applies. |
late_threshold_1_action | string | No | What happens at the first threshold. |
late_threshold_2_minutes | integer | No | Minutes late at which the second action applies. |
late_threshold_2_action | string | No | What happens at the second threshold. |
late_threshold_3_minutes | integer | No | Minutes late at which the third action applies. |
late_threshold_3_action | string | No | What happens at the third threshold. |
lates_per_month_for_absent | integer | No | How many late days in a month count as one absence. |
overtime_min_minutes | integer | No | Shortest stretch past the shift end that counts as overtime. |
overtime_rate_multiplier | string | No | Multiple of the ordinary hourly rate paid for overtime. |
overtime_require_approval | boolean | No | When true, overtime minutes only count once a request is approved. |
overtime_auto_approve | boolean | No | When true, overtime requests are approved on creation. |
checkout_grace_minutes | integer | No | How long after the shift end a clock-out is still accepted onto the day. |
working_days_per_week | integer | No | Working days in a normal week. |
week_off_days | string | No | Default weekly rest days, where a shift does not set its own. |
geo_attendance_enabled | boolean | No | Whether punches are geofenced to assigned sites. |
geo_max_accuracy_meters | integer | No | Worst GPS accuracy accepted. A coarser fix is refused rather than trusted, since it could place someone inside a fence they are nowhere near. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
AttendanceSite
A geofenced location employees may clock in from. Only meaningful when geo attendance is enabled for the workspace.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | attendance_site | No | Always attendance_site. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Site name. |
latitude | string | No | Centre of the geofence, in decimal degrees. |
longitude | string | No | Centre of the geofence, in decimal degrees. |
radius_meters | integer | No | How far from the centre a punch is accepted. |
branch_id | string | Yes | Branch this site belongs to. |
status | active · inactive | No | Whether the site is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Branch
An office or site.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | branch | No | Always branch. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Branch name. |
code | string | Yes | Short code. |
address | string | Yes | Street address. |
city | string | Yes | City. |
phone | string | Yes | Contact number. |
email | string | Yes | Contact email. |
is_head_office | boolean | No | True for the workspace’s principal office. |
status | active · inactive | No | Whether the record is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Candidate
Someone who has applied. These are people outside the workspace, so the record carries personal contact details and sits behind its own recruitment:read scope. The CV file is not exposed.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | candidate | No | Always candidate. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
first_name | string | No | Given name. |
last_name | string | No | Family name. |
email | string | No | Contact email. |
phone | string | Yes | Contact phone. |
current_employer | string | Yes | Where they work now. |
current_designation | string | Yes | Their current job title. |
linkedin_url | string | Yes | Their LinkedIn profile. |
notes | string | Yes | Free-text note. |
converted_employee_id | string | Yes | The employee record created when they were hired. |
converted_at | timestamp | Yes | When they became an employee. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Contract
An employment contract. Signing one is what activates an employee, so status here and an employee’s status move together.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | contract | No | Always contract. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
contract_number | string | Yes | Human-facing reference. |
type | string | No | The kind of contract. |
start_date | date | No | First day of the term. |
end_date | date | Yes | Last day. Null for an open-ended contract. |
probation_months | integer | No | Length of probation. |
salary_structure_id | string | Yes | Structure the contract sets. |
gross_salary | string | Yes | Gross pay the contract sets. |
status | string | No | Where the contract stands. |
signed_date | date | Yes | When it was signed. |
accepted_electronically | boolean | No | Whether it was accepted through the portal rather than on paper. |
accepted_at | timestamp | Yes | When the employee accepted it. |
language | string | Yes | Language it was issued in. Null means English. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Department
A department. Departments may nest through parent_id.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | department | No | Always department. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Department name. |
code | string | Yes | Short code. |
parent_id | string | Yes | Parent department, for a nested structure. |
head_employee_id | string | Yes | Employee who heads this department. |
cost_center | string | Yes | Cost centre reference. |
status | active · inactive | No | Whether the record is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Designation
A job title.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | designation | No | Always designation. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Job title. |
code | string | Yes | Short code. |
level | integer | No | Seniority level. Higher is more senior; 0 when unranked. |
pay_grade_id | string | Yes | Pay grade this title maps to. |
job_description | string | Yes | Free-text job description. |
status | active · inactive | No | Whether the record is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
DocumentType
A kind of document the workspace collects — a passport, a degree, a contract copy. Mandatory types are the ones an employee record is considered incomplete without.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | document_type | No | Always document_type. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
code | string | Yes | Short code. |
is_mandatory | boolean | No | Whether every employee is expected to have one. |
allowed_formats | string | No | File types accepted, as a comma-separated list. |
max_file_size_mb | integer | No | Largest upload accepted, in megabytes. |
allow_multiple_entries | boolean | Yes | Whether an employee may hold several of this type. |
sort_order | integer | Yes | Display position. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Employee
A person employed by the workspace. Related records are referenced by id; child collections are separate sub-resources so that updated_since stays truthful.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | employee | No | Always employee. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_code | string | No | The workspace's own identifier for this employee, unique within the workspace. READ-ONLY: it is assigned from the workspace numbering settings (prefix and digit count) and cannot be set or changed through the API. Use it as a filter on the list endpoint. |
first_name | string | No | Given name. |
last_name | string | No | Family name. |
father_name | string | Yes | Father's name, where the workspace records it. |
date_of_birth | date | Yes | Date of birth. |
gender | string | Yes | Gender as recorded. |
marital_status | string | Yes | Marital status as recorded. |
nationality | string | No | Nationality. Empty string when not recorded. |
personal_email | string | Yes | Personal email address. |
work_email | string | Yes | Work email address. |
phone_primary | string | Yes | Primary contact number. |
national_id | string | Yes | Government identity number. Its meaning follows the workspace country: CNIC in Pakistan, Emirates ID in the UAE, National Insurance number in the UK. Requires the employees.sensitive:read scope. |
department_id | string | No | Department this employee belongs to. |
designation_id | string | No | Job title. |
branch_id | string | Yes | Office or branch. |
employment_type_id | string | No | Employment type, e.g. permanent or contract. |
reporting_manager_id | string | Yes | The employee this person reports to. |
joining_date | date | No | First day of employment. |
confirmation_date | date | Yes | Date probation was confirmed. |
probation_end_date | date | Yes | Scheduled end of probation. |
separation_date | date | Yes | Last day of employment. |
status | string (enum) | No | Employment status. |
deleted | boolean | No | True when the record has been deleted. Deleted employees are excluded unless include_deleted=true, and are returned with this flag so a client syncing on updated_since can learn about removals. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the employee record itself last changed. Does not move when a child record (address, bank account, document) changes. |
EmployeeDocument
One document held against an employee. The file itself is not exposed — only whether it exists, and whether someone has verified it.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | employee_document | No | Always employee_document. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
document_type_id | string | No | The kind of document. |
entry_label | string | Yes | Label distinguishing several documents of one type. |
verification_status | pending · verified · rejected | No | Whether the document has been checked. |
verified_at | timestamp | Yes | When it was verified. |
rejection_reason | string | Yes | Why it was rejected. |
version | integer | No | Increments when the document is replaced. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
EmployeeShift
Which shift an employee works, from a given date. Assignments form a history: creating one closes the previous open assignment the day before the new one starts.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | employee_shift | No | Always employee_shift. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
shift_id | string | No | The shift being worked. |
effective_from | date | No | First day this assignment applies. |
effective_to | date | Yes | Last day it applies. Null while it is the current assignment. |
created_at | timestamp | No | When the record was created. |
EmploymentType
An employment arrangement, e.g. permanent, contract, intern.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | employment_type | No | Always employment_type. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Name of the arrangement. |
description | string | Yes | Free-text description. |
is_residential | boolean | No | The role includes on-site residence. |
accommodation_provided | boolean | No | Accommodation is provided. |
meals_provided | boolean | No | Meals are provided. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
ExpenseCategory
A kind of expense that can be claimed.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | expense_category | No | Always expense_category. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
description | string | Yes | What belongs in it. |
is_active | boolean | No | Whether it can be claimed against. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
ExpenseClaim
A reimbursement request. Two levels of approval, and an approved claim becomes a payroll addition rather than a separate payment.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | expense_claim | No | Always expense_claim. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
title | string | No | What the claim is for. |
description | string | Yes | Detail. |
total_amount | string | No | Sum of the claim items. |
status | string (enum) | No | Where the claim stands. |
submitted_at | timestamp | Yes | When it was submitted. |
manager_approved_at | timestamp | Yes | When the manager approved it. |
hr_approved_at | timestamp | Yes | When HR gave final approval. |
rejected_at | timestamp | Yes | When it was rejected. |
rejection_reason | string | Yes | Why it was rejected. |
cancelled_at | timestamp | Yes | When it was withdrawn. |
payroll_adjustment_id | string | Yes | The payroll addition an approved claim created. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
ExpenseClaimItem
One line on a claim. Receipts are not exposed.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | expense_claim_item | No | Always expense_claim_item. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
claim_id | string | No | The claim. |
category_id | string | No | The expense category. |
expense_date | date | No | When the expense was incurred. |
amount | string | No | The amount claimed. |
description | string | Yes | What it was for. |
sort_order | integer | No | Position on the claim. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Holiday
A non-working day.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | holiday | No | Always holiday. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Holiday name. |
date | date | No | The date, as a calendar date. |
year | integer | No | Calendar year the date falls in. |
type | public · company · optional · religious | No | Category of holiday. |
is_recurring | boolean | No | Repeats annually on the same date. |
branch_id | string | Yes | Limits the holiday to one branch. Null applies it workspace-wide. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
HrLetter
A letter issued to an employee — an employment certificate, a salary letter, an experience letter. The rendered PDF is not exposed.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | hr_letter | No | Always hr_letter. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
letter_type | string | No | The kind of letter. |
reference_number | string | No | Human-facing reference, printed on the letter. |
language | string | Yes | Language it was issued in. Null means English. |
issued_date | date | No | The date on the letter. |
emailed_at | timestamp | Yes | When it was emailed to the employee. |
created_at | timestamp | No | When the record was created. |
HrLetterRequest
An employee asking for a letter. An approved request produces an issued letter, which issued_letter_id points at.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | hr_letter_request | No | Always hr_letter_request. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
letter_type | string | No | The kind requested. |
purpose | string | No | Why it is needed. |
addressed_to | string | Yes | Who the letter should be addressed to. |
status | string | No | Where the request stands. |
rejection_reason | string | Yes | Why it was refused. |
decided_at | timestamp | Yes | When it was decided. |
issued_letter_id | string | Yes | The letter this request produced. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
JobOpening
A role the workspace is hiring for.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | job_opening | No | Always job_opening. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
title | string | No | Job title. |
department_id | string | Yes | Department the role sits in. |
designation_id | string | Yes | Designation the role maps to. |
branch_id | string | Yes | Branch the role is based at. |
employment_type_id | string | Yes | Employment type offered. |
level | integer | Yes | Seniority level. |
headcount | integer | No | How many people are being hired. |
status | string | No | Where the opening stands. |
budget_approved_at | timestamp | Yes | When the headcount was signed off. |
closed_at | timestamp | Yes | When the opening was closed. |
notes | string | Yes | Free-text note. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
LeaveApplication
A request for leave. Approving one consumes the balance and marks the days on the employee's attendance.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | leave_application | No | Always leave_application. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee requesting leave. |
leave_type_id | string | No | The kind of leave requested. |
fiscal_year_id | string | No | The fiscal year the days are drawn from. |
from_date | date | No | First day of leave. |
to_date | date | No | Last day of leave. |
total_days | string | No | Days this request consumes. Computed by the workspace from its own rest days, holidays and sandwich rule — not simply the span. |
is_half_day | boolean | No | Whether the request is for half a day. |
half_day_type | string | Yes | Which half, when the request is a half day. |
reason | string | No | Why the leave is being requested. |
status | pending · approved · rejected · cancelled | No | Where the request stands. |
approved_at | timestamp | Yes | When it was approved or rejected. |
rejection_reason | string | Yes | Why it was rejected. |
cancelled_at | timestamp | Yes | When it was cancelled. |
cancellation_reason | string | Yes | Why it was cancelled. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
LeaveBalance
One employee's standing under one leave type for a fiscal year. available_days is the number that matters and the only one that accounts for accrual — do not derive it from the others.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | leave_balance | No | Always leave_balance. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Identifier of the underlying allocation. |
employee_id | string | No | The employee this balance belongs to. |
leave_type_id | string | No | The leave type. |
fiscal_year_id | string | No | The fiscal year this balance covers. |
entitled_days | string | No | The year's full entitlement, before accrual is applied. |
accrued_days | string | No | How much of the entitlement has been released so far. Equal to entitled_days under an annual policy; a fraction of it under a monthly one. |
carried_forward_days | string | No | Days brought in from the previous year. |
used_days | string | No | Days consumed by approved leave. |
encashed_days | string | No | Days paid out instead of taken. |
available_days | string | No | What the employee can actually take: accrued + carried forward − used − encashed. Computed here because a client subtracting the raw columns would over-report every monthly-accrual policy. |
LeaveGroup
A named set of policies applied together. An employee belongs to one group, which is what decides the leave types available to them.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | leave_group | No | Always leave_group. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Group name. |
description | string | Yes | What the group is for. |
is_active | boolean | No | Whether the group is in use. |
is_default | boolean | No | Applied to employees with no group of their own. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
LeavePolicy
The entitlement rules for one leave type. Read-only: changing a policy retroactively changes what people are entitled to and what has already accrued, which is a decision for the app rather than an API call.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | leave_policy | No | Always leave_policy. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
leave_type_id | string | No | The leave type this policy governs. |
annual_quota | string | No | Days granted for a full year of service. |
accrual_method | string | No | How the quota is released. annual grants it all at the start of the year; monthly releases it as the year passes, which is why a balance cannot be derived from the quota alone. |
allocation_type | string | No | Whether the entitlement runs per fiscal year or per cycle. |
max_consecutive_days | integer | Yes | Longest single stretch allowed. Null when unlimited. |
carry_forward_allowed | boolean | No | Whether unused days survive into the next year. |
max_carry_forward_days | string | No | Ceiling on days carried forward. |
encashment_allowed | boolean | No | Whether unused days can be paid out instead of taken. |
negative_balance_allowed | boolean | No | Whether an employee may go into deficit. |
max_negative_days | string | No | How far into deficit, when that is allowed. |
pro_rata_for_joiners | boolean | No | Whether someone joining mid-year gets a proportion of the quota. |
min_service_months | integer | No | Months of service before this type may be used. |
applicable_gender | string | No | Restricts the type where the law or the policy does. |
requires_document_after_days | integer | Yes | Length past which supporting evidence is expected. Null when never. |
sandwich_rule | boolean | No | Whether rest days falling inside a leave span are counted against it. |
effective_from | date | No | First day this policy applies. |
effective_to | date | Yes | Last day it applies. Null while it is the current policy. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
LeaveType
A kind of leave — annual, sick, unpaid. The entitlement attached to it lives on its policy.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | leave_type | No | Always leave_type. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
code | string | No | Short code, unique within the workspace. |
color | string | No | Hex colour used to render this type in calendars. |
is_paid | boolean | No | Whether days taken under this type are paid. |
is_active | boolean | No | Inactive types cannot be applied for, but keep their history. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
Loan
A loan to an employee. Installments are claimed against payroll as the months come round, so outstanding_balance moves with each run.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | loan | No | Always loan. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
loan_type_id | string | No | The kind of loan. |
loan_number | string | Yes | Human-facing reference. |
amount | string | No | Principal advanced. |
interest_rate | string | No | Annual rate, as a percentage. |
total_payable | string | No | Principal plus interest. |
installment_amount | string | No | Amount due each month. |
total_installments | integer | No | Months of repayment. |
paid_installments | integer | No | Installments settled so far. |
paid_amount | string | No | Repaid so far. |
outstanding_balance | string | No | Still owed. |
start_month | integer | No | First repayment month, 1–12. |
start_year | integer | No | First repayment year. |
purpose | string | Yes | Why the loan was taken. |
status | string | No | Where the loan stands. |
approved_at | timestamp | Yes | When it was approved. |
completed_at | timestamp | Yes | When it was fully repaid. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
LoanInstallment
One scheduled repayment. Claimed when the payroll run for its due month is processed, and settled when that run is locked.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | loan_installment | No | Always loan_installment. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
loan_id | string | No | The loan. |
installment_no | integer | No | Position in the schedule, from 1. |
due_month | integer | No | Month due, 1–12. |
due_year | integer | No | Year due. |
principal | string | No | Principal portion. |
interest | string | No | Interest portion. |
total_due | string | No | Total for this installment. |
paid_amount | string | No | Amount actually settled. |
status | string | No | Where the installment stands. |
paid_at | timestamp | Yes | When it was settled. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
LoanType
A kind of loan the workspace offers, with its limits.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | loan_type | No | Always loan_type. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
code | string | No | Short code, unique within the workspace. |
max_amount | string | Yes | Largest loan of this kind. Null when unlimited. |
max_installments | integer | Yes | Longest repayment. Null when unlimited. |
interest_rate | string | No | Annual rate, as a percentage. |
max_active_loans | integer | No | How many of this kind an employee may hold at once. |
is_active | boolean | No | Whether it is offered. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
OvertimeRequest
A claim for overtime on one day. Whether overtime counts toward pay without one depends on the workspace's attendance settings.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | overtime_request | No | Always overtime_request. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
date | date | No | The day the overtime was worked. |
hours | string | No | Hours claimed. |
reason | string | Yes | Justification. |
status | pending · approved · rejected | No | Where the request stands. A workspace with auto-approval on returns approved straight from the create call. |
approved_at | timestamp | Yes | When it was approved or rejected. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
PayGrade
A salary band.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | pay_grade | No | Always pay_grade. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Grade name. |
min_salary | string | No | Bottom of the band, as a decimal string in the workspace currency. |
max_salary | string | No | Top of the band, as a decimal string in the workspace currency. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
PayrollEntry
One employee's pay for one run. The attendance figures are what the calculation actually used, so they explain the deductions rather than merely accompanying them.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | payroll_entry | No | Always payroll_entry. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
payroll_run_id | string | No | The run this entry belongs to. |
employee_id | string | No | The employee this record belongs to. |
salary_assignment_id | string | No | The pay package the calculation used. |
working_days | string | No | Days in the month the employee was expected to work. |
present_days | string | No | Days counted as present. |
absent_days | string | No | Days counted as absent. |
leave_days | string | No | Days on approved leave. |
unpaid_leave_days | string | No | Leave days that are not paid. |
half_days | string | No | Days counted as half. |
late_count | integer | No | Late arrivals. |
early_leave_count | integer | No | Early departures. |
holidays | integer | No | Public holidays in the month. |
overtime_hours | string | No | Approved overtime hours paid. |
gross_salary | string | No | Gross pay before deductions. |
total_earnings | string | No | Earnings including bonus and additions. |
total_deductions | string | No | Everything subtracted. |
net_salary | string | No | What the employee is paid. |
employer_contributions | string | No | Employer-paid contributions. On top of net pay, not deducted from it. |
taxable_income | string | No | The base income tax was computed on. |
tax_amount | string | No | Income tax withheld. |
loan_deduction | string | No | Loan installments claimed this month. |
absence_deduction | string | No | Deducted for absent days. |
unpaid_leave_deduction | string | No | Deducted for unpaid leave. Separate from absence so the two reconcile distinctly on a slip. |
late_deduction | string | No | Deducted for lateness. |
bonus_amount | string | No | Approved bonuses added this month. |
adjustment_addition | string | No | Approved one-off additions. |
adjustment_deduction | string | No | Approved one-off deductions. |
payment_method | string | No | How the salary is paid. |
payment_date | date | Yes | The date the transfer was actually made. |
payment_reference | string | Yes | Transfer or cheque reference. |
paid_at | timestamp | Yes | When the entry was marked paid in the system. |
acknowledged_at | timestamp | Yes | When the employee confirmed receipt. |
status | string | No | Where the entry stands. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
PayrollEntryComponent
One line on one payslip, with the amount actually applied. This is what turns an entry total into an explanation.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | payroll_entry_component | No | Always payroll_entry_component. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
payroll_entry_id | string | No | The entry this line belongs to. |
salary_component_id | string | No | The component. |
type | earning · deduction · employer_contribution | No | Earning, deduction, or employer contribution. |
amount | string | No | The amount applied. |
is_taxable | boolean | No | Whether it counted toward taxable income. |
display_order | integer | No | Position on the payslip. |
PayrollRun
One month's payroll for the workspace. A run moves draft → approved → locked → disbursed; once locked its entries cannot change.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | payroll_run | No | Always payroll_run. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
fiscal_year_id | string | No | The fiscal year this run belongs to. |
month | integer | No | Calendar month, 1–12. |
year | integer | No | Calendar year. |
run_date | date | No | The date the run covers. |
total_employees | integer | No | Employees included. |
total_gross | string | No | Sum of gross pay across the run. |
total_deductions | string | No | Sum of deductions. |
total_net | string | No | Sum of net pay — what is actually disbursed. |
total_employer_cost | string | No | Employer-paid contributions on top of net pay. Not part of what employees receive. |
status | string (enum) | No | Where the run stands. |
source | processed · imported | No | processed came from the monthly pipeline. imported was backfilled from a historical file — it has no attendance behind it, so its per-day figures are zero rather than measured. |
approved_at | timestamp | Yes | When the run was approved. |
locked_at | timestamp | Yes | When it was locked and became immutable. |
disbursed_at | timestamp | Yes | When payment was recorded. |
notes | string | Yes | Free-text note. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
RestDaySwap
An employee works one of their rest days and takes a different day off instead. worked_date becomes an ordinary working day and off_date becomes the rest day, for both the calendar and payroll.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | rest_day_swap | No | Always rest_day_swap. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
worked_date | date | No | The rest day that was worked. |
off_date | date | No | The working day taken off in exchange. |
reason | string | Yes | Free-text note. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
SalaryAssignment
An employee's pay, from a date. Assignments form a history: a raise closes the previous one and opens a new one, so the row with a null effective_to is the current package.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | salary_assignment | No | Always salary_assignment. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
employee_id | string | No | The employee this record belongs to. |
salary_structure_id | string | No | The structure this package follows. |
gross_salary | string | No | Monthly gross pay. |
effective_from | date | No | First day this package applies. |
effective_to | date | Yes | Last day it applies. Null while it is the current package. |
reason | string | Yes | Why the package changed. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
SalaryComponent
A line that can appear on a payslip — an earning, a deduction, or an employer contribution. The contributes_to_* flags decide which statutory bases it counts toward, which is usually only true of basic pay.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | salary_component | No | Always salary_component. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Display name. |
code | string | No | Short code, unique within the workspace. |
type | earning · deduction · employer_contribution | No | What the line does. employer_contribution is an employer-paid cost that is NOT part of employee cash — it does not reduce net pay and does not appear in the employee total. |
category | string | Yes | Grouping label. |
calculation_type | string | No | How the amount is derived: fixed, a percentage, or a formula. |
default_value | string | No | Amount or percentage used when no override is set. |
is_taxable | boolean | No | Whether the line counts toward taxable income. |
exemption_mode | string | No | Partial-exemption treatment. none means is_taxable alone decides; pct_of_basic exempts up to a percentage of basic pay; flat_cap exempts up to a fixed amount. |
exemption_value | string | No | The percentage or cap the exemption mode applies. |
affects_gross | boolean | No | Whether the line is part of gross pay. |
contributes_to_eobi | boolean | No | Counts toward the statutory social-security base. |
contributes_to_pf | boolean | No | Counts toward the provident-fund base. |
contributes_to_overtime | boolean | No | Counts toward the hourly rate overtime is paid at. |
contributes_to_gratuity | boolean | No | Counts toward the gratuity accrual base. |
is_mandatory | boolean | No | Present on every structure. |
is_active | boolean | No | Whether the line is in use. |
display_order | integer | No | Position on a payslip. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
SalarySlip
A rendered payslip document. The PDF itself is not exposed — the file lives in workspace storage and is delivered by email or the portal.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | salary_slip | No | Always salary_slip. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
payroll_entry_id | string | No | The entry this slip renders. |
slip_number | string | Yes | Human-facing reference. |
language | string | Yes | Language the slip was generated in. Null means English. |
emailed_at | timestamp | Yes | When it was emailed to the employee. |
generated_at | timestamp | No | When it was rendered. |
created_at | timestamp | No | When the record was created. |
SalaryStructure
A named set of components. An employee is assigned one, and the amounts for their own assignment live on the assignment rather than here.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | salary_structure | No | Always salary_structure. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Structure name. |
description | string | Yes | What it is for. |
is_active | boolean | No | Whether it is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |
SalaryStructureComponent
One component on one structure, with the default it contributes.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | salary_structure_component | No | Always salary_structure_component. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
salary_structure_id | string | No | The structure. |
salary_component_id | string | No | The component. |
calculation_type | string | Yes | Overrides the component's own calculation type. |
default_value | string | Yes | Amount or percentage for this structure. |
is_mandatory | boolean | No | Whether the component cannot be removed from an assignment. |
display_order | integer | No | Position on a payslip. |
Shift
A working pattern: hours, grace periods and rest days.
| Field | Type | Nullable | Description |
|---|---|---|---|
object | shift | No | Always shift. Every object names its own type, so a payload stays self-describing after it has been passed through your code. |
id | string | No | Unique identifier. |
name | string | No | Shift name. |
start_time | string | No | Start time as HH:MM:SS in the workspace timezone. |
end_time | string | No | End time as HH:MM:SS in the workspace timezone. Earlier than start_time for a shift that crosses midnight. |
break_duration_minutes | integer | No | Unpaid break within the shift, in minutes. |
grace_period_minutes | integer | No | Minutes after the start time before an arrival counts as late. |
late_threshold_minutes | integer | No | Minutes late before the day is marked as a late arrival. |
weekly_off_days | integer[] | No | Rest days as ISO weekday numbers, where 1 is Monday and 7 is Sunday. |
attendance_mode | punch_required · auto_present · punch_not_required | No | How attendance is captured. punch_required expects clock-in and clock-out, auto_present marks attendance automatically, and punch_not_required tracks neither. |
is_default | boolean | No | Assigned to new employees when no other shift is chosen. |
status | active · inactive | No | Whether the record is in use. |
created_at | timestamp | No | When the record was created. |
updated_at | timestamp | No | When the record last changed. |