kapi WorksDocs

The five registers

What each register returns, at a moment or over a period, and how dates and the company's time zone work.

The API has five registers of employee evidence, plus a snapshot check. All of them answer GET with JSON.

EndpointReturnsScope
GET /v1/training-recordsTraining records at a momenttraining:read
GET /v1/training-records/periodEvery training record owed during a periodtraining:read
GET /v1/certificatesCertificates at a momentcertificates:read
GET /v1/peopleEmployees and invitations during a periodpeople:read
GET /v1/coursesCourse versions referenced by employee recordstraining:read
GET /v1/snapshotCheck whether anything changedAny

At a moment, or over a period

At a moment. Training records and certificates accept as_at: the register as it stood then. Leave it out to read the register now.

Over a period. Period training records and people need from and to on the first page of a pull. A period is at most 400 days long. Period training lists every record owed at any time in the period, with its outcome at the end of the period or when the record ended. People lists the employees and invitations that existed in the period.

The cursor keeps the dates of the first call, so send from, to and as_at only on the first page.

Training endpoints also accept course, a course UUID, to read one course. Courses list the published course versions that employee records refer to, with their content fingerprints.

Dates and the company's time zone

Prefer RFC 3339 timestamps with an explicit offset, such as 2026-10-09T09:00:00Z. A date on its own is read in the company's time zone: from starts at the beginning of that day, and as_at and to end at the end of it.

Where history starts

Kapi records history from history_complete_from, which every snapshot carries. Earlier records are unavailable, not empty: asking for a moment or period before it answers before_history, with history_complete_from in the body. Use that time as the earliest you ask for.

The response

Every register answers with the same envelope:

  • data: the rows of this page;
  • total: the rows in the whole pull, not just this page;
  • snapshot: the pinned snapshot the pull reads, with the company and deployment it belongs to;
  • next_cursor: send it to get the next page; null when the pull is complete.

Rows hold only the fields the contract publishes. v1 can add fields and new values for open fields such as outcome; ignore fields you do not know, and see Versioning for the rest. The field dictionary explains every field.

On this page