Aliases: course schema, course json, course structure json, module topic section schema

Course Schema

The course is a JSON structure: Course → Modules → Topics → Sections. This document describes the schema at each level — from the top-level course object down to format-specific section variants. The nested outline subtree is also documented separately in Outline Schema.


Course

The top-level object representing a complete course.

FieldTypeDescription
idnumberCourse identifier
titlestring (max 255)Original course title
localized_titlestring?Localized course title (set during localization)
languagestringTarget language code (default: en)
outlineModule[]Array of modules (min 1). See Outline Schema.
thumbnailobjectCover image: { content_type, base64 }
objectivesstring?Learner-facing learning objectives (HTML)
descriptionstring?Learner-facing course description
quizQuizQuestion[]?Post-course assessment (10–20 questions)
course_group_idUUID?Groups localized copies of the same course
versionnumberSchema version (default: 1)

Module

FieldTypeDescription
titlestring (max 255)Module title
localized_titlestring?Localized module title
summarystringModule summary
positionstringPosition identifier (e.g., "1")
topicsTopic[]Array of topics (min 1)

Topic

FieldTypeDescription
titlestring (max 255)Topic title
localized_titlestring?Localized topic title
positionstringPosition identifier (e.g., "1.1")
blueprintstringTopic-level blueprint — what this topic covers
sectionsSection[]Array of sections (min 1)

Structural invariants

Beyond the base JSON shape, the outline follows these planning invariants:

  • Except for the fixed "Welcome to the training" topic at 1.1, every non-final topic in a module ends with a Whats_Next section.
  • The final topic of every non-last module ends with a Key_takeaways section and does not include Whats_Next.
  • The final topic of the whole course ends with Learning_Outcomes followed by Reference_List and does not include Whats_Next or Key_takeaways.

Section (base)

Every section shares these fields regardless of format:

FieldTypeDescription
section_typestringSemantic type — what the section does. See Section types
formatSectionFormatPresentation format — how it is delivered. See Section formats
titlestring (max 255)Section title
section_titlestring? (max 255)Localized section title (set during localization)
positionstringPosition identifier (e.g., "1.1.3")
blueprintstringContent blueprint — the prompt for generation

The blueprint is the bridge between planning and production: it tells the generator what to produce for this section, while section_type and format tell it how to frame and how to present the result.


Format-specific fields

The format field determines which additional fields the section carries. The schema is a discriminated union on format.

Text formats

Text — plain HTML content:

FieldType
contentstring (HTML, no markdown)

VideoPresentation / VideoTalkingHead / VideoScenario — video with script:

FieldType
contentstring (voiceover script)
video_data{ platform, video_id }

Text + Image formats

TextWithPhoto / TextWithIllustration / TextWithPortrait / TextWithDiagram:

FieldType
contentstring (HTML, no markdown)
content_renderedstring (HTML with image embedded)
image_data{ prompt?, url }

Assessment formats

ChoiceQuestions — single or multiple choice:

FieldType
questionsQuizQuestion[] (min 1)

Where each question is either:

  • SingleChoiceQuestion: { type, question, possible_answers: [{ text, correct, feedback_text }] }
  • MultiChoiceQuestion: { type, question, possible_answers: [{ text, correct }], correct_feedback_text, incorrect_feedback_text }

FillTheBlanks — cloze exercise:

FieldType
contentstring (HTML with [PLACEHOLDER_INPUT] or [PLACEHOLDER_DROPDOWN] markers)
correct_feedback_textstring
incorrect_feedback_textstring
placeholders[{ index, type: 'dropdown' | 'input', options: [{ text, correct }] }]

QuestionWithFeedback — open-ended with LLM evaluation:

FieldType
contentstring (HTML)
question_data{ criteria, question }

Artifact — interactive exercise:

FieldType
contentstring (HTML)
artifact_data{ path }

Available formats

Text  VideoPresentation  VideoTalkingHead  VideoScenario
TextWithPhoto  TextWithIllustration  TextWithPortrait  TextWithDiagram
ChoiceQuestions  FillTheBlanks  QuestionWithFeedback  Artifact
SingleChoiceQuestion  MultiChoiceQuestion  Question

For what each format means and when to use it, see Section formats. For what each section type means semantically, see Section types.


Validation

The schema is enforced at runtime with Zod. The discriminated union on format ensures that format-specific fields are present and correctly typed. Key rules:

  • All content fields in text-based sections must not contain markdown (** is rejected)
  • Quiz questions are limited to 255 characters
  • FillTheBlanks content must include at least one [PLACEHOLDER_INPUT] or [PLACEHOLDER_DROPDOWN]
  • Image URLs must be valid URLs
  • All position fields are required strings (e.g., "1.2.3")