Skip to main content
Manage chapters inside a training: list, create, reorder, show, update, and permanently delete. Chapters carry lessons and any number of chapter quizzes (since 19/10/2026). Quizzes are created and edited through the Quizzes & Exams endpoints with a chapter_id. All endpoints are authenticated — they run behind auth:sanctum, the “user is not blocked” check, and the per-company policy middleware. Always send your Sanctum token as a Bearer header.

Table of contents

  • Base URL & Headers
  • Chapter quizzes in the payload
  • List chapters
  • Reorder chapters
  • Create a chapter
  • Retrieve a chapter
  • Update a chapter
  • Permanently delete a chapter
  • Postman setup

Base URL & Headers

Dates are returned in Y-m-d H:i:s format. Boolean query params accept true, false, 1, 0.
Chapter position is 1-based and unique per training. A new chapter is not auto-positioned — you must send the position you want.

Chapter quizzes in the payload

Since 19/10/2026 a chapter can hold any number of quizzes (before, adding a second quiz turned the first one into an exam). Every chapter object returned by GET /chapters and GET /chapter/{id} therefore carries two keys: Who sees what:
  • Students only get the published chapter quizzes (is_published = 1), in both keys.
  • Staff (instructor, content manager, admin, super admin) also get the drafts, so editors can list them. Check each quiz’s is_published.
Each quiz is a full Quiz row: training_id is null for a chapter quiz (it is found through chapter_id), it carries its slug, its instructor and the computed rating / sales fields. The same two keys appear in the chapters of GET /training/{id}, the login payload (GET /auth/user) and the chapter exports.
⚠️ Like GET /training/{id}, these endpoints return each quiz’s options with their is_correct flags and explanation texts. Use them for the course player of an owned training and for the editors, never for the marketplace.

List chapters

GET /chapters Returns a paginated list of chapters for a given training. Each chapter always includes its quizzes (plus the deprecated quiz, see Chapter quizzes in the payload), each with its question tree (questions → options → option items). Lessons are included only when you ask for them.

Query parameters

Example request

Example response — 200 OK

Called by an instructor: chapter 40 has a published quiz and a draft, chapter 41 has no lessons but still returns its quiz. A student would not see quiz 78 (draft).
A chapter without any quiz returns "quizzes": [] and "quiz": null.

Reorder chapters

POST /chapters/reorder Bulk-updates the position of multiple chapters in a single call. The request body is a bare array — not an object.

Body

An array of { id, position } pairs.

Example request

Response — 200 OK


Create a chapter

POST /chapter

Body parameters

Example request

Response — 200 OK


Retrieve a chapter

GET /chapter/{id} Returns a single chapter with all its quizzes (quizzes, creation order) and their question trees (questions → options → option items), plus the deprecated quiz (= the first one). Students only get the published quizzes; staff also get the drafts — see Chapter quizzes in the payload. Lessons are not included in this endpoint — use GET /lessons?chapter_id={id} to list them.
Before 19/10/2026 this endpoint returned the chapter’s single quiz whatever its publish state, so a student could receive a draft quiz here while GET /training/{id} (published only) did not show it.

Example request

Response — 200 OK

Called by a student: the draft quiz 78 of chapter 40 is not listed.

Unknown id — 500

The controller catches the “not found” exception in its generic handler, so an unknown id answers 500 (not 404) with the model message:

Update a chapter

POST /chapter/{id} Updates an existing chapter. The chapter must belong to the training_id supplied in the body — otherwise 404 is returned.

Body parameters

Example request

Response — 200 OK


Permanently delete a chapter

DELETE /chapter/{id}/hard_delete Force-deletes the chapter and all its lessons. This is irreversible. The quizzes.chapter_id foreign key cascades on delete, so every quiz of the chapter is removed by the database too (there can be several since 19/10/2026), together with their questions and the students’ attempts on them (those foreign keys cascade as well).
⚠️ This endpoint does not soft-delete — both the chapter and every lesson it contains are removed from the database immediately. If you need a recoverable operation, archive upstream (e.g. the training) instead.

Example request

Response — 200 OK


Postman setup

  1. Environment variables.
    • base_url — your API root, e.g. http://localhost:8000
    • token — the Sanctum token returned by POST /auth/login
  2. Collection-level headers.
    • Accept: application/json
    • Authorization: Bearer {{token}}
  3. Request bodies.
    • JSON bodies → Body → raw → JSON
    • For Reorder, remember the body is a bare JSON array, not an object wrapped in a key.
  4. Smoke-test flow.
    1. POST /chapter — create
    2. GET /chapters?training_id={id} — verify it appears
    3. POST /chapter/{id} — update
    4. POST /chapters/reorder — reorder with peers
    5. GET /chapter/{id} — confirm
    6. DELETE /chapter/{id}/hard_delete — cleanup