# Course versions referenced by employee records

`GET https://api.kapiworks.com/v1/courses`

The 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.

Scope: `training:read`.

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | string | No | Opaque next_cursor from the previous page. Send it unchanged to the same endpoint. It pins the snapshot and filters, and grants no access. |
| `limit` | integer | No | 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. |

## Responses

| Status | Description |
| --- | --- |
| 200 | One page from a pinned company snapshot. |
| 400 | RFC 9457 problem details. Codes: invalid_request, invalid_cursor, key_in_url. Act on `code` or `type`; never parse `detail`. |
| 401 | RFC 9457 problem details. Codes: invalid_token. Act on `code` or `type`; never parse `detail`. |
| 403 | RFC 9457 problem details. Codes: insufficient_scope, ip_not_allowed. Act on `code` or `type`; never parse `detail`. |
| 404 | RFC 9457 problem details. Codes: not_found. Act on `code` or `type`; never parse `detail`. |
| 405 | RFC 9457 problem details. Codes: method_not_allowed. Act on `code` or `type`; never parse `detail`. |
| 422 | RFC 9457 problem details. Codes: before_history, record_too_large. Act on `code` or `type`; never parse `detail`. |
| 429 | RFC 9457 problem details. Codes: rate_limited, concurrent_limit. Act on `code` or `type`; never parse `detail`. |
| 502 | RFC 9457 problem details. Codes: read_failed. Act on `code` or `type`; never parse `detail`. |
| 503 | RFC 9457 problem details. Codes: unavailable, upstream_unavailable, writer_unavailable. Act on `code` or `type`; never parse `detail`. |
| 504 | RFC 9457 problem details. Codes: read_timeout. Act on `code` or `type`; never parse `detail`. |

## Fields of each row

| Field | Type | Meaning |
| --- | --- | --- |
| `row_id` | string (uuid) | Stable course release row UUID. |
| `course_id` | string (uuid) | Course UUID. |
| `course_release_id` | string or null (uuid) | Immutable published course version UUID. |
| `course_title` | string or null | Title from the current source course. |
| `version` | integer or null | Published version number. |
| `published_at` | string or null (date-time) | Time the release was sealed. |
| `publisher_id` | string or null (uuid) | Publisher UUID. |
| `content_sha256` | string or null | Immutable course content fingerprint. |
| `contents_sha256` | string or null | Fingerprint of the list of contained releases. |
| `source_kind` | string | course_release, release_unavailable or lesson_share_without_course_release. |
| `lessons` | array of object | JSON array of lesson release IDs, current source titles, versions and content SHA-256 values. |

## Example response

```json
{
  "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
}
```

The full contract, with every schema, is at https://api.kapiworks.com/v1/openapi.json.