# Certificates at a moment

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

Employee certificates issued by `as_at`, with their state then. Requires `certificates:read`. Names, work emails and certificate check codes also need `people:read`; without it they are left out.

Scope: `certificates:read`.

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `as_at` | string (date-time) or string (date) | No | RFC 3339 instant with an offset, or a date read as the end of the company's day. Defaults to now. |
| `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 |
| --- | --- | --- |
| `deployment_id` | string (uuid) | Kapi deployment UUID. |
| `organization_id` | string (uuid) | Company UUID; the tenant boundary. |
| `learning_space_id` | string (uuid) | Learning-space UUID. |
| `certificate_id` | string (uuid) | Certificate UUID. |
| `learner_profile_id` | string (uuid) | Employee profile UUID; retained after erasure. |
| `person_name` | string or null | Name from its current source row. Erased person once Kapi erased the person at the company’s instruction. Certificate names are the issued subject name until then. |
| `course_id` | string (uuid) | Course UUID. |
| `course_release_id` | string or null (uuid) | Immutable published course version UUID. |
| `course_release_version` | integer or null | Published course version number. |
| `certificate_title` | string | Title recorded on the certificate edition. |
| `kind` | string | completion or assessed. |
| `earned_at` | string (date-time) | Completion or assessment time. |
| `issued_at` | string (date-time) | Certificate issue time. |
| `valid_until` | string or null (date-time) | Fixed expiry instant; null means no expiry. |
| `status` | string | Certificate state at the requested moment: valid, expired, revoked or replaced. |
| `changed_at` | string or null (date-time) | Revocation/replacement time, when known at this snapshot. |
| `changed_by` | string or null (uuid) | Actor UUID for revocation/replacement. |
| `supersedes_id` | string or null (uuid) | Earlier certificate corrected by this certificate. |
| `renews_id` | string or null (uuid) | Earlier certificate renewed by this certificate. |
| `check_code` | string | Certificate check code. Returned only with people:read because it opens the public check page, which shows the holder's name. The check page shows nothing once the holder is erased. |
| `live_session_id` | string or null (uuid) | Live session UUID when the person finished the course by attending a live session in full; null otherwise. |
| `live_session_format` | string or null | online or on_site. |
| `live_session_starts_at` | string or null (date-time) | When the live session started. |
| `live_session_ends_at` | string or null (date-time) | When the live session ended. |
| `live_session_minutes` | integer or null | Length of the live session in minutes. |
| `live_session_marked_by` | string or null | Who made the final register mark: trainer, or kapi when Kapi changed it after an ask. |
| `trainer_name` | string or null | Trainer of the live session, from their current Kapi profile; A Kapi expert until they set a name. |

## Example response

```json
{
  "data": [
    {
      "deployment_id": "00000000-0000-4000-8000-000000000001",
      "organization_id": "4f6b2a52-1c1e-4f7a-9d3e-2b7c8a9e0d11",
      "learning_space_id": "8b2d6c3e-5f41-4a8e-9c27-1d0e3f4a5b62",
      "certificate_id": "f1b9d3e5-6a2c-4d70-8b4e-5c3a2f1e0d98",
      "learner_profile_id": "c3a1e7f2-8d64-4b1f-a9e2-6f5d4c3b2a10",
      "person_name": "Amira Okafor",
      "course_id": "d2f8b4a6-7c1e-4e93-b5a0-3c9e8f7d6a21",
      "course_release_id": "e5c2a9d7-4b3f-4c18-9a6e-2f1d0c9b8a77",
      "course_release_version": 3,
      "certificate_title": "Information security essentials",
      "kind": "completion",
      "earned_at": "2026-09-12T13:41:09Z",
      "issued_at": "2026-09-12T13:41:10Z",
      "valid_until": "2027-09-12T13:41:10Z",
      "status": "valid",
      "changed_at": null,
      "changed_by": null,
      "supersedes_id": null,
      "renews_id": null,
      "check_code": "KW7Q4M2X9P",
      "live_session_id": null,
      "live_session_format": null,
      "live_session_starts_at": null,
      "live_session_ends_at": null,
      "live_session_minutes": null,
      "live_session_marked_by": null,
      "trainer_name": null
    }
  ],
  "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.