Developers

Changes

Changelog

Deliberate changes to the published contract, newest first. 253 operations today. Additions — a new operation, a new optional field, a new enum value in a response — are not breaking and ship without notice; your client must tolerate fields and values it does not know. Anything that is breaking is called out below and, from now on, announced through the deprecation policy before it happens.

Errors, capabilities and the work-day register

  • Every operation now documents its error responses (400/401/403/404/409/429/500) against a published `Problem` schema, so a generated client models failure as well as success.
  • Each operation declares the capability its key scope must contain, as `x-kelomo-capabilities` and in its description.
  • The `Idempotency-Key` header is declared on the operations that require it — a generated client could not send it before.
  • Every response carries `X-Request-Id`, repeated in the problem body as `requestId`; the problem `type` links to the code’s entry in the error reference.
  • New: `GET /v1/work-days` — the organisation-wide, cursor-paginated work-day register with `updatedSince`, replacing one-request-per-member reads.
  • New: `GET /v1/me/access` — what the presented credential is and which capabilities it can exercise.
  • New: `GET /v1/webhook-events` — the event catalogue with each payload as JSON Schema.
  • Published: employer-assigned absence (`POST /v1/team/absence/preview`, `POST /v1/team/absence/plan`) and `POST /v1/absence-periods/{id}/cancel`, so an HR system of record can push and withdraw approved leave.
  • Rate-limit headers now report the binding budget of the two buckets and add `RateLimit-Policy`; the API-platform headers are exposed through CORS.

Provisioning, time import and the deprecation policy

Breaking

  • `GET /v1/projects` returns `{ items, pageInfo }` instead of `{ projects }`. Read the cursor to page; a client reading `projects` must move to `items`.
  • HRIS provisioning: members became writable (create, bulk create, update, invite, unit placement, employment window, termination).
  • Time import: supervisor entries, day types, confirmations and reopens (single and by range), batch returns and corrections.
  • `GET /v1/projects` gained `updatedSince`.
  • Deprecation policy: retiring an operation announces itself with RFC 9745 `Deprecation` and RFC 8594 `Sunset` headers, twelve months ahead of a removal.

Incremental sync and the money loop

  • `updatedSince` on customers, members, invoices, quotes, deals, leads and tasks.
  • `invoice.paid` fires on the transition to settled, once, no matter which of the six writers closes the receivable.
  • Sync events: `customer.created/updated`, `project.updated`, `member.updated`, `shift.unpublished`.
  • Dead-lettered webhook deliveries and approaching key expiry now notify the people who can act on them.

API key identity model

Breaking

  • `POST /v1/api-keys` and the admin key rotation were removed: a rotated token is shown to the caller, so an admin rotating somebody else’s key was a silent way to obtain a credential in their name. Mint personal keys at `POST /v1/me/api-keys`.
  • Personal keys moved to `/v1/me/api-keys` and are open to every member, so a key is only as large as the person who made it.
  • Service keys (`POST /v1/api-keys/service`) name an explicit owner and can be reassigned when that person leaves.

First release of the public contract

  • Around 160 operations across time, members, balances, shifts, absences, approvals, payroll and billing batches, invoices and receivables, projects, tasks, quotes, customers, CRM, reports, catalogues, the integration-event log, webhooks and keys.
  • Search, bulk imports and several MCP-only routes were brought inside the published contract.