---
title: "Update a product lesson"
method: PATCH
path: "/api/products/{productId}/lessons/{lessonId}"
tags: ["Product Content"]
---

# Update a product lesson

`PATCH /api/products/{productId}/lessons/{lessonId}`

Updates editable lesson fields. Lesson type and section cannot be changed after creation. Use the same content/media shapes documented on create. SCORM lesson updates are rejected with `not_supported`.

## Path parameters

- `productId` string, required
- `lessonId` string, required

## Request body

- LessonUpdateRequest
  - `title` string
  - `content` union — `text` lessons use `TiptapDocument`; `embed` lessons use `EmbedContent`; `quiz` lessons use `QuizContent`. Media-backed lessons (`video`, `audio`, `pdf`, `file`) use `media` instead of `content`.
    - TiptapDocument — Tiptap/ProseMirror document JSON used by `text` lessons. Supported nodes include `doc`, `paragraph`, `heading` (`level` 1, 2, or 3), `text`, `bulletList`, `orderedList`, `listItem`, `blockquote`, `horizontalRule`, `codeBlock`, `table`, `tableRow`, `tableHeader`, `tableCell`, `image`, and `hardBreak`. Supported marks include `bold`, `italic`, `underline`, `strike`, `code`, `link`, and `highlight`. An `image` node uses `attrs` with `src` (required), `alt` (optional), and `title` (optional).
      - `type` string, required
      - `content` object[], required
    - EmbedContent — Embed content for `embed` lessons. The value can be a supported video URL or iframe/embed code, matching the dashboard Embed lesson field.
      - `value` string, required
    - QuizContent — Quiz content for `quiz` lesson type.
      - `questions` object[], required — List of quiz questions.
        - `text` string, required — Question text.
        - `options` object[], required — Answer options. Exactly one option should have `correctAnswer: true` for single-choice; multiple for multiple-choice.
          - `text` string, required — Option text.
          - `correctAnswer` boolean — Whether this is the correct answer. Stripped from student-facing responses.
      - `requiresPassingGrade` boolean, required — Whether a minimum score is required to pass.
      - `passingGrade` number, required — Score threshold (0–100) when `requiresPassingGrade` is true.
  - `media` LessonMedia — Media object used by `video`, `audio`, `pdf`, and `file` lessons. Use `/api/media/presigned` to upload to MediaLit first, then send the resulting media metadata here.
    - `mediaId` string, required
    - `originalFileName` string
    - `mimeType` string
    - `size` number
    - `access` 'public' | 'private'
    - `file` string — Public file URL when available. Private media may omit this field.
    - `thumbnail` string
    - `caption` string
  - `downloadable` boolean
  - `requiresEnrollment` boolean
  - `published` boolean

## Response `200`

Success.

- Lesson
  - `lessonId` string
  - `title` string
  - `type` 'text' | 'video' | 'audio' | 'pdf' | 'file' | 'embed' | 'quiz'
  - `content` union — `text` lessons use `TiptapDocument`; `embed` lessons use `EmbedContent`; `quiz` lessons use `QuizContent`. Media-backed lessons (`video`, `audio`, `pdf`, `file`) use `media` instead of `content`.
    - TiptapDocument — Tiptap/ProseMirror document JSON used by `text` lessons. Supported nodes include `doc`, `paragraph`, `heading` (`level` 1, 2, or 3), `text`, `bulletList`, `orderedList`, `listItem`, `blockquote`, `horizontalRule`, `codeBlock`, `table`, `tableRow`, `tableHeader`, `tableCell`, `image`, and `hardBreak`. Supported marks include `bold`, `italic`, `underline`, `strike`, `code`, `link`, and `highlight`. An `image` node uses `attrs` with `src` (required), `alt` (optional), and `title` (optional).
      - `type` string, required
      - `content` object[], required
    - EmbedContent — Embed content for `embed` lessons. The value can be a supported video URL or iframe/embed code, matching the dashboard Embed lesson field.
      - `value` string, required
    - QuizContent — Quiz content for `quiz` lesson type.
      - `questions` object[], required — List of quiz questions.
        - `text` string, required — Question text.
        - `options` object[], required — Answer options. Exactly one option should have `correctAnswer: true` for single-choice; multiple for multiple-choice.
          - `text` string, required — Option text.
          - `correctAnswer` boolean — Whether this is the correct answer. Stripped from student-facing responses.
      - `requiresPassingGrade` boolean, required — Whether a minimum score is required to pass.
      - `passingGrade` number, required — Score threshold (0–100) when `requiresPassingGrade` is true.
  - `media` LessonMedia — Media object used by `video`, `audio`, `pdf`, and `file` lessons. Use `/api/media/presigned` to upload to MediaLit first, then send the resulting media metadata here.
    - `mediaId` string, required
    - `originalFileName` string
    - `mimeType` string
    - `size` number
    - `access` 'public' | 'private'
    - `file` string — Public file URL when available. Private media may omit this field.
    - `thumbnail` string
    - `caption` string
  - `downloadable` boolean
  - `courseId` string
  - `groupId` string
  - `requiresEnrollment` boolean
  - `published` boolean

## Other responses

- `422` — SCORM lessons are not supported, or lesson validation failed.

---

[API](https://skmtc.net/codelitdev/apis/courselit-rest-api.md) · [All operations](https://skmtc.net/codelitdev/apis/courselit-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/codelitdev/courselit-rest-api/versions/3b48f60910dc/schema)
