Skip to main content

Versioning & changelog

The API is versioned in the path: /api/v1. A v2 would be a new path served alongside v1, not a replacement for it.

What we may change without warning​

These are additive and your integration must tolerate them:

  • A new field on an existing object. Do not use a parser that rejects unknown properties.
  • A new endpoint, or a new optional parameter on an existing one.
  • A new value in an enumerated field — a new attendance status, say. Handle the default case rather than assuming the set is closed.
  • A new webhook event type. You only receive the events you subscribed to.
  • Wording changes in title and detail on an error. Branch on code, which never changes meaning.

What counts as breaking​

  • Removing or renaming a field, endpoint or error code.
  • Narrowing what a field may contain, or making an optional parameter required.
  • Changing the meaning of an existing code or scope.
  • Changing an authentication or pagination mechanism.

Outside beta, these go in a new version rather than into v1.

During the private beta​

v1 is not frozen yet. We are in a private beta with a small number of workspaces, and the point of it is to find the mistakes that are still cheap to correct. A breaking change is possible.

What we commit to instead: we know who is building against the API, and we will contact you directly before changing anything that would break you. That promise only works if the list is accurate, so tell us you are integrating.

When the contract freezes at general availability, this page becomes the record of every change.

Changelog​

2026-10 — Leave pay share​

leave_type gains pay_percent, an integer from 1 to 100: the share of a normal day's pay a day of that leave is paid at. It reads 100 unless a workspace set it lower; the reduced-pay tiers of sick and maternity leave in a starter set read their rate (50, 75).

On a payroll entry, unpaid_leave_days and unpaid_leave_deduction now include the unpaid share of leave at reduced pay: four days of 50% leave count as 2 days.

2026-10 — Employee status is read-only​

PATCH /v1/employees/{id} used to accept status and then ignore it: the request succeeded and the employee kept their status. It is now refused with 400 validation_failed, and the errors entry names status, the same way employee_code is refused. POST /v1/employees refuses it too; every employee is created as new.

Changing a status is not a field write. Activation opens the employee's leave balance, and leaving runs through offboarding (clearance and final settlement), which writes separated. Both happen in the app. Reading status, and filtering the list by it, are unchanged.

2026-09 — Plan features​

Payroll and loans, recruitment, and geofenced attendance sites are now refused with 402 plan_upgrade_required when the workspace's plan does not include the feature, matching what the app already did. The refusal carries feature and plan (new, additive fields on the problem body), each gated endpoint documents the 402, and the OpenAPI document marks it with x-plan-feature.

GET /v1/scopes gains plan_feature per scope, and webhook events for a feature the plan lacks — the payroll events — are no longer delivered. Keys are unaffected: a key may still hold payroll:read on any plan.

Nothing changes for a workspace whose plan includes these features, which is every beta workspace.

2026-09 — Documents, assets, recruitment and announcements​

Thirteen more read-only resources, under four scopes: documents:read for document types, employee documents, contracts and HR letters; the new assets:read and announcements:read; and recruitment:read for openings, candidates and applications.

No file is exposed anywhere. A signed contract, a rendered letter, an announcement attachment and a candidate's CV all live behind keys into workspace storage — they would resolve to nothing for you and invite guessing at other people's.

Assets are retired rather than deleted, so pass include_deleted if you are mirroring them; without it a retirement looks like a record that simply stopped existing.

Writes are deliberately absent. Every one of these is a file-and-workflow surface: uploading a document needs multipart and a storage design this API does not have yet, and issuing a letter or converting a candidate runs a pipeline with emails and PDF rendering behind it. Writing the row without running the pipeline would produce records the app itself treats as broken.

2026-09 — Payroll, loans and expenses​

Fourteen resources, all read-only: salary components, structures and assignments; payroll runs, entries and their component lines; salary slips; loan types, loans and installments; expense categories, claims and items.

Read-only is a decision rather than a stage. The figure on a payroll entry is the product of attendance, leave, loans, bonuses, adjustments, statutory contributions and tax slabs — a write path that set it directly would produce a number the workspace itself disagrees with.

Expenses have their own expenses:read scope, so an expense-reporting integration does not have to be trusted with everyone's salary.

Two of these resources page by id rather than by creation time, because their tables were created without timestamps. The cursor is opaque either way; only the ordering differs.

2026-09 — Leave​

Leave types, policies, groups, balances and applications, with approve, reject and cancel. The four leave.* webhooks now fire — and they fire for decisions made in the app as well as through the API, because they are recorded inside the same transaction as the decision itself.

Read available_days from a balance rather than deriving one: it accounts for accrual, and subtracting the raw columns over-reports every monthly-accrual policy.

Policies and groups are read-only. Changing a policy retroactively changes what everyone is entitled to and what has already accrued, which belongs in the app.

2026-09 — Attendance & time​

Eight resources covering the working day: attendance records, punches, regularisations, overtime requests, rest-day swaps, shift assignments, geofenced attendance sites, and a read-only attendance settings object.

attendance.recorded and attendance.updated webhooks now fire.

Worth reading if you record punches: a punch that changes no attendance record answers 409, not 201. The punch is still written to the log — the status tells you whether the day moved. See the attendance reference.

2026-09 — Outbound webhooks​

Signed, retried webhook delivery with per-endpoint secrets, rotation with a 24-hour overlap, a delivery log and manual replay. See Webhooks.

2026-09 — Developer console​

Self-service API keys and webhook endpoints in the app, under Settings, with per-key usage.

2026-09 — Core HR and organisation​

Employees, departments, designations, branches, employment types, pay grades, shifts and holidays. employee.created, employee.updated and employee.deleted webhooks.

2026-09 — The API opens​

Scoped API keys, cursor pagination, idempotent writes, application/problem+json errors, per-plan rate limits, and a generated OpenAPI document at /api/v1/openapi.json.

Coming next​

The read surface is complete. Next is the private beta, and then the contract freezes at general availability.

Not yet covered, and each for its own reason: file upload and download, which needs a pre-signed-URL design rather than multipart on these endpoints; performance and scorecards, whose composite figures are computed with clamping and windowing that publishing the raw parts would invite clients to recompute wrongly; and onboarding and offboarding checklists, which are internal task lists rather than data anyone integrates against. Say so if you need one of them and it moves up.