LearningRecord
A request or response body; the type column links to the schemas it refers to.
LearningRecord
| Field | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | yes | — |
| owner_organization_id | string (uuid) | yes | — |
| owner_department_id | string (uuid) | null | yes | Null when the organization itself owns the record. |
| learner_user_id | string (uuid) | yes | `users.id` of the learner the record is about. |
| learner_display_name | string | null | yes | Snapshot taken at write time; the IdP is not queryable for it later. |
| learner_email | string | null | yes | — |
| title | string | yes | — |
| description | string | null | yes | — |
| status | string | yes | one of "pending" | "rejected" | "in_progress" | "completed" | "expired" | "revoked" |
| completed_at | string (date-time) | null | yes | — |
| expires_at | string (date-time) | null | yes | — |
| external_id | string | null | yes | Importer-assigned id, unique per owning organization. |
| recorded_by | string (uuid) | null | yes | `users.id` of the writer, which is not always the learner. |
| approved_by | string (uuid) | null | yes | `users.id` of the manager who approved the record out of pending; null otherwise. |
| approved_at | string (date-time) | null | yes | — |
| rejected_by | string (uuid) | null | yes | `users.id` of the manager who rejected the record back to its learner; set exactly while the status is rejected. |
| rejected_at | string (date-time) | null | yes | — |
| rejection_note | string | null | yes | The rejecter's note: what to fix before resubmitting. |
| hidden_from_learner | boolean | yes | True when the learner's own-records read exemption does not apply: only records:read over the owner (or superuser) reads the record, and to the learner without such a grant it does not exist. Never true on a pending or rejected record. |
| subjects | array of RecordSubjectRef | yes | — |
| evidence_count | integer | yes | — |
| hours | number | yes | Hours of evidence the record carries, as an hours rule counts them: quantity evidence in hour or minute units, and the span of date_range evidence. 0 when none of its evidence measures time. |
| archived_at | string (date-time) | null | yes | When set, the record is retired; it stays readable but should not grow. |
| created_at | string (date-time) | yes | — |
{
"id": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"owner_organization_id": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"owner_department_id": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"learner_user_id": "8f14e45f-ceea-467f-a10e-cbb9f6bcaf0f",
"learner_display_name": "string",
"learner_email": "string",
"title": "string",
"description": "string",
"status": "pending",
"completed_at": "2026-01-01T00:00:00.000Z",
"expires_at": "2026-01-01T00:00:00.000Z",
"external_id": "string",
"recorded_by": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"approved_by": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"approved_at": "2026-01-01T00:00:00.000Z",
"rejected_by": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"rejected_at": "2026-01-01T00:00:00.000Z",
"rejection_note": "string",
"hidden_from_learner": true,
"subjects": [
{
"id": "1b671a64-40d5-491e-99b0-da01ff1f3341",
"slug": "string",
"name": "string",
"archived_at": "2026-01-01T00:00:00.000Z"
}
],
"evidence_count": 0,
"hours": 6.5,
"archived_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z"
}