Skip to content

Endpoint reference

Every route, and the scope it needs. This table is generated from the routes the API actually serves, so it cannot describe an endpoint that does not exist or omit one that does.

EndpointScope requiredFiltersText search
GET /api/v1/assets
GET /api/v1/assets/{id}
assets:readcategory, location_id, statusyes
GET /api/v1/handovers
GET /api/v1/handovers/{id}
handovers:readlocation_id, statusyes
GET /api/v1/kpi-results
GET /api/v1/kpi-results/{id}
kpi:readmetric_id—
GET /api/v1/kpis
GET /api/v1/kpis/{id}
kpi:readcadence, function_category, location_idyes
GET /api/v1/learning-assignments
GET /api/v1/learning-assignments/{id}
learning:read——
GET /api/v1/locations
GET /api/v1/locations/{id}
locations:read—yes
GET /api/v1/people
GET /api/v1/people/{id}
people:readlocation_idyes
GET /api/v1/purchase-requests
GET /api/v1/purchase-requests/{id}
approvals:readlocation_idyes
GET /api/v1/systems
GET /api/v1/systems/{id}
systems:readcategory, location_id, statusyes
GET /api/v1/tasks
GET /api/v1/tasks/{id}
tasks:readlocation_idyes
GET /api/v1/transitions
GET /api/v1/transitions/{id}
transitions:readlocation_id, statusyes
GET /api/v1/vendors
GET /api/v1/vendors/{id}
vendors:readcategory, location_id, statusyes
GET /api/v1/workplace-records
GET /api/v1/workplace-records/{id}
workplace:readlocation_id, record_type, statusyes
WriteScope requiredBody
POST /api/v1/kpi-resultskpi:recordmetric_id, period_start, actual, target (optional)

Common parameters

Every list accepts:

  • limit — 1 to 1000, default 100
  • cursor — the next_cursor from the previous page
  • updated_since — an ISO 8601 timestamp; returns only records changed after it

A register accepts search only where the table above says so, and only the filters listed against it. A parameter an endpoint does not accept is a 422, and a value outside the set it does accept is a 400 — neither is an empty page, because a page you cannot tell from "no matches" is worse than an error.

Recording a KPI result

POST /api/v1/kpi-results with a key holding kpi:record records the result of one closed reporting period, or corrects the one already there.

curl https://your-workspace.kitset.io/api/v1/kpi-results \
  -H "Authorization: Bearer kitset_sk_live_YOUR_KEY_ID_HERE" \
  -H "Content-Type: application/json" \
  -d '{"metric_id": "9b2c...", "period_start": "2026-09-01", "actual": 28.5}'
  • metric_id is the id of an active KPI in this workspace, from GET /api/v1/kpis. Any other — archived, deleted, or another workspace's — is a 404, and the three are never told apart.
  • period_start is the first day of one of the KPI's reporting periods: a Monday for a weekly KPI, the 1st for a monthly one, the first day of a quarter for a quarterly one. The period must have ended where the KPI is reported; otherwise the answer is 400.
  • actual is the result, up to four decimal places. Send it as a JSON number or a string; either is read exactly, never through a binary float.
  • target is optional. Leave it out and a new result is judged against the KPI's current target, while a correction keeps the target its period was judged against.

The answer is the result as GET /api/v1/kpi-results/{id} returns it, with operation set to created (status 201), or updated or unchanged (both 200). Sending the same request twice records it once, so a request that timed out can simply be sent again.

There is no note: like every field this API serves, a write carries no free text. The result is stored without an author — a key is not a person — and the workspace audit trail names the key id instead. The workspace's KPI Scorecards app must be installed (403 otherwise), and a workspace whose subscription has lapsed answers 402. The body may be at most 4096 bytes, must declare its Content-Length, and must arrive within ten seconds. A workspace busy with other work, such as a large import, answers 503 with a Retry-After; send the same request again.

Scopes

ScopeCoversAccessWhat it allows
vendors:readVendors & RenewalsReadSubscriptions, their owners, spend, seats, renewal dates and notice periods.
approvals:readRequests & ApprovalsReadPurchase requests, their approvers and the decisions taken on them.
systems:readSystems & AccessReadBusiness systems, their owners and access-review dates.
learning:readLearning & ComplianceReadAssignments: who was given which content, and their progress, score and completion.
handovers:readHandover & ContinuityReadHoliday, shift and role handovers: who handed over to whom, when, and their status.
transitions:readEmployee TransitionsReadJoiner and leaver checklists: who each is for, who coordinates it, its dates and status.
assets:readAssets & MaintenanceReadEquipment, who holds it now, and its warranty and maintenance dates.
workplace:readWorkplace OperationsReadWorkplace records and the people they concern.
people:readPeopleReadThe employee directory: names, work contact details, roles and teams.
locations:readLocationsReadSites, departments and teams.
tasks:readTasksReadThe shared task list: work generated by handovers and learning assignments, and work people have written by hand.
kpi:readKPI ScorecardsReadKPI definitions, targets and owners, and each closed period's recorded result.
kpi:recordRecord KPI resultsWriteRecord or correct a closed period's result for any active KPI. Write only: reading needs kpi:read as well.

The machine-readable contract

/api/v1/openapi.json describes this surface as OpenAPI, and is generated from the same routes. Use it to build a client rather than typing one out.

It describes /api/v1 only. kitset's own browser client talks to other endpoints; those are internal, they change without notice, and they are not part of this contract.