New in Vidext: Tag people with @ in the chat. Read the release notes →
Vidext Docs

The content model

How a built module is stored — the snapshot envelope, typed scenes, the layout union, and the draft and publishable contracts.

A Vidext module is typed, validated data, not opaque media. This page describes the shape Vidext stores and plays. For the product view, start with Scenes and layouts.

No public API returns this

No MCP tool or other public endpoint returns a module's snapshot or scenes. The Operator tools list modules and read sources; a module's content is seen and edited in the Vidext app. This page is background for understanding what a module is made of.

The snapshot envelope

A module's playable content is a module snapshot: a versioned JSON envelope around the module itself. Each built version of a module is one immutable snapshot.

ModuleSnapshot { schemaVersion, createdAt, updatedAt?, createdBy?, useCaseId, language?, narrableContentId? }
└── Module { id, title, description?, built? }
    └── Chapter[] { id, title, description? }
        └── Scene[]
  • language is the language the module's narration was written and spoken in.
  • built is present on a module that Vidext's agents built in the chat: { by: "sandbox", mapper }, where mapper names the version of the build that laid it out.
  • useCaseId is null unless the module was planned with a use case.

Snapshots are validated when read and written. A malformed snapshot is refused, never half-served.

Scenes: a discriminated union

Each scene is:

Scene { id, layoutId, content, audioNarration?, sourceSubsectionLabel?, sourceRefs?, visualConcepts? }

layoutId is the discriminant: it names the kind of scene and selects the schema its content follows. It has seven values:

cover · chapter · beat · quiz · video · interactive · closing

Six of them are the module's structure: its cover, the start of a chapter, a quiz, a video, an interactive scene, and its closing. Every teaching moment is a beat.

Beat

A beat's content is the beat as the build laid it out, plus what it says:

{ title, screen { kind, …elements }, form, segmentsMs?, avatar?, paragraphs }
  • screen.kind says what shape the information has (one claim, a set, ordered steps, a timeline, and so on) and decides which elements the screen holds. Each element carries an id, the short text written for the screen and, when the speech was aligned, at: the milliseconds into the scene's speech at which the voice reaches it. When a long beat is split over several scenes, an element said in an earlier scene is at 0 and one said in a later scene is at 3600000, which this scene never reaches. An element may also carry a description, a line under its text that forms drawing titles alone leave out.
  • form is how that kind is drawn, its look in product terms, and it must be a form that draws the screen's kind. The build chooses and stores it, so a version renders the same everywhere. null means none was chosen, and the player picks one for the kind.
  • segmentsMs? is how long each speech segment ran when the elements were timed, so new speech for the same text (a translation, another voice) moves each element with it.
  • avatar? appears only on a beat drawn with the presenter form: image, a still of the module's presenter, and video, the presenter speaking the scene's narration. The video is rendered after the build, so a player shows the still until it loads. New speech for the same text keeps the still and drops the video.
  • paragraphs are the one to six paragraphs the beat speaks, one audio segment each. They are heard, not shown: what a learner reads on a beat comes from its title and its screen's elements, plus captions when subtitles are on.

A beat names no chapter: a scene's chapter is the one that holds it.

Quiz

A quiz scene holds one to three questions, and speaks each question as one audio segment. Each question has a kind:

  • select: three or four answers, exactly one correct;
  • multi: three or four answers, at least two correct;
  • boolean: true or false.

Each question carries an explanation, and select and multi answers can each carry their own feedback.

Video

A video scene names its src, which must be an https URL, and a title. It may also carry measured: the video's length in seconds, as the build read it, with the file size it was read from.

Interactive

An interactive scene carries a small built program the player runs in the scene: its title, a summary of what it teaches and what the learner does (read to screen readers and given to the learner's AI tutor in place of the code), the kit version it runs on, its strings, the built code, and a sha256 of that code. A module carries the whole program, so a version plays without fetching anything but its kit.

Cover, chapter, and closing

A cover carries the module's title and a spoken description, and may carry a promise shown under the title and points, the learning points listed under it. A chapter scene carries the chapter's title and a spoken line, and a closing an optional spoken line.

Scene-level fields

  • audioNarration? is the generated speech for the scene: ordered segments, each anchored to what it speaks (a beat's paragraph, a quiz's question), with its audio URL, duration, and subtitle cues.
  • sourceRefs? is scene-level provenance: references to the evidence that grounded the scene, each with a documentId (an uploaded source) or a url (a web finding), plus an excerpt and a relevance note. Modules built in the chat by Vidext's agents leave it out: the script a module is built from names the source of each beat instead.
  • visualConcepts? names, in order, what each image slot in the scene depicts.

Draft and publishable: two strictness levels

Most schemas have two variants:

  • Draft is permissive: fields may be empty while content is being written.
  • Publishable is strict: non-empty strings, positive audio durations, at least one chapter, and at least one scene in each chapter.

Video and interactive scenes use one schema for both: even a draft video needs its title and an https source, and an interactive scene is always written whole.

Content must pass the publishable contract before a version can be built, and only a built version can go live. This is the type-level form of the product's draft, built, and live states. A build by Vidext's agents is checked against the publishable schemas before it is kept, which is why a build cannot produce a structurally broken module.

Last updated on

On this page