Course versions referenced by employee records
/v1/coursesThe published course versions behind employee training records, with their content fingerprints. Requires training:read. Names, work emails and certificate check codes also need people:read; without it they are left out.
Authorization
bearerAuth training:readA company API key, not an OAuth access token: kw_live_ in production, kw_test_ elsewhere. Send it only in the Authorization header. A key sent in a URL is revoked.
In: header
Scope: training:read
Query Parameters
Opaque next_cursor from the previous page. Send it unchanged to the same endpoint. It pins the snapshot and filters, and grants no access.
Rows per page, 1 to 200. Larger values are treated as 200. A page can hold fewer rows to stay within 3 MiB, so follow next_cursor until it is null.
1 <= value200Response Body
application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
# Supply the key from your server's secret manager. Do not log it.# curl reads the header from stdin, keeping the key out of its arguments.printf 'header = "Authorization: Bearer %s"\n' "$KAPI_WORKS_API_KEY" | curl --config - --silent --show-error --fail-with-body \ 'https://example.com/v1/courses'{ "data": [ { "row_id": "e5c2a9d7-4b3f-4c18-9a6e-2f1d0c9b8a77", "course_id": "d2f8b4a6-7c1e-4e93-b5a0-3c9e8f7d6a21", "course_release_id": "e5c2a9d7-4b3f-4c18-9a6e-2f1d0c9b8a77", "course_title": "Information security essentials", "version": 3, "published_at": "2026-08-20T16:30:00Z", "publisher_id": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c21", "content_sha256": "8d2f6a0c4e9b1d3f5a7c9e2b4d6f8a0c1e3b5d7f9a2c4e6b8d0f1a3c5e7b9d2f", "contents_sha256": "1a3c5e7b9d2f4a6c8e0b2d4f6a8c0e2b4d6f8a1c3e5b7d9f0a2c4e6b8d1f3a5c", "source_kind": "course_release", "lessons": [ { "release_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b10", "title": "Spotting a phishing email", "version": 2, "content_sha256": "6c8e0b2d4f6a8c0e2b4d6f8a1c3e5b7d9f0a2c4e6b8d1f3a5c7e9b2d4f6a8c0e" } ] } ], "total": 1, "snapshot": { "organization_id": "4f6b2a52-1c1e-4f7a-9d3e-2b7c8a9e0d11", "deployment_id": "00000000-0000-4000-8000-000000000001", "as_at": "2026-10-09T09:00:00Z", "from": null, "known_at": "2026-10-09T08:59:41Z", "sequence": 1284, "capture_sequence": 352, "chain_hash": "3f9a1c7e5b2d8f4a6c0e9b1d3f5a7c9e2b4d6f8a0c1e3b5d7f9a2c4e6b8d0f1a", "logic": { "version": 4, "date": "2026-10-06" }, "history_complete_from": "2026-10-06T05:00:00Z", "available": true }, "next_cursor": null}Employees and invitations during a period
Employees and invitation records that existed between `from` and `to`. Requires `people:read`. Names, work emails and certificate check codes also need `people:read`; without it they are left out.
Check whether anything changed
Returns the company's latest snapshot in one call, with any scope. If `sequence` and `capture_sequence` match your last complete pull, no recorded facts have changed since. Outcomes that depend on the clock, such as `not_due_yet` becoming `overdue`, can still change, so recompute them from `due_at` or pull again at least daily.