subjects

9 endpoints.

GET/api/subjects Bearer token

List subject matters

Lists the subject matters the caller can read, newest first, with cursor pagination. Requires subjects:read in scope; rows outside the caller's scope are simply absent.

Parameters

NameInTypeRequiredDescription
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).
departmentquerystringnoDepartment UUID id or slug, resolved within org (which is then required).
include_archivedquerystringnoInclude archived rows. Defaults to false.
limitqueryintegernoPage size, 1-200. Defaults to 50.
cursorquerystringnoOpaque cursor from a previous page's next_cursor.

Responses

StatusDescriptionBody
200One page of subject matters, and the cursor for the next.SubjectMatterList
400A filter did not resolve, or the cursor is malformed.ErrorResponse
401The access token is missing or invalid.ErrorResponse
500The database could not be read.ErrorResponse
POST/api/subjects Bearer token

Create a subject matter

Creates a subject matter owned by an organization, or by one department within it, optionally filed beneath broader subjects of the same organization. Requires subjects:write over the owner.

Request body

application/jsonrequiredCreateSubjectMatterRequest
FieldTypeRequiredDescription
owner_organization_idstring (uuid)yes

Organization the subject belongs to. Always required.

owner_department_idstring (uuid)no

Omit for a subject owned by the organization directly.

slugstringyes

Unique within the organization. Slugs are lowercase letters and digits in words separated by single hyphens, like forklift-safety.

1–100 characters · matches ^[a-z0-9]+(-[a-z0-9]+)*$

namestringyes

1–200 characters

descriptionstringno

Omit or send empty for no description.

at most 2000 characters

parent_idsarray of string (uuid)no

Broader subjects of the same organization to file the new one beneath; omit for a top-level subject.

at most 50 items

Responses

StatusDescriptionBody
201The created subject matter.SubjectMatter
400The request body failed validation, or a parent is the subject itself.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold subjects:write over the owner.ErrorResponse
404The organization, the department within it, or a parent subject in it does not exist.ErrorResponse
409The organization already has a subject with that slug.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/subjects/{subject_id}/permanent-deletion Bearer token

Preview permanently deleting a subject matter

Counts everything DELETE on this path would untag or remove: the learning records, events, quizzes, courses and certification types tagged with the subject, the proof rules scoped to it, and its narrower subjects. Nothing is changed. Requires subjects:delete — a grant separate from subjects:write, which only archives.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Responses

StatusDescriptionBody
200What the deletion would take with it.DeletionImpact
401The access token is missing or invalid.ErrorResponse
403The caller can read this subject but does not hold subjects:delete over it.ErrorResponse
404No visible subject matter has that id or slug.ErrorResponse
500The database could not be read.ErrorResponse
DELETE/api/subjects/{subject_id}/permanent-deletion Bearer token

Permanently delete a subject matter

Hard-deletes the subject — unlike DELETE /subjects/{subject_id}, which only archives. Every learning record, event, quiz, SCORM course, external course and certification type loses the tag (the rows themselves stay), so hours and record counts filed under it stop satisfying any certification rule on this subject; proof rules scoped to the subject alone are deleted, and hierarchy edges go. Irreversible. Preview the cost with GET first. Requires subjects:delete — a grant separate from subjects:write, which only archives.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Responses

StatusDescriptionBody
204The subject matter and its tags are gone.—
401The access token is missing or invalid.ErrorResponse
403The caller can read this subject but does not hold subjects:delete over it.ErrorResponse
404No visible subject matter has that id or slug.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/subjects/{subject_id} Bearer token

Get a subject matter

Returns one subject matter, by UUID id or by slug resolved within ?org=. Requires subjects:read over its owner.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Responses

StatusDescriptionBody
200The subject matter.SubjectMatter
401The access token is missing or invalid.ErrorResponse
404No visible subject matter has that id or slug.ErrorResponse
500The database could not be read.ErrorResponse
PATCH/api/subjects/{subject_id} Bearer token

Update a subject matter

Changes a subject matter's slug, name or description. Requires subjects:write.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Request body

application/jsonrequiredUpdateSubjectMatterRequest
FieldTypeRequiredDescription
slugstringno

1–100 characters · matches ^[a-z0-9]+(-[a-z0-9]+)*$

namestringno

1–200 characters

descriptionstring | nullno

Send null to clear the description.

at most 2000 characters

Responses

StatusDescriptionBody
200The updated subject matter.SubjectMatter
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller can read this subject but does not hold subjects:write over it.ErrorResponse
404No visible subject matter has that id or slug.ErrorResponse
409The organization already has a subject with that slug.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
DELETE/api/subjects/{subject_id} Bearer token

Archive a subject matter

Soft-deletes a subject matter by setting archived_at; records filed under it keep their tags. Requires subjects:write.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Responses

StatusDescriptionBody
200The archived subject matter.SubjectMatter
401The access token is missing or invalid.ErrorResponse
403The caller can read this subject but does not hold subjects:write over it.ErrorResponse
404No visible subject matter has that id or slug.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/subjects/{subject_id}/hierarchy Bearer token

Read a subject matter's place in the hierarchy

Returns the subject with the broader subjects it sits beneath (its parents, and every ancestor above them) and the narrower subjects directly beneath it. Requires subjects:read over the subject's owner; the related subjects are named regardless of their own owners.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Responses

StatusDescriptionBody
200The subject and its parents, ancestors and children.SubjectMatterHierarchy
401The access token is missing or invalid.ErrorResponse
404No visible subject matter has that id or slug.ErrorResponse
500The database could not be read.ErrorResponse
PUT/api/subjects/{subject_id}/parents Bearer token

Set a subject matter's parents

Replaces the broader subjects this one sits beneath — "arithmetic" under "mathematics". Parents must belong to the subject's own organization, and the hierarchy stays acyclic: a subject cannot be placed beneath itself or beneath one of its own descendants. Requires subjects:write over the subject's owner.

Parameters

NameInTypeRequiredDescription
subject_idpathstringyesUUID id, or a slug resolved within the organization given by the org query parameter.
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).

Request body

application/jsonrequiredSetSubjectMatterParentsRequest
FieldTypeRequiredDescription
parent_idsarray of string (uuid)yes

Replaces the subject's parents. Each must be a subject of the same organization, and none may be the subject itself or one already beneath it.

at most 50 items

Responses

StatusDescriptionBody
200The subject with its new parents.SubjectMatterHierarchy
400The body failed validation, or a parent is the subject itself or one beneath it.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller can read this subject but does not hold subjects:write over it.ErrorResponse
404No visible subject matter has that id or slug, or a parent is not in its organization.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse