Assigning training
These endpoints decide what people owe: assigning a lesson, requiring a topic or knowledge item of someone, retraining them, excusing them or moving their due date, setting how often a lesson has to be retaken, and sending a pop quiz. The reads that go with them are under Training and Lessons.
They need a token granted the training:assign scope, which is an OAuth path
today. It can be granted by an organization admin or a team admin. The person
behind the token must also be allowed to do the act in Mereon, checked on every
call, so a demotion takes effect on the next one.
Who you can reach
Section titled “Who you can reach”How far a person reaches is the same as in the web app:
| Person | May assign to | May excuse (waive, cancel, move a due date) |
|---|---|---|
| Organization admin | Anyone in the organization | Anyone in the organization |
| Team admin | People on the teams they administer | Nobody |
| Anyone else | Themselves | Nobody |
A request that names someone outside that reach is a 403, and nothing is
changed for anyone named in it. Sending a pop quiz, and setting a lesson’s
retraining policy, have their own rules, described below.
Obligations
Section titled “Obligations”Most of these return an obligation: a person’s requirement to complete a lesson or learn a topic or item, as it stands after the change.
{ "id": "…", "userId": "…", "itemType": "lesson", "itemId": "…", "status": "waived", "required": true, "dueDate": "2026-11-01T14:00:00.000Z", "dueDateOverridden": false, "needsReview": false}| Field | Type | Notes |
|---|---|---|
itemType |
string | lesson, topic or item. |
status |
string | active, completed, cancelled or waived. |
dueDate |
string | null | The due date the person sees, or null when there is none. |
dueDateOverridden |
boolean | true when someone set the due date by hand, over the one it would have. |
needsReview |
boolean | true when what its due date counts from changed (a start date moved, for instance) and someone should confirm the new date. |
To act on someone else’s obligation you need its id: read their obligations
with GET /v1/people/{id}/progress.
Assign a lesson
Section titled “Assign a lesson”POST /v1/lessons/{id}/assignments
Requires a lesson of everyone, of the people on some teams, or of named people. Each person it newly reaches gets an enrollment, a quiz prepared for them, and an email and text telling them.
{ "audience": "users", "userIds": ["…", "…"], "due": { "type": "days", "days": 30 }}| Field | Type | Notes |
|---|---|---|
audience |
string | Required. everyone, teams or users. |
teamIds |
string[] | With teams only. Up to 50, from GET /v1/teams. |
userIds |
string[] | With users only. Up to 500, from GET /v1/people. |
due |
object | Leave out for no deadline. { "type": "date", "date": "2026-11-01T09:00:00-05:00" } for a moment (ISO 8601 with a UTC offset), or { "type": "days", "days": 30 } for a number of days after it is assigned (1 to 3,650). |
{ "lessonId": "…", "title": "Forklift safety", "assigned": [{ "userId": "…", "enrollmentId": "…" }]}People who already had the lesson are left as they were and are not in
assigned, so an empty list is a success that reached nobody new. With
everyone or teams, people who cannot take the lesson are left out quietly;
naming one of them in userIds is a 400. A closed lesson, or one generated
for a single person, cannot be assigned.
Unassign a lesson
Section titled “Unassign a lesson”POST /v1/lessons/{id}/unassign
Takes a lesson back from named people. Their enrollment in progress is removed, with their progress in it, and the requirement is cancelled. An enrollment someone already completed is kept, since it is the record of having done it. To excuse someone while keeping their record, waive or cancel the obligation instead.
{ "userIds": ["…"] }{ "lessonId": "…", "title": "Forklift safety", "removedCount": 1 }Refused with a 400 when none of the people named has the lesson in progress.
Only an organization admin may take back a lesson that is required of someone,
because removing the enrollment cancels the requirement; anyone else gets a
403.
Set a lesson’s retraining policy
Section titled “Set a lesson’s retraining policy”PUT /v1/lessons/{id}/retraining-policy
How often people who completed the lesson have to take it again. It needs permission to edit that lesson, the same as changing it in the web app.
{ "retrainingType": "recurring", "intervalDays": 365, "completionMode": "full_retake"}| Field | Type | Notes |
|---|---|---|
retrainingType |
string | Required. recurring, or none to turn retraining off. |
intervalDays |
integer | With recurring only. Days between retakes, 1 to 3,650. |
completionMode |
string | With recurring only. full_retake to redo the whole lesson, or changed_material for a shorter lesson on what changed since. |
Returns the policy in the shape GET /v1/lessons/{id}/retraining-policy
does. It applies from each person’s next completion, and creates nothing for
people who completed the lesson before. A lesson generated for a single person
cannot have one.
Require a topic or item
Section titled “Require a topic or item”POST /v1/knowledge-obligations
Requires one person to learn a topic or a knowledge item. The level they have
to reach follows from their duty on it, so the person must hold a duty on it,
directly or through a role or team; otherwise it is a 400. If they already owe
it, this merges into the obligation they have.
{ "userId": "…", "itemType": "topic", "itemId": "…", "dueDays": 30, "reason": "New to the warehouse"}| Field | Type | Notes |
|---|---|---|
userId |
string | Required. |
itemType |
string | Required. topic or item. |
itemId |
string | Required. |
dueDays |
integer | Days from now until it is due, 1 to 3,650. Leave out for no deadline. |
reason |
string | Up to 2,000 characters, kept on the obligation. |
Returns the obligation.
Retrain someone
Section titled “Retrain someone”POST /v1/retraining-assignments
Requires one person to take a lesson again within a number of days, and tells them.
{ "userId": "…", "lessonId": "…", "dueDays": 14, "retrainingResetsClock": true, "reason": "Failed the forklift check"}| Field | Type | Notes |
|---|---|---|
userId |
string | Required. |
lessonId |
string | Required. |
dueDays |
integer | Required. 1 to 3,650. |
retrainingResetsClock |
boolean | Required. Whether completing it counts as the person’s next scheduled retake under the lesson’s retraining policy. |
reason |
string | Up to 2,000 characters, kept on the obligation. |
Returns the obligation. A lesson generated for a single person cannot be retrained.
Waive or cancel an obligation
Section titled “Waive or cancel an obligation”POST /v1/obligations/{id}/waive
POST /v1/obligations/{id}/cancel
Waiving excuses a person from something they owe, as a deliberate exception. Cancelling ends a requirement that was assigned by mistake or no longer applies. Both keep the reason on the record, and for a lesson the person is told. Neither can be undone: assigning the same thing again creates a new obligation. Only an organization admin may do either.
{ "reason": "Moving to the front office" }reason is required, up to 2,000 characters. Returns the obligation, now
waived or cancelled. Only an active obligation can be waived or
cancelled.
Set an obligation’s due date
Section titled “Set an obligation’s due date”POST /v1/obligations/{id}/due-date
Sets the due date the person sees by hand, over the one it would have. Later
assignments of the same thing do not move a date set this way. Send null to
take the override off. For a lesson, setting a date tells the person. Only an
organization admin may, and only on an active obligation.
{ "dueDate": "2026-11-08T17:00:00-05:00" }Returns the obligation.
Confirm a recalculated due date
Section titled “Confirm a recalculated due date”POST /v1/obligations/{id}/confirm-review
An obligation has needsReview set when what its due date counts from
changed. This settles it at the date given, or with none, and clears the flag.
It is refused for an obligation that is not flagged. Only an organization admin
may.
{ "resolvedDueDate": "2026-12-01T00:00:00Z" }Leave resolvedDueDate out, or send null, for no due date. Returns the
obligation.
Send a pop quiz
Section titled “Send a pop quiz”POST /v1/pop-quizzes
Sends a short quiz on a video, document or guide. Only an organization admin may send one.
{ "contentId": "…", "audience": "teams", "teamIds": ["…"], "dueDate": "2026-11-01T17:00:00-05:00"}| Field | Type | Notes |
|---|---|---|
contentId |
string | Required. A video, document or guide from GET /v1/content. |
audience |
string | Required. everyone, teams or users, with teamIds or userIds as for assigning a lesson. |
dueDate |
string | Required. ISO 8601 with a UTC offset, in the future. |
difficulty |
string | SIMPLE, MODERATE, CHALLENGING or ADVANCED. Leave out for the organization’s default. The harder levels need a plan that includes them. |
{ "id": "…", "title": "Forklift safety check", "dueDate": "2026-11-01T22:00:00.000Z", "url": "https://mereon.ai/pop-quiz/…"}Questions are written for each person after the call returns, and each is
told by email and text once theirs are ready. Follow it with
GET /v1/pop-quizzes/{id}. Everyone it goes
to must be able to see the content; if someone cannot, it is a 400 and
nothing is sent. If its questions cannot be started, nothing is created and the
call is a 503 with POP_QUIZ_GENERATION_FAILED, which is safe to retry.
Errors
Section titled “Errors”| Status | When |
|---|---|
400 |
The body is invalid, a list does not match audience, nobody can be reached, a person or topic is not in the organization, a person has no duty on the topic or item, the obligation is not in a state that allows the change, or a pop quiz recipient cannot see the content. |
403 |
The token lacks training:assign, the person may not do this act, or a person named is outside their reach. |
404 |
The lesson, obligation or content is not in the organization. |
429 |
Over the rate limit. Retry-After says when to try again. |
503 |
A pop quiz’s questions could not be started. Nothing was created. |
The other routes on this page are limited to 30 calls a minute and 300 an hour per connection. The MCP tools that do the same acts are held to the same numbers, counted per tool.