events

17 endpoints.

GET/api/events/mine Bearer token

List the caller's own events

Every unarchived event the caller is on — as a participant, a trainer, or both — in calendar order (unscheduled events last), each with their own attendance where they are a participant. Needs no permission grant: being on the event is the authorization. Cancelled events are included, flagged by cancelled_at.

Parameters

NameInTypeRequiredDescription
fromquerystring (date-time)noOnly events ending at or after this instant; unscheduled events are always included.
toquerystring (date-time)noOnly events starting before this instant (unscheduled events included).

Responses

StatusDescriptionBody
200The caller's events.MyTrainingEventList
401The access token is missing or invalid.ErrorResponse
500The database could not be read.ErrorResponse
POST/api/events/batch Bearer token

Create a series of training events

Creates one event per window given, all owned by the same organization (or owning department within it), with the same title, venue, credit and subject tags — a recurring session scheduled for a term in one request. The trainers and participants named are put on every event of the series; each must be a member of the organization. Everything is written in one transaction, so a series is never half-created. Requires events:write over the owner. Answers the created events in calendar order.

Request body

application/jsonrequiredCreateTrainingEventBatchRequest
FieldTypeRequiredDescription
orgstringyes

Organization UUID id or slug the event belongs to.

at least 1 character

departmentstringno

UUID id or slug of the owning department within the organization; omit for an event owned by the organization directly.

at least 1 character

titlestringyes

1–200 characters

description_markdownstringno

Omit or send empty for no description.

at most 50000 characters

meeting_urlstring (uri)no

Video meeting link, for remote or hybrid sessions.

at most 2000 characters

locationstringno

Free-text venue, for in-person sessions.

1–500 characters

credit_hoursnumberno

Hours an attendance credits toward subject-hours rules. Omit to credit the event's wall-clock duration instead.

maximum 10000

subject_matter_idsarray of string (uuid)no

Subjects the event (and every attendance record it produces) is filed under. Subjects of the event's own organization only.

at most 50 items

windowsarray of TrainingEventWindowyes

One event is created per window, all sharing the fields above. A client scheduling weekly slots expands them into windows before sending.

1–200 items

trainer_user_idsarray of string (uuid)no

`users.id` of members of the organization to schedule as trainers of every event in the series.

at most 50 items

participant_user_idsarray of string (uuid)no

`users.id` of members of the organization to put on every event's roster as `registered`.

at most 200 items

Responses

StatusDescriptionBody
201The created events, earliest first.TrainingEventList
400The request body failed validation, or a named trainer or participant is not a member of the organization.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the intended owner.ErrorResponse
404No visible organization has that id or slug, or the department or a subject matter is not the organization's own.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
POST/api/events/conflicts Bearer token

Check for scheduling conflicts

Says who among the given people is already on another live training event — as a participant or a trainer — during any of the given windows, so a double booking is seen before it is made. Cancelled, archived and unscheduled events never clash. Writes nothing: it is a POST only because the people and windows do not fit a query string. Requires events:write somewhere, since it serves the scheduling forms; the clash itself is reported wherever the other event lives, but that event's id and title are given only when the caller's events:read scope covers it.

Request body

application/jsonrequiredCheckSchedulingConflictsRequest
FieldTypeRequiredDescription
user_idsarray of string (uuid)yes

`users.id` of the people about to be scheduled.

1–250 items

windowsarray of TrainingEventWindowyes

The windows they would be scheduled in — one for a single event, one per event for a series. Conflicts name the window by its index in this array.

1–200 items

exclude_event_idstring (uuid)no

An event to leave out of the check: the one being edited, whose own roster would otherwise conflict with itself.

Responses

StatusDescriptionBody
200The clashes found, by window then by the other event's start; empty when none.SchedulingConflictList
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller holds events:write nowhere.ErrorResponse
500The database could not be read.ErrorResponse
GET/api/events Bearer token

List training events

Lists the training events the caller's events:read scope covers, in calendar order (unscheduled events last), optionally filtered to one organization or one owning department within it, and to a time window. Archived events are left out unless asked for; cancelled ones are listed with their cancelled_at set. The events one is on as a participant or trainer are listed by GET /events/mine instead.

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.
fromquerystring (date-time)noOnly events ending at or after this instant. Unscheduled events (no time yet) are always included.
toquerystring (date-time)noOnly events starting before this instant (unscheduled events included).

Responses

StatusDescriptionBody
200The visible events.TrainingEventList
400The department filter was given without an org filter.ErrorResponse
401The access token is missing or invalid.ErrorResponse
404No visible organization has that id or slug, or the department is not one of the organization's own.ErrorResponse
500The database could not be read.ErrorResponse
POST/api/events Bearer token

Create a training event

Creates an event owned by the organization, or by the owning department named within it, tagged with the given subjects. Requires events:write over that owner. Give starts_at and ends_at to schedule it, or neither for an event whose time is not yet known: it is listed as unscheduled, and attendance cannot be marked until it is given a window. Trainers and participants are added afterwards through the event's own routes.

Request body

application/jsonrequiredCreateTrainingEventRequest
FieldTypeRequiredDescription
orgstringyes

Organization UUID id or slug the event belongs to.

at least 1 character

departmentstringno

UUID id or slug of the owning department within the organization; omit for an event owned by the organization directly.

at least 1 character

titlestringyes

1–200 characters

description_markdownstringno

Omit or send empty for no description.

at most 50000 characters

meeting_urlstring (uri)no

Video meeting link, for remote or hybrid sessions.

at most 2000 characters

locationstringno

Free-text venue, for in-person sessions.

1–500 characters

credit_hoursnumberno

Hours an attendance credits toward subject-hours rules. Omit to credit the event's wall-clock duration instead.

maximum 10000

subject_matter_idsarray of string (uuid)no

Subjects the event (and every attendance record it produces) is filed under. Subjects of the event's own organization only.

at most 50 items

starts_atstring (date-time)no

When the event starts. Omit both starts_at and ends_at for an event whose time is not yet known; it is listed as unscheduled until PATCHed with a window.

ends_atstring (date-time)no

When the event ends; required exactly when starts_at is given.

Responses

StatusDescriptionBody
201The created event.TrainingEvent
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the intended owner.ErrorResponse
404No visible organization has that id or slug, or the department or a subject matter is not the organization's own.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/events/{event_id}/permanent-deletion Bearer token

Preview permanently deleting an event

Counts everything DELETE on this path would remove: the learning records attendance marks wrote (and the hours they credited), the roster and the trainers. Nothing is changed. Requires events:delete over the event's owner — a grant separate from events:write, which only archives.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Responses

StatusDescriptionBody
200What the deletion would take with it.DeletionImpact
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:delete over the event's owner.ErrorResponse
404No visible event has that id.ErrorResponse
500The database could not be read.ErrorResponse
DELETE/api/events/{event_id}/permanent-deletion Bearer token

Permanently delete an event

Hard-deletes the event — unlike archiving (hides it) or cancelling (archives its records). The roster, trainers and subject tags go, and so do the learning records attendance marks produced, with their evidence: the hours they credited toward certification requirements disappear. Irreversible. Preview the cost with GET first. Requires events:delete over the event's owner — a grant separate from events:write, which only archives.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Responses

StatusDescriptionBody
204The event, its roster and its attendance records are gone.—
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:delete over the event's owner.ErrorResponse
404No visible event has that id.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
POST/api/events/{event_id}/duplicate Bearer token

Duplicate a training event

Creates a copy of an event — the next session of a recurring one — with the same owner, description, venue, meeting link, credit hours, subject tags and trainers. Participants, attendance and the learning records attendance wrote stay with the original, and the copy is neither cancelled nor archived. Give starts_at and ends_at to schedule the copy, or neither for an unscheduled one; the title is the original's unless given. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Request body

application/jsonoptionalDuplicateTrainingEventRequest
FieldTypeRequiredDescription
titlestringno

The copy's title; omit to keep the original's.

1–200 characters

starts_atstring (date-time)no

When the copy starts. Omit both starts_at and ends_at for an unscheduled copy, whose time is set later by PATCH /events/{event_id}.

ends_atstring (date-time)no

When the copy ends; required exactly when starts_at is given.

Responses

StatusDescriptionBody
201The copy.TrainingEvent
400The request body failed validation, or the window is half set or out of order.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller can see the event but does not hold events:write over its owner.ErrorResponse
404No visible event has that id.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/events/{event_id} Bearer token

Read one training event

Reads one event with its subject tags, trainers and participant roster (with attendance). Requires events:read over the event's owner — or being on the event as a participant or trainer.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Responses

StatusDescriptionBody
200The event.TrainingEventDetail
401The access token is missing or invalid.ErrorResponse
404No visible event has that id.ErrorResponse
500The database could not be read.ErrorResponse
PATCH/api/events/{event_id} Bearer token

Edit, cancel or archive an event

Changes an event's title, description, times (set both to schedule an unscheduled event, null both to unschedule it), meeting link, location or credit hours; cancels it (final — attendance can no longer be marked, and the learning records earlier attendance marks produced are archived); or archives/restores it. Edits never touch records already written for attendance. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Request body

application/jsonrequiredUpdateTrainingEventRequest
FieldTypeRequiredDescription
titlestringno

1–200 characters

description_markdownstring | nullno

Send null (or empty) to clear the description.

at most 50000 characters

starts_atstring (date-time) | nullno

Send both halves to (re)schedule the event, or null on both to make it unscheduled again. An omitted half keeps its stored value; the result must still be both or neither.

ends_atstring (date-time) | nullno

Send null on both halves to clear the window.

meeting_urlstring (uri) | nullno

Send null to clear.

at most 2000 characters

locationstring | nullno

Send null to clear.

1–500 characters

credit_hoursnumber | nullno

Send null to credit the wall-clock duration again.

maximum 10000

cancelledbooleanno

Cancels the event. Final: attendance can no longer be marked, and the learning records earlier attendance marks produced are archived.

one of true

archivedbooleanno

True hides the event from listings; false restores it.

Responses

StatusDescriptionBody
200The updated event.TrainingEvent
400The request body failed validation, or the new window is out of order or half set.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id.ErrorResponse
409The event is already cancelled.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
PUT/api/events/{event_id}/subjects Bearer token

Replace an event's subject tags

Sets the complete set of subjects the event — and every attendance record it produces from now on — is filed under. Records already written keep their tags. Subjects of the event's own organization only. Requires events:write over the owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Request body

application/jsonrequiredSetTrainingEventSubjectsRequest
FieldTypeRequiredDescription
subject_matter_idsarray of string (uuid)yes

The complete set of subject tags; an empty array clears them.

at most 50 items

Responses

StatusDescriptionBody
200The event's subjects after the change.array of TrainingEventSubject
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id, or a subject is not the organization's own.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/events/{event_id}/participants Bearer token

List an event's participants

The roster with each participant's attendance and, for attendees, the learning record their attendance wrote. Same visibility as reading the event.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Responses

StatusDescriptionBody
200The roster.TrainingEventParticipantList
401The access token is missing or invalid.ErrorResponse
404No visible event has that id.ErrorResponse
500The database could not be read.ErrorResponse
POST/api/events/{event_id}/participants Bearer token

Add a participant

Puts a member of the event's organization on the roster as `registered`. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Request body

application/jsonrequiredAddTrainingEventPersonRequest
FieldTypeRequiredDescription
user_idstring (uuid)yes

`users.id` of a member of the event's organization.

Responses

StatusDescriptionBody
201The new roster row.TrainingEventParticipant
400The request body failed validation, or the user is not an organization member.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id.ErrorResponse
409That user is already on the roster.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
DELETE/api/events/{event_id}/participants/{user_id} Bearer token

Remove a participant

Takes a person off the roster. If their attendance had been marked, the learning record it wrote is archived — off the roster means off the count. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.
user_idpathstring (uuid)yes`users.id` of the person on the event.

Responses

StatusDescriptionBody
204Removed.—
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id, or the user is not on its roster.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
PUT/api/events/{event_id}/participants/{user_id}/attendance Bearer token

Mark a participant's attendance

Sets one participant's attendance once the event has started. `attended` writes a completed learning record for them — titled and owned like the event, filed under its subjects, with one evidence row worth its credit hours (or its duration) — which the subject-hours rules count immediately. Any other mark archives the record an earlier `attended` wrote. A cancelled or archived event, or one that has not started, takes no marks. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.
user_idpathstring (uuid)yes`users.id` of the person on the event.

Request body

application/jsonrequiredSetTrainingEventAttendanceRequest
FieldTypeRequiredDescription
attendancestringyes

registered: on the roster. attended: was there — a completed learning record was written for them. absent: was not there.

one of "registered" | "attended" | "absent"

Responses

StatusDescriptionBody
200The roster row after the mark.TrainingEventParticipant
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id, or the user is not on its roster.ErrorResponse
409The event has not started, or is cancelled or archived.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
POST/api/events/{event_id}/trainers Bearer token

Schedule a trainer

Names a member of the event's organization as one of its trainers. Informational: being scheduled grants no permission over the event, though trainers can always read it. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.

Request body

application/jsonrequiredAddTrainingEventPersonRequest
FieldTypeRequiredDescription
user_idstring (uuid)yes

`users.id` of a member of the event's organization.

Responses

StatusDescriptionBody
200The event's trainers after the change.array of TrainingEventTrainer
400The request body failed validation, or the user is not an organization member.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id.ErrorResponse
409That user is already a trainer of the event.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
DELETE/api/events/{event_id}/trainers/{user_id} Bearer token

Unschedule a trainer

Removes a trainer from the event. Requires events:write over the event's owner.

Parameters

NameInTypeRequiredDescription
event_idpathstring (uuid)yesUUID id of the training event.
user_idpathstring (uuid)yes`users.id` of the person on the event.

Responses

StatusDescriptionBody
204Removed.—
401The access token is missing or invalid.ErrorResponse
403The caller does not hold events:write over the event's owner.ErrorResponse
404No visible event has that id, or the user is not one of its trainers.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse