Skip to content

Training

These endpoints answer “what am I supposed to learn, and how am I doing?” for the person behind the token, and “how is someone doing?” for the people they are allowed to see. The /v1/me/* reads are always the connected user’s own. There is no parameter that names someone else, so a token can never be used to read a colleague’s record through them. Reading someone else’s is a separate endpoint with its own rule, and the rules differ: progress follows who the app lets read a person’s enrollments and obligations, while the learning queue follows the reporting line.

GET /v1/me/obligations

The lessons, topics and items the connected user has been assigned, each with its due date and whether it is overdue.

An obligation is overdue when it is still active and its due date has passed. Cancelled and waived obligations are administrative states and are not returned. The list is not paginated, so nextCursor is always null.

Terminal window
curl "https://api.mereon.ai/v1/me/obligations" \
-H "Authorization: Bearer $MEREON_TOKEN"
{
"data": [
{
"id": "obl_3a7c...",
"itemType": "lesson",
"itemId": "lsn_6e3f...",
"itemName": "Lockout/Tagout basics",
"required": true,
"status": "active",
"dueDate": "2026-10-15T00:00:00.000Z",
"overdue": false,
"url": "https://mereon.ai/lesson/lsn_6e3f.../start",
"createdAt": "2026-09-20T14:30:00.000Z"
}
],
"nextCursor": null
}
Field Type Notes
itemType string lesson, topic or item.
required boolean false when completing it is optional.
status string active or completed.
dueDate string | null null when there is no deadline.

GET /v1/me/enrollments

The lessons the connected user is enrolled in, newest first, each with whether it is finished, the score where one is recorded, and any due date. The id of an enrollment is what quiz results take. Not paginated.

{
"data": [
{
"id": "enr_91d0...",
"itemId": "lsn_6e3f...",
"title": "Lockout/Tagout basics",
"status": "completed",
"completedAt": "2026-09-28T16:02:00.000Z",
"score": 86,
"dueDate": "2026-10-15T00:00:00.000Z",
"url": "https://mereon.ai/lesson/lsn_6e3f.../start",
"enrolledAt": "2026-09-20T14:30:00.000Z"
}
],
"nextCursor": null
}

status is completed or in_progress. itemId is the lesson’s id, which GET /v1/lessons/{id} reads.

GET /v1/me/pop-quizzes

The pop quizzes sent to the connected user, each with the user’s own status and score. It never shows how anyone else did. Not paginated.

{
"data": [
{
"id": "pq_5e20...",
"title": "Lockout check",
"prompt": "A quick check on this week's lockout procedure.",
"dueDate": "2026-10-10T00:00:00.000Z",
"url": "https://mereon.ai/pop-quiz/pq_5e20...",
"status": "not_started",
"completedAt": null,
"score": null
}
],
"nextCursor": null
}

status is not_started, STARTED or COMPLETED.

GET /v1/me/learning-queue

The ranked list of topics the connected user should study next, the same queue as their dashboard. It is limited to content the user can read.

Parameter Type Notes
cursor string Pagination cursor from a previous response.
limit number 1 to 100. Default 50.
{
"data": [
{
"topicId": "top_1f4a...",
"topicName": "Lockout/Tagout",
"type": "NEW",
"priority": "HIGH",
"raciRole": "RESPONSIBLE",
"roleName": "Service Technician",
"dueDate": null,
"overdue": false,
"lessonId": "lsn_6e3f...",
"blocked": false,
"blockingPrerequisiteName": null,
"url": "https://mereon.ai/lesson/lsn_6e3f.../start"
}
],
"nextCursor": "2",
"total": 61
}
Field Type Notes
type string Why it is queued. NEW was never learned, PARTIAL was started but not mastered, RETRAINING was mastered and is due again, DEEPEN raises mastery to what the role expects.
topicId string | null null for an assigned lesson that no topic the user can read backs.
blocked boolean true when an unfinished prerequisite is in the way.
total number Entries in the whole queue, not just this page.

The queue is ranked and recomputed on every request, so an entry can move between pages while you are paging through it.

GET /v1/people/{id}/progress

The lessons a person is enrolled in, with completion and score, and the obligations they have been assigned, with due dates and whether each is overdue, plus a roll-up count. Ids come from people and teams.

The rule is whatever the app applies to those two lists, so the API shows no one anything the app would not.

  • The person themselves can always read their own.
  • An organization admin (owner, admin or billing admin) can read anyone in the organization.

A manager cannot. The app’s own enrollment and obligation lists refuse them for a report, so this does too. A report’s learning queue follows a different rule, which does admit a manager, and is the next section.

Anyone else receives 404, as if the person did not exist, and so does an id that belongs to another organization.

A person who has left the organization is found. The app keeps their record, and an audit asks for exactly the training someone completed before they were offboarded.

{
"user": { "id": "usr_2d9e...", "name": "Ada Admin", "email": "ada@example.com" },
"enrollments": [
{
"id": "enr_91d0...",
"itemId": "lsn_6e3f...",
"title": "Lockout/Tagout basics",
"status": "completed",
"completedAt": "2026-09-28T16:02:00.000Z",
"score": 86,
"dueDate": "2026-10-15T00:00:00.000Z",
"url": "https://mereon.ai/lesson/lsn_6e3f.../start",
"enrolledAt": "2026-09-20T14:30:00.000Z"
}
],
"obligations": [
{
"id": "obl_3a7c...",
"itemType": "lesson",
"itemId": "lsn_6e3f...",
"itemName": "Lockout/Tagout basics",
"required": true,
"status": "completed",
"dueDate": "2026-10-15T00:00:00.000Z",
"overdue": false,
"url": "https://mereon.ai/lesson/lsn_6e3f.../start",
"createdAt": "2026-09-20T14:30:00.000Z"
}
],
"summary": {
"enrollmentCount": 1,
"completedCount": 1,
"obligationCount": 1,
"overdueCount": 0
}
}

The enrollments and obligations entries have the same shape as your own. Enrollment titles and obligation names are not filtered by what the reader could open themselves: a person who may read the progress sees what the person is enrolled in.

GET /v1/people/{id}/learning-queue

The ranked list of topics a person should study next: why each is queued, its priority, any due date and whether it is overdue, whether an unfinished prerequisite blocks it, and a lesson to start from. It is the way to see who is behind. The entries have the same shape as your own queue, and the response also names the person.

This is the rule the app applies to a person’s learning queue.

  • The person themselves can always read their own.
  • An organization admin can read anyone in the organization.
  • A manager can read the people who report to them, directly or any number of levels down.

The reporting line is the manager each person has been given, not the role tree. Two people who share a title are not each other’s managers, and holding a senior role does not make someone a manager of everyone in a junior one.

Anyone else receives 404, as if the person did not exist, and so does an id that belongs to another organization. A person who has left the organization has an empty queue, as in the app.

Topics are limited to what the reader can open, so a manager is not shown the name of a topic they could not read. Lessons assigned to the person are the exception: they are listed by title whether or not the reader could open them, because the app builds those rows from the person’s obligations and does not filter them.

The queue is worked out from scratch on every request, which is far dearer than the other reads, so this route and your own queue are limited to 20 requests a minute.

Parameter Type Notes
cursor string Pagination cursor from a previous response.
limit number 1 to 100. Default 50.
{
"user": { "id": "usr_2d9e...", "name": "Ada Admin", "email": "ada@example.com" },
"data": [
{
"topicId": "top_1f4a...",
"topicName": "Lockout/Tagout",
"type": "NEW",
"priority": "HIGH",
"raciRole": "RESPONSIBLE",
"roleName": "Service Technician",
"dueDate": "2026-09-15T00:00:00.000Z",
"overdue": true,
"lessonId": "lsn_6e3f...",
"blocked": false,
"blockingPrerequisiteName": null,
"url": "https://mereon.ai/lesson/lsn_6e3f.../start"
}
],
"nextCursor": null,
"total": 1
}

GET /v1/enrollments/{id}/quiz-results

The per-question results of the quizzes on one lesson enrollment. For each question you get the answer the learner gave, whether it was right, the correct answer and the explanation, along with the overall score and summary. Ids come from your enrollments.

A learner reads their own results. Anyone else needs the review access the app asks for before it shows an enrollment’s answers, which only owners, admins and billing admins have, and a manager does not. Anyone else receives 404, as if the enrollment did not exist, and so does an enrollment in another organization.

{
"data": [
{
"id": "qz_08be...",
"status": "COMPLETED",
"completedAt": "2026-09-28T16:02:00.000Z",
"score": 86,
"resultsSummary": "Strong on isolation steps; revisit verification.",
"questions": [
{
"number": 1,
"question": "Which valve isolates the line?",
"isCorrect": false,
"score": 0,
"answer": "Downstream",
"correctAnswer": "Upstream",
"explanation": "The upstream valve isolates the line."
}
]
}
],
"nextCursor": null
}

GET /v1/pop-quizzes

The organization’s pop quizzes, newest first, each with who sent it, how many people it went to, and how many have finished. This is where an admin finds the id that a pop quiz takes.

It needs organization-wide access to pop quizzes, which owners, admins and billing admins have. Anyone else receives 403, because the pop quizzes sent to the connected user are their own and this list is about pop quizzes that went to other people.

Parameter Type Notes
sentByMe boolean true for only the pop quizzes the connected user sent.
cursor string Pagination cursor from a previous response.
limit number 1 to 100. Default 50.
{
"data": [
{
"id": "pq_5e20...",
"title": "Lockout check",
"prompt": "A quick check on this week's lockout procedure.",
"dueDate": "2026-10-10T00:00:00.000Z",
"createdAt": "2026-10-01T09:00:00.000Z",
"sentBy": { "id": "usr_2d9e...", "name": "Ada Admin" },
"announcementId": null,
"recipientCount": 12,
"completedCount": 5,
"url": "https://mereon.ai/pop-quiz/pq_5e20..."
}
],
"nextCursor": null
}

sentBy is null when the sender’s account is gone or the system made the pop quiz. A pop quiz that certifies an announcement carries that announcement’s id in announcementId, and the announcement’s pop quiz read says how it went.

GET /v1/pop-quizzes/{id}

One pop quiz with its recipients and how each did: who it went to, whether they finished, and their score, plus how many finished.

An owner, admin or billing admin sees every recipient. A recipient sees the pop quiz they were sent with only their own row, and summary counts the rows shown. Anyone else receives 404.

Ids come from the pop quiz list, which is for admins, and from your pop quizzes, which lists the ones sent to you.

{
"id": "pq_5e20...",
"title": "Lockout check",
"prompt": "A quick check on this week's lockout procedure.",
"dueDate": "2026-10-10T00:00:00.000Z",
"createdAt": "2026-10-01T09:00:00.000Z",
"url": "https://mereon.ai/pop-quiz/pq_5e20...",
"recipients": [
{
"user": { "id": "usr_2d9e...", "name": "Ada Admin", "email": "ada@example.com" },
"status": "COMPLETED",
"completedAt": "2026-10-02T11:15:00.000Z",
"score": 90
}
],
"summary": { "recipientCount": 1, "completedCount": 1 }
}