---
title: "Read a pitch deck's chapters, their calls and every take."
method: GET
path: "/pitch-decks/{jobId}/chapters"
tags: ["Pitch Deck"]
---

# Read a pitch deck's chapters, their calls and every take.

`GET /pitch-decks/{jobId}/chapters`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/pitch-decks/{jobId}/chapters`
- Auth: HTTP bearer

Returns the deck's chapters as they render: each chapter's plan (what it delivers and shows, its words, who speaks its line — a cast member in their own voice (`speaker`; `speakerOnCamera` when they are in the picture and say it on camera, lip-synced, rather than as a voice-over) or the narrator (`narrated`) — its cast and the location key it is set in) and its render calls (at most 10s each) — duration, audio mode, the plate rung the render opens on, the cast on camera, the shots and the lines spoken in them, the speech track — and every take with its checks: whether each line was heard in a voice of its own (`voiceMissLineRefs`: a line not heard, or said in a voice too like another character's — a flag; `ownReadingLineRefs`: a line said in the take's own voice, heard and distinct, kept and never a flag), whether it opened on its planned framing (`openingMiss`), whether a mouth did not do what its line asks — the speaker's not following an on-camera line, or lips moving under someone else's voice (`mouthMiss`, with the `mouths` check) — whether it was the call's one automatic retake at our cost (`atOurCost`), whether it was not checked for a person shown twice (`duplicateNotChecked`: the check could not judge it even on its retry — never a pass, and it ranks below checked takes), whether its lip sync was not checked (`mouthNotChecked`: no on-camera speaker's mouth could be read, even after the face locator's denser retry — never a pass and never a retake, and it ranks below a take whose mouths were measured passing), whether its lip sync is uncertain (`mouthUncertain`: measured, but a reading sat inside the band around its limit, so the same file could read either side of it — never a pass and never a retake, ranked below a measured pass and above a measured miss), each criterion the mouth check missed or was uncertain on, with its line, face, number and limit (`mouthFindings`), a content refusal (released, never retried; `reference_render_provider_ip_refused` is a shot refused as possibly someone else's intellectual property, whose notice names what to edit before it renders again), the selection, what a priced retake would cost, and the repair engine's state: what the take watcher saw (`watch`), the remedy decided and the rule that fired (`repair`), where a take came from (`lineage`: repaired from, trimmed from, or a new take after, an earlier take), what a repair cost (`repairCost`), what repairing it in place would cost now (`repairQuote`), what a free trim of it may keep (`trimBounds`: never into a spoken line) and, on a trimmed take, the span it kept (`trim`: its cut plays that length). Also the chapter's cut and poster frame, `stale` when the plan changed since it rendered, the master (a 480p preview in review, finished once the finish completes), the delivery class, the warnings the finish and export carry, `videoModelPreflight` in draft and review (what each chapter's render needs and what is missing; a missing location plate reads as made at render), and `reviewUrl`. Each chapter also carries `montage` (a rapid intercut run: brief shots cut tight across the people and places it names), and the deck its `interludes` — its black interludes in cut order, each with the chapter it follows, its seconds, its length in the master, its line and speaker or its sound, and what the master made of them (replace them with POST /pitch-decks/{jobId}/interludes). The deck also carries its `titleSequence` (its epigraph and source credit, its title and the people its flash cuts go to, with what each flash cut resolved to and each person's name super when `nameSupers` is on — set it with POST /pitch-decks/{jobId}/title-sequence) its `closingSequence` (the closing quote, "Coming Soon" and the production credit after the last chapter, with each card's length, start, bell beat and the look it wears, and where the music and the bell fade out — set it with POST /pitch-decks/{jobId}/closing-sequence) and its `finish` (the film finish laid on the picture at master assembly: its look, intensity and adjustments — set it with POST /pitch-decks/{jobId}/look). There are no stills and no storyboard or draft approval. A read: it never compiles, renders, voices or makes a plate. Scope: `story:read`.

## Response `200`

The deck's chapters, calls and takes + a browser review link.

- PitchDeckChapters: A pitch deck's chapters as they render (reads only: it never compiles, renders, voices or makes a plate). Statuses: draft → rendering → review → finishing → complete | failed.
  - `jobId` string, required
  - `title` string, required: The deck's one name: its title, else the first clause of its brief. Never a length (`master.durationSeconds` is the length).
  - `deckMode` 'pitch' | 'showcase', required: What the deck is for: a `pitch` (tells the story), or a `showcase` cast reel, judged as one. Set when it was planned; never changes.
  - `shotDensity` 'held' | 'standard' | 'dense', required: How many shots each render of a chapter carries (`held`, `standard` or `dense`), set when the deck was planned. Cuts inside a render are free: it never changes the price.
  - `videoModel` 'wan3-prime' | 'vidu-q4': The video model the deck renders on (`/video-model`): `wan3-prime`, the default, or `vidu-q4`. A chapter rendered on the other model reads `stale`.
  - `intent` VideoStoryIntent: What a deck or trailer is FOR. Every deck and trailer is planned from an explicit intent — what the video is for, its logline, theme, central question, stakes, what a first-time viewer is promised, a four-stage arc (setup, escalation, turn, closing question) and how the ending lands the question. Every chapter or beat names the arc stage it serves (`arcStage`), how it advances the central question (`advancesQuestion`) and, after the first, why it follows the one before it (`whyItFollows`: the visible link — a cause, an answer, a contrast, a match cut, a look, an object, a sound — and what it moves forward; one line, never shown on screen). Plan coverage first writes what a first-time viewer would take away from the plan without seeing the intent (`viewerTakeaway`, with how much of the story the words recited rather than let them work out: `toldVersusShown`, and where they lost the thread: `lostTheThread`), then compares it with the intent: intent clarity, the central question, the buildup and whether the theme is carried each fail the plan on their own, and so do subtext — a plan that recites its plot instead of posing its question — and transitions — a part that follows the one before it for no reason a first-time viewer can feel (`weakTransitions` names the weakest, each with its fix); voices (do the characters speak, rather than the narrator carrying everything) is scored beside them.
    - `purpose` string, required: What this video is for: a pitch sells the series, a showcase shows the world AS the story, a trailer hooks the episode.
    - `audience` string: Who it is for (a pitch's buyer, a trailer's audience). Optional.
    - `logline` string, required: What this show is about, in one sentence.
    - `theme` string, required: What it is really about underneath.
    - `centralQuestion` string, required: The dramatic question the video poses and leaves open.
    - `stakes` string, required: What is at risk, and for whom.
    - `viewerPromise` string, required: What a first-time viewer should feel and want by the end.
    - `arc` VideoIntentArcEntry[], required: The four stages, in order: setup, escalation, turn, closing_question.
      - `stage` 'setup' | 'escalation' | 'turn' | 'closing_question', required: Which stage: the arc is exactly setup, escalation, turn, closing_question, in that order.
      - `purpose` string, required: What this stage does for a first-time viewer.
      - `temperature` string, required: The emotional temperature, in words.
      - `intensity` integer, required: The same temperature on a 1–10 scale. It rises to the turn: the escalation runs hotter than the setup, and the turn is the peak of the first three (the closing question may fall quiet).
    - `ending` string, required: How the final moment lands the central question — posed, sharpened, and left open.
  - `visualGrammar` string, nullable, required: The deck's visual grammar. The visual grammar is the deck's one camera language across every chapter: how its world is lit and framed, how the camera moves or holds, and how chapters hand off. It is plan words: plan coverage judges every chapter against it, and nothing rendered reads it, so changing it never makes a take out of date. Replace it with POST /pitch-decks/{jobId}/visual-grammar. Null when the plan cannot be read.
  - `status` 'pending' | 'draft' | 'rendering' | 'review' | 'finishing' | 'complete' | 'failed', required: Where the deck is. A retired storyboard-era status is terminal and read-only.
  - `reviewUrl` string, nullable, required: Logged-in browser link to the deck in the Videos tab, where the cut plays — motion cannot play in a terminal.
  - `deliveryResolution` '720p' | '1080p', required: What the finish delivers: the writer's choice, else 720p (the plan never raises it).
  - `master` object, required: The stitched master: a 480p `preview` in review, `finished` once the finish completes. Only a finished master exports.
    - `url` string, nullable, required
    - `stage` 'preview' | 'finished' | 'null', nullable, required
    - `resolution` string, nullable, required
    - `interim` boolean, required: True while the master is an EARLY LOOK: a take landed while it was stitched, so the cut with every new take is put together after it and replaces it by itself. Nothing reviews an early look; only the latest master is watched.
    - `durationSeconds` number, nullable, required: `master.durationSeconds` is how long the cut runs as it was stitched — every chapter or beat at the length its take plays, the black between them and the closing — the one length to say (never the length the plan asked for). `master.posterUrl` is the still to show before it plays (null when no chapter or beat has one). Null before there is a master.
    - `posterUrl` string, nullable, required: The still to show before the master plays; null when no part of it has one.
  - `platformExports` VideoPlatformExport[], required: The master's copies levelled for another platform (POST `video-export` with a `target`): one per target asked for, in target order, with its link once ready. Empty when none was asked for.
    - `target` 'youtube' | 'x', required
    - `status` 'waiting' | 'queued' | 'rendering' | 'complete' | 'failed', required: `waiting` while the master it is made from is rebuilt; `queued`, `rendering`; `complete` with its link; `failed` with `error` (ask again).
    - `url` string, nullable, required: The levelled copy, once `complete`.
    - `current` boolean, required: False once a newer master replaced the one the copy was made from: export again for a copy of the new one.
    - `loudness` object, nullable, required: What the delivered copy measured on the EBU R128 meter: within 0.5 LU of `targetLufs`, its true peak at or under `truePeakCeilingDbtp`. Null until complete, and for a master with no sound.
      - `integratedLufs` number, required
      - `truePeakDbtp` number, required
      - `loudnessRangeLu` number, nullable, required
      - `levelling` 'linear' | 'dynamic', required: `linear`: one gain, the master's dynamics kept. `dynamic`: the peaks left no room for one gain, so the loudness pass limited them.
    - `targetLufs` number, required: The integrated loudness the copy is levelled to.
    - `truePeakCeilingDbtp` number, required: The true peak the copy never goes over.
    - `error` string, nullable, required
    - `updatedAt` string, date-time, nullable, required
  - `motion` object, required: How many footage chapters have a cut: `requested` footage chapters, `rendered` with a cut, `stillOnly` without one yet, `complete` when every one has (null before anything rendered).
    - `rendered` integer, required
    - `requested` integer, required
    - `stillOnly` integer, required
    - `complete` boolean, nullable, required
  - `chapters` PitchDeckChapter[], required
    - `chapterIndex` integer, required: The chapter's key: pass it, exactly as read, to every chapter edit, render and take selection. A plan may key its chapters from 0 or from 1.
    - `chapterNumber` integer, required: The chapter's place in the deck, counted from 1: the number a person says ("chapter 2") and every sentence uses. Never an input; chapter edits take `chapterIndex`.
    - `title` string, required
    - `chapterType` string
    - `storyBeat` string, required: What the chapter delivers dramatically.
    - `audiencePurpose` string
    - `visualPlan` string, required: What the chapter shows on screen: the source its shots are compiled from.
    - `motionPlan` string
    - `motionPrompt` string: The chapter's camera-motion prompt (`refine-chapter --motion-prompt`). When set, the render and plan coverage's storyboard use it IN PLACE OF `motionPlan`; a refine that changes `motionPlan` without one clears it; '' when unset (then `motionPlan` is used).
    - `transitionPrompt` string: The handoff out of this chapter into the next (`refine-chapter --transition-prompt`); '' when unset.
    - `captionText` string
    - `narrationText` string: The chapter's spoken line.
    - `narrationVoice` string, nullable: Who speaks the line: a cast member (in their own voice inside the cut: on camera when they are on visibleCharacters, else as a voice-over) or the narrator.
    - `textMode` 'voiceover' | 'caption' | 'null', nullable
    - `compositionKind` 'image' | 'text' | 'both', required: image = footage only, text = on-screen text only, both = text over footage.
    - `chapterFocus` 'world' | 'cast', nullable: What the chapter is of: `world` = the place itself, establishing its scale and life, with no cast on camera; `cast` = cast members on camera. Null when the plan does not mark it.
    - `propContinuity` string, required: The props this chapter's shots carry — what is held, set down or kept in the frame. The render is told it as "Props: …", so a prop you are steering away from must leave this field too. After the render, changing it puts the chapter's takes out of date. An empty string clears it. Empty when the plan states none.
    - `wardrobeContinuity` string, required: What the people in this chapter wear, kept the same across its shots. The render is told it as "Wardrobe: …". After the render, changing it puts the chapter's takes out of date. An empty string clears it. Empty when the plan states none.
    - `screenDirection` string, required: Which way people and things face and move on screen (left to right, toward the camera), kept consistent across the cut. The render is told it as "Screen direction: …". After the render, changing it puts the chapter's takes out of date. An empty string clears it. Empty when the plan states none.
    - `continuityNotes` string, required: Notes on what this chapter must keep consistent with the chapters around it, for the writer and the planner. The render is never told them, so changing them never puts a take out of date. An empty string clears them. Empty when there are none.
    - `arcStage` 'setup' | 'escalation' | 'turn' | 'closing_question' | 'null', nullable: The stage of the intent's arc this unit serves (setup, escalation, turn, closing_question), or null when the plan names none — a blocking plan defect on a plan with an intent.
    - `advancesQuestion` string, nullable: How this unit advances the intent's central question, or null when the plan says nothing — a blocking plan defect on a plan with an intent.
    - `whyItFollows` string, nullable: Why this unit follows the one before it — the link a viewer sees or hears (a cause, an answer, a contrast, a match cut, a look, an object, a sound) and what it moves forward; never on screen. Null when the plan says nothing: after the first unit, the blocking plan defect `transition_unexplained`.
    - `montage` boolean: True when the chapter is a rapid intercut run. A montage chapter is a rapid intercut run: several brief shots of about one to two seconds each across the people and places it names, cut tight (a run across more than three named people renders as a few short calls of the chapter). Marking or unmarking it changes what renders, so a rendered chapter goes stale.
    - `keepsSceneSound` boolean: True when the chapter's own sound is part of its beat. A chapter that keeps its scene sound plays the sound its own render made (harness bells, singers, a crowd: voices and all) over the score: the music dips about 12 dB under it, and a narration line dips it only while it is spoken. Every other chapter plays only its cast's lines over quiet room tone. On a chapter with no spoken line it also decides whether the render is made with sound, so keeping the sound of takes made silent needs them rendered again; any other change re-cuts the chapter from the takes it has, free.
    - `scoreUnderOwnSound` 'duck' | 'out' | 'hold': What the music does under its own sound: `duck` (Lower, the default), `out` (Stop) or `hold` (Keep). Where a beat plays its own sound (a capture's recorded track, a cut that kept its takes' sound, a chapter's kept scene sound), `scoreUnderOwnSound` says what the music does under it: `duck` (Lower, the default) dips it about 12 dB; `out` (Stop) fades it to silence over a quarter second and back after, for a captured video that carries its own score; `hold` (Keep) leaves it at its level (a spoken line still dips it). `ownSoundGainDb` (−12 to +18, null clears) raises or lowers the beat's own sound itself. The score to picture is composed around it, thinning or stopping there, so a score composed before the change is out of date: score to picture again. Free: in review the master is rebuilt from what it has, and a finished video's master is stitched again.
    - `ownSoundGainDb` number, nullable: Its own sound raised or lowered in the master, in dB; null when it plays as recorded.
    - `narrationOverOwnSound` object, nullable: Its narration speaks over its own sound, which dips under the line (the read's `warnings` say so too): `overlapMs` how long, `narration` the line's window and `ownSound` the spans it covers, in ms from its start. Null when they do not overlap.
      - `overlapMs` integer, required
      - `narration` object, required
        - `startMs` integer, required
        - `endMs` integer, required
      - `ownSound` object[], required
        - `startMs` integer, required
        - `endMs` integer, required
    - `lineDelivery` string, nullable: How the cast member says the chapter's spoken line, or null when the writer set none. How the cast member says the chapter's spoken line, in a few words ("quietly, broken, through tears, almost a whisper"; at most 300 characters, an empty string clears it). The line is voiced with it: the words reach the voice as written, and the feeling, pace and level they name (sad, angry, quiet, slow) set its tone. It directs the voice only: the face and body are directed in the motion plan, and the footage's prompt never carries it. Only a line a cast member speaks is voiced with it; a narrated chapter's narration is unchanged. On a rendered chapter a change voices the line again, so its takes go out of date (rendering it again is priced first).
    - `cutIntoNext` 'dip' | 'cut': How the chapter hands into the next one in the master: `dip` unless the writer chose `cut`. How the chapter hands into the next one in the master: `dip` (the default) falls to black and rises again over about a second; `cut` is a hard cut, the next chapter's first frame right after this one's last. A black interlude after the chapter still plays between them, and the last chapter's choice does nothing. It changes only how the master is stitched: nothing is rendered again and no take goes out of date; on a rendered deck the master is stitched again with it, free.
    - `shotType` string, nullable: The chapter's shot size as the plan states it, or null. The chapter's shot size in a few words ("close-up on Smerdyakov", "wide establishing of the square"). It must name a scale on the shot ladder — establishing, wide, medium or close — or it is refused; the scale word decides, read in that order: "medium close" is a MEDIUM, and a two-shot or over-the-shoulder with no scale word is a medium. The render is told it ("Framing: …"), so on a rendered chapter it puts the takes out of date; plan coverage reads it for the shot ladder. An empty string clears it.
    - `shotLadderRung` 'establishing' | 'wide' | 'medium' | 'close' | 'null', nullable: The rung of the shot ladder `shotType` places the chapter on, read the way plan coverage reads it ("medium close" is a medium), or null when it names none.
    - `shotTypeDirected` boolean: True when the writer set `shotType` (refine-chapter): the render is told it ("Framing: …"). A shot type the planner wrote guides plan coverage only.
    - `speaker` string, nullable, required: The cast member whose voice speaks the chapter's line inside its cut, or null.
    - `speakerOnCamera` boolean, required: True when `speaker` is in the picture (visibleCharacters) and says the line on camera, lip-synced; false when the line is their voice-over (the chapter does not show them) or there is no cast speaker.
    - `narrated` boolean, required: True when the master lays the chapter's line as narration over its cut.
    - `visibleCharacters` string[]: The named characters in the picture (an identity reference each). Unnamed people are not listed.
    - `location` string, nullable: Where the chapter is set: a canonical location key (the room's key in the location plates read, e.g. INT_TAVERN), never a scene heading.
    - `intendedDurationSeconds` integer, nullable
    - `clipUrl` string, nullable: The chapter's cut, assembled from its calls' selected takes.
    - `clipResolution` string, nullable
    - `posterUrl` string, nullable: A poster frame taken from the chapter's takes (never a generated still).
    - `textClipUrl` string, nullable
    - `textStale` boolean
    - `audioUrl` string, nullable
    - `durationMs` number, nullable
    - `stale` boolean, required: The plan changed since this chapter rendered: render it again to bring it in line. Its takes stay playable.
    - `motionError` string, nullable
    - `inMaster` boolean: Whether the chapter plays in the deck's master. False for a footage chapter with no cut (its shot was refused or has not rendered; `motionError` says why): the master leaves it out and plays the chapters around it end to end. Render the chapter again to put it back.
    - `renderedWith` object, nullable: The chapter whose renders film this one: consecutive chapters in one place (at most two with a line in a cast voice) render as one long sequence, and its shots and takes are listed (and retaken) on its first chapter. Null when the chapter's shots are its own.
      - `chapterIndex` integer
      - `chapterNumber` integer
    - `motionRemedy` object, nullable: The free way back for a chapter whose scene group is held: one of the group's selected takes is a trim that cuts away a chapter's only shot, so the group keeps its last cut (`motionError` says which take of which shot). Choose take `take` of call `callId` on the chapter keyed `chapterIndex` with select-take (free, nothing renders) and the group is cut again on the next assembly. Null when nothing is held, or when no take of that shot keeps every chapter (then `motionError` says to render the shot again).
      - `action` 'select_take', required
      - `chapterIndex` integer, required: The chapter holding the scene group's takes: the select-take path's `{chapter}`.
      - `callId` string, required
      - `take` integer, required
      - `message` string, required
    - `lineDrop` PitchDeckLineDrop: What cutting a chapter's line out of its footage would do now.
      - `available` boolean, required
      - `reason` string, nullable, required: Why not, in one plain sentence.
      - `code` string, nullable, required: `drop_line_in_middle`, `drop_line_too_short`, `drop_line_empties_chapter`, `drop_line_cuts_other_line`, `drop_line_narrated`, `drop_line_not_rendered`, `drop_line_no_take`, `drop_line_unplaced`, `drop_line_no_file` or `drop_line_no_line`.
      - `trims` PitchDeckLineDropTrim[], required
        - `callId` string, required
        - `take` integer, required
        - `keep` 'before' | 'after', required
        - `keepStartSeconds` number, required
        - `keepEndSeconds` number, required
        - `lineStartSeconds` number, required: Where the take says the line, padded: cut out with it.
        - `lineEndSeconds` number, required
        - `takeSeconds` number, required
      - `sides` object[], required: A line in the middle: the sides that could be kept instead (`keep`), per take.
        - `callId` string
        - `take` integer
        - `keep` 'before' | 'after'
        - `keepStartSeconds` number
        - `keepEndSeconds` number
        - `seconds` number
    - `droppedLine` PitchDeckDroppedLine: A line cut out of a chapter's footage, with the rest kept.
      - `speaker` string, nullable, required
      - `text` string, required
      - `lineDelivery` string, nullable, required
      - `movedTo` object, nullable, required
        - `chapterIndex` integer
        - `chapterNumber` integer
      - `at` string, date-time, required
      - `trims` object[], required
        - `callId` string
        - `take` integer: The take the line was cut out of.
        - `trimTake` integer: The trimmed take that keeps the rest.
        - `keep` 'before' | 'after'
        - `keepStartSeconds` number
        - `keepEndSeconds` number
        - `state` 'pending' | 'playing' | 'landed' | 'failed'
    - `calls` PitchDeckCall[], required
      - `callId` string, required
      - `durationSeconds` number, required
      - `audioMode` 'dialogue' | 'ambient' | 'silent', required
      - `plateKey` string, nullable, required: The location plate the render opens on (the rung matched to shot 1's framing), or null for a text-only render: no named character on camera and no speech track, so no reference image is sent.
      - `cast` string[], required: Who is on camera (a body figure each).
      - `blocking` string
      - `shots` object[]
        - `framing` string
        - `onCamera` string[]
        - `setup` string
        - `action` string
        - `startSeconds` number
        - `endSeconds` number
        - `lines` object[]
          - `lineRef` integer
          - `speaker` string
          - `text` string
          - `voice` string
      - `speechTrack` object, nullable: The cast member's recorded line the selected take was sent with (a chapter spoken in a cast voice).
        - `url` string
        - `seconds` number
      - `takes` PitchDeckTake[], required
        - `take` integer, required
        - `status` 'accepted' | 'rejected' | 'failed' | 'pending', required
        - `videoUrl` string, nullable
        - `atOurCost` boolean, required: True for the call's ONE automatic retake (a line not heard or said in another character's voice, a mouth that did not do what its line asks, or an opening off its framing): we paid for it, never the writer.
        - `selected` boolean, required
        - `selectedBy` 'default' | 'writer' | 'null', nullable
        - `voiceMissLineRefs` integer[], required: Lines this take failed by voice: not heard where they belong, or said in a voice too like another speaking character's. A flag: the take is retaken once automatically, ranks below a take without one, and may still be selected by the writer.
        - `ownReadingLineRefs` integer[], required: Lines this take said in its own reading, heard and distinct from the other voices, and kept: never a flag. Every take plays its own sound under its own picture, so the lips follow what is heard; such a line does not sound like the cast card's voice.
        - `openingMiss` boolean, required: True when shot 1 opened off its planned framing.
        - `mouthMiss` boolean, required: True when the mouth check measured a mouth that did not do what its line asks, past the band around the limit, or the quiet-mouth check measured a face moving its lips as if speaking where no line is heard (`quiet_mouth_motion`): the speaker's mouth not following an on-camera line (or following it too late or early, or still moving after it), or lips moving under someone else's voice or a voice-over. `mouthFindings` names each criterion and its number. Where the speaker's mouth could not be measured (a face too small, not found or hidden — or a miss read on a face too small to trust), the take watcher's own look at the lips decides the line (unmeasurable → decided by the watcher, finding `watcher_lip_sync`): a mouth it saw not speak the line is a miss. A reading inside the band, or an unread speaker the watcher saw speak, is `mouthUncertain`, never a miss.
        - `mouthUncertain` boolean, required: True when the take's lip sync is UNCERTAIN: measured, but a criterion sat inside the band around its limit — r within 0.10 of 0.35, one frame too many open after the line, a listener's openings just past the limit — so the same file could read either side of it; or unmeasurable → decided by the watcher, which saw the speaker's mouth speak the line (`watcher_lip_sync`, uncertain). Never a pass and never a retake (automatic or priced): the take ranks below a measured pass and above a measured miss, and its `warning` names the criterion and its number. Also true when a face where no line is heard is TOO CLOSE TO CALL (`quietMouths`: read near its bar, or a pod reading of lips moving that the take watcher did not see too): its words are in `mouthFindings` (outcome `uncertain`), it is the writer's to retake (the call's `retake`), and it is never retaken automatically nor ranks the take down.
        - `mouthFindings` object[], required: Every criterion the mouth check missed (`outcome: fail`) or was uncertain on (`outcome: uncertain`), misses first. Speaker: `correlation` (r, the least that passes), `lag` (ms the mouth trails the voice, negative when it leads; the most that passes), `trailing_motion` (the share of the frames after the line with the mouth open), `articulation` (the lips barely part under the voice: the mean openness of the voiced frames, 0 closed to 3 wide; the least that passes), `articulation_stretch` (voiced frames running on lips that never open; the most that passes). Still face: `still_open_run` (frames), `still_open_share`, `still_openings`. `watcher_lip_sync`: unmeasurable → decided by the watcher — a speaker whose mouth could not be measured (or whose miss was read on a face too small to trust) is decided by the take watcher's own look at the lips: `fail` when it saw the mouth not speak the line (a miss, retaken like any), `uncertain` when it saw it speak; `value` is the watcher's severity on the speaker (0 none, 1 minor, 2 major, 3 critical), `limit` 1. Empty on a pass and when the lips were not checked.
          - `lineRef` integer, required
          - `name` string, required
          - `role` 'speaker' | 'still', required
          - `criterion` 'correlation' | 'lag' | 'trailing_motion' | 'articulation' | 'articulation_stretch' | 'still_open_run' | 'still_open_share' | 'still_openings' | 'watcher_lip_sync' | 'quiet_mouth_motion', required: `quiet_mouth_motion`: a face whose lips were MEASURED moving as if speaking where NO line is heard (the quiet-mouth check; `lineRef` 0, `startSeconds`–`endSeconds` say where in the take; `value` its lip movement or mouth motion, `limit` the bar it crossed).
          - `outcome` 'fail' | 'uncertain', required
          - `value` number, required
          - `limit` number, required
          - `words` string, required: The sentence every surface shows, with the numbers.
          - `startSeconds` number: Where in the take it was seen, when narrower than its line (`articulation_stretch`, `quiet_mouth_motion`).
          - `endSeconds` number
        - `playthrough` object, nullable: The per-line check that the take played the cast's recorded line: `{ status: checked | unavailable | not_applicable, pass, lines[], reason }`.
        - `opening` object, nullable: The opening-framing check: `{ status: judged | unavailable, pass, plannedFraming, observedFraming, detail, reason }`.
        - `quietMouths` object, nullable: The QUIET-MOUTH check — every named face on camera where NO line is heard (a silent or ambient take throughout, a dialogue take between and around its lines), MEASURED, two ways (`measure`): `lips` — the render box found the face and outlined its lips (Apple Vision), and `energy` is how far the lips' openness swung across the stretch once its slow drift is out — a smile, a head turn, a push-in or the light read still (still under 0.06, speaking at 0.08 or more; `box` is where the face was); `motion` — no box answered, so the face was located and its lower face's motion that no head or camera move explains was measured against its upper face's (still under 0.13, speaking at 0.18 or more), and a `motion` reading of `speaking` counts only where the take watcher saw lips moving too (else `uncertain`, with why: a push-in, a flare or a smile reads the same). `{ status: checked | unmeasurable | unavailable | not_applicable, pass, uncertain, spans[{ shot, startSeconds, endSeconds, onCamera, faces[{ name, status: measured | unmeasurable, verdict: still | uncertain | speaking | null, energy, measure: lips | motion, box, exempt, faceHeightPx, startSeconds, endSeconds, pairs, pairsSetAside, words }], keepsSceneSound }], reason, version, clipSha256, cached }`. A face the box read in a shot with more than one person is named by where it sits ("the face on the left") unless it moved, when the face locator names it. Where the chapter keeps its own sound (`keepsSceneSound`: a crowd, singers), only the cast's named faces are held: a moving face none of the cast is recorded with `exempt: kept_scene_sound`, never a miss. A face `speaking` is a mouth miss (`mouthMiss`, a `quiet_mouth_motion` finding), but never retaken on its own: the same staging brings it back, so the take's decision offers a new take held `restage_needed` (restage the shot: one face, framed closer), unless the lips run on past the take's last line, which is trimmed free (`trim_overrun`). `uncertain` is shown (`mouthUncertain`, and a minor review finding marked `uncertain`) and is the writer's to retake, never retaken automatically and never a veto. Null when it never ran on this take.
        - `quietTrack` 'silence' | 'room_tone', nullable: The deck's quiet track this take was sent as its voice track (a render with no spoken line, while the deck sends one: get_pitch_deck_quiet_track); null: none. Compare the quiet-mouth checks of takes with and without it.
        - `videoModel` 'wan3-prime' | 'vidu-q4': The video model this take was made on. On `vidu-q4` the take speaks its lines in its own reading of each speaker's voice sample: its `playthrough` is `measureOnly` (measured and shown, never a flag or a retake).
        - `mouths` object, nullable: The mouth check: `{ status: checked | unmeasurable | unavailable | not_applicable, pass, uncertain, lines[{ lineRef, speaker, voice, shot, status: measured | unmeasurable, pass, uncertain, reason, faces[{ name, role: speaker | still, status, pass, uncertain, findings[{ criterion, outcome, value, limit, words }], correlation, lagMs, openShareAfter, speechOnCameraSeconds, box, states }], locatorFrames, locatorRetried, decidedBy: mouth_reader | watcher | null, watcher: { basis: unread | small_face, verdict: rigid | speaking, finding, words } | null }], reason, version, clipSha256, cached }`. A line with `decidedBy: watcher` is unmeasurable → decided by the watcher: its speaker's mouth could not be measured (or its miss was read on a face shorter than the reader is trusted on alone), so the take watcher's judgment decided it — `rigid` is a miss, `speaking` is uncertain. The verdict is stored by the take file's content hash (`clipSha256`) and the check `version` (the code, its numbers, both judging rows and their models): the same file always returns the same verdict (`cached: true` on a re-check). The face locator reads frames across each line's speech (`locatorFrames`, in seconds) with each person's identity image, and once more, denser, when it finds the speaker in none (`locatorRetried`); in `states`, one character per tenth of a second, `.` is off camera. Each line's `measure` says how its mouths were read: `lips` (the render box's lip outlines, measured; no `locatorFrames`) or `reader` (the face locator and the mouth reader). Null when it never ran on this take.
        - `abandoned` boolean, required: True for A TAKE THAT NEVER FINISHED (RELEASED): the job holding its claim died (a restart, a redeploy) before anything was sent, so the claim was released, any credits reserved for it were released once, and the shot's next take was decided again. It is recorded `failed` (`failure.code` `take_never_finished`, `failure.message` says why), never selected, and never counts against the shot's automatic retake. Say "a take that never finished (released)".
        - `checksPending` boolean, required: True while the take's CHECKS HAVE NOT COMPLETED — its QA, its mouth or duplicate-person check, or its watch (a redeploy can interrupt them; the worker runs them again): nothing proves the take is clean yet. It ranks below every take whose checks completed, so it is never selected by default over one, and its `warning` says so. Say "checks pending", never "clean".
        - `identitySwaps` object[], required: Every line the WRONG PERSON speaks: the mouth check found the line's `speaker` nowhere on camera across it, and `face` — another member of the call's cast, matched by their identity image — following it. A measured miss of its own kind (`mouthMiss` is true too): it earns the call's automatic retake, told whose face must say the line, and the take never plays over one the right person speaks. Empty when none.
          - `lineRef` integer, required
          - `speaker` string, required
          - `face` string, required
        - `mouthNotChecked` boolean, required: True when the take's lip sync was NOT CHECKED: the mouth check could not read an on-camera speaker's mouth (the face not found even after the locator's denser retry, too small or hidden) and no watch of the take could decide it instead, read no line, or could not run. A speaker the take watcher decided is a `mouthMiss` or `mouthUncertain`, not this. Never a pass: the take ranks below every take whose mouths were measured passing, and its `warning` says why. It earns no retake, automatic or priced: only a measured `mouthMiss` does.
        - `duplicatePerson` boolean, required: True when the duplicate-person check saw one person in the picture twice at once. It earns the call's one automatic retake, and the take ranks below every other take for the default selection.
        - `duplicateNotChecked` boolean, required: True when the take was NOT CHECKED for a person shown twice: the duplicate-person check could not judge it, even on its one retry (or never ran on it). Never a pass: the take ranks below every take whose check passed, and its `warning` says so. It earns no automatic retake.
        - `duplicates` object, nullable: The duplicate-person check: `{ status: judged | unavailable, pass, duplicates[{ name, shot, seconds, detail }], reason }`. `unavailable` (after one retry) proves nothing and is never a pass: see `duplicateNotChecked`. Null when it never ran on this take.
        - `warning` string, nullable: The sentence the finish quote and the export carry if this take is kept.
        - `failure` object, nullable: Why the take produced nothing. `moderation: true` is a content refusal: released (nothing charged) and never retried. `code: reference_render_provider_ip_refused` is the provider refusing the shot as possibly someone else's intellectual property: the same shot is refused again, so the call's notice says what to edit (and the likely trigger: currency, a logo or brand, a named work) before it is rendered again.
          - `code` string
          - `message` string
          - `moderation` boolean
        - `billedSeconds` number, nullable
        - `recordedAt` string, date-time
        - `watch` TakeWatch: The take watcher's pass over one take. `unavailable`: the watch could not finish (after one retry with more room), so it proves nothing either way and the take is UNWATCHED — its decision reads `unwatched`, never clean, and `decision: rewatch` watches it again, free; `skipped` was not watched on purpose (the checks alone then decide).
          - `status` 'watched' | 'unavailable' | 'skipped', required
          - `defects` TakeDefect[], required
            - `kind` 'anachronism' | 'signage' | 'stray_person' | 'duplicate_person' | 'crowd_unison' | 'lighting' | 'camera_path' | 'speed_ramp' | 'timing' | 'invented_cut' | 'drawn_screen' | 'identity' | 'identity_swap' | 'lip_sync' | 'line_voice' | 'other', required
            - `source` 'watcher' | 'playthrough' | 'mouths' | 'duplicates' | 'opening' | 'dissolves', required: `watcher`: the take watcher saw it; the others are the checks that measured it.
            - `severity` 'minor' | 'major' | 'critical', required: `minor` is shown and never acted on; `major` and `critical` earn a remedy.
            - `startSeconds` number, required: Seconds from the start of the take.
            - `endSeconds` number, required
            - `description` string, required
            - `removableInPlace` boolean, required: True when it can be removed or replaced in place without a new take.
            - `replaceWith` string, nullable: For a removable defect: what should be there instead, in plain words (never a word to write).
          - `reason` string, nullable, required
          - `watchedAt` string, date-time, required
        - `repair` TakeRepairDecision: What the repair engine decided for one take, and why. Every rendered take is watched with its sound after its checks. A cut nobody asked for at the start or end of an otherwise good take is trimmed off first, before any new take: free, frame for frame, only where the cut is measured in the file, outside every spoken line (each kept whole with a breath after it), and only when what is left keeps its chapter or beat within a quarter of its planned length. When the shot's automatic new take is spent and the take it plays still has such a cut outside its line, that end is trimmed as a last resort: past the quarter, as long as the line stays whole, at least 2 seconds are left and the chapter or beat keeps half its planned length. A cut inside a spoken line is never trimmed. A speaker whose lips keep moving past the take's last line, where nothing is heard, is trimmed half a second after the line, free and frame for frame. Lips moving where no line is heard are never retaken on their own: the same staging brings them back, so the shot is offered for restaging (one face, framed closer), a trim, or your call. Any other defect is remedied by rule during processing, at our cost: first a new take told what to avoid; a repair in place when the same problem comes back after a new take, or when the take passed every other check and only something removable (a period anachronism, garbled lettering, a stray or doubled person) or the light is wrong. Camera movement and its speed (a move that rushes, or dies into a hold at the end), timing, cuts and a crowd moving as one (extras in step, everyone turning or looking down at once, repeated faces) are only ever fixed by a new take, or by the free trim when they sit only at an end of the take. A made-up screen or app the shot never had (a display or app window painted into the picture where none was filmed) is only ever fixed by a new take, or by the free trim when it sits only at an end of the take; spoken shots are not repaired in place. A line the speaker's mouth did not speak on two takes is no longer retaken on camera: the next take stages it as a voice-over, the speaker seen from behind, the line heard over the picture. Every take plays its own sound under its own picture, so the lips follow what is heard: a line said in the take's own reading is kept, and only a line not heard, or said in a voice too like another character's, is a defect (a new take). Where a speaker's mouth cannot be measured (or the face is too small to trust a miss), the watcher's own judgment of the lips decides the line: a mouth it saw not speak is a miss, one it saw speak is uncertain. Each shot gets at most one automatic new take, one automatic repair in place and one automatic voice-over re-stage, so a new take whose removable defect came back is repaired in the same pass; a repaired or trimmed take is never remedied again on its own. A repair that fails on the repair service's own side (never one declined at its content check) and cost nothing is sent again once; if that fails too, a new take instead. A repaired take keeps the take's own sound, is judged again, and is kept as a new take linked to the one it repairs; it plays only when it passes. A trimmed take plays over the take it came from when it passes, or when it shows only part of what that take showed, with the same speech and faces: it is judged by time window, so anything seen inside the span it keeps counts as that take's own footage too, and it wins when the trim cut something off.
          - `remedy` 'none' | 'wan_retake' | 'aleph_repair' | 'trim' | 'stage_as_voice_over', required: `none`; `trim`: a cut nobody asked for at the start or end of the take is cut off (free, frame for frame, never into a spoken line; see `trim`); `wan_retake`: a new take, told what to avoid; `stage_as_voice_over`: a new take that plays a line whose speaker's lips failed it on two takes as a voice-over (see `voiceOver`); `aleph_repair`: a repair in place.
          - `rule` 'not_judged' | 'clean' | 'writer_kept' | 'first_remedy_is_a_new_take' | 'recurred_after_new_take' | 'clean_but_removable' | 'needs_a_new_render' | 'spoken_shot_held_from_repair' | 'repair_refused_before' | 'repair_unavailable' | 'writer_requested' | 'trim_edge' | 'writer_trimmed' | 'repair_failed_at_host' | 'line_revoiced_twice' | 'mouth_failed_twice' | 'writer_staged_voice_over' | 'trim_last_resort' | 'trim_overrun' | 'unwatched', required: The rule that fired. `unwatched`: the take's watch could not finish, so nothing is decided for it (never `clean`, never a remedy on its own); `defects` lists what its other checks measured, and `take-repair-override` with `decision: rewatch` watches it again, free.
          - `reason` string, required: The rule in plain words, with what was found.
          - `defects` TakeDefect[], required
            - `kind` 'anachronism' | 'signage' | 'stray_person' | 'duplicate_person' | 'crowd_unison' | 'lighting' | 'camera_path' | 'speed_ramp' | 'timing' | 'invented_cut' | 'drawn_screen' | 'identity' | 'identity_swap' | 'lip_sync' | 'line_voice' | 'other', required
            - `source` 'watcher' | 'playthrough' | 'mouths' | 'duplicates' | 'opening' | 'dissolves', required: `watcher`: the take watcher saw it; the others are the checks that measured it.
            - `severity` 'minor' | 'major' | 'critical', required: `minor` is shown and never acted on; `major` and `critical` earn a remedy.
            - `startSeconds` number, required: Seconds from the start of the take.
            - `endSeconds` number, required
            - `description` string, required
            - `removableInPlace` boolean, required: True when it can be removed or replaced in place without a new take.
            - `replaceWith` string, nullable: For a removable defect: what should be there instead, in plain words (never a word to write).
          - `automatic` boolean, required: True when the engine applied (or applies) it on its own, at our cost.
          - `heldBy` 'one_remedy_per_pass' | 'new_take_budget_spent' | 'repair_budget_spent' | 'spend_gate' | 'next_take_is_the_writers' | 'writer_overrode' | 'failed_repair_billed' | 'voice_over_budget_spent' | 'restage_needed' | 'null', nullable, required: Why it was not applied automatically: it is offered to the writer instead.
          - `outcome` 'applied' | 'offered' | 'failed' | 'refused' | 'pending' | 'none', required: `refused` only when the repair was declined at the content check (never sent again unchanged).
          - `resultTake` integer, nullable, required: The take the remedy made, once it exists.
          - `outcomeMessage` string, nullable, required
          - `decidedAt` string, date-time, required
          - `trim` TakeTrimPlan: A trim: the span of the take that is kept (frame-exact) and what was cut off at each end.
            - `keepStartSeconds` number, required
            - `keepEndSeconds` number, required
            - `keptSeconds` number, required: The kept span's length: what the trimmed take plays in its cut.
            - `takeSeconds` number, required: The take's length before the trim.
            - `edges` TakeTrimEdge[], required
              - …
            - `basis` 'outside_the_line' | 'dying_move' | 'last_resort_after_retakes' | 'speaker_overrun', nullable: Why the engine trimmed it, recorded with the take's checks: `outside_the_line` ("invented edge cut trimmed: outside the line": the free trim before any new take, the invented edge cut lying outside every spoken line and the chapter or beat kept within a quarter of its plan), `dying_move` ("camera move dying into a hold trimmed: outside the line": the same free trim of a camera move that dies into a hold at the end, cut at the hold's first frame, never slowed or padded) or `last_resort_after_retakes` ("invented edge cut trimmed: last resort after retakes": the shot's automatic new take was spent, so the take it plays was trimmed past the quarter, the line kept whole, at least 2 s left, the chapter or beat at least half its plan). Null for the writer's own trim.
            - `droppedLineRefs` integer[], nullable: The lines this trim cut OUT of the take (the writer cut the chapter's line out and kept the rest of its footage): the span kept is one side of them. Null for every other trim, which keeps every line whole.
          - `voiceOver` TakeVoiceOver: Lines a take plays as a VOICE-OVER that its call says on camera: the speaker seen from behind, the line heard over the picture.
            - `lineRefs` integer[], required
            - `speakers` string[], required
        - `lineage` TakeLineage: Where a take came from: the take it remedies, and how.
          - `repairedFrom` integer, required
          - `remedy` 'wan_retake' | 'aleph_repair' | 'trim' | 'stage_as_voice_over', required: `trim`: a trim of the take (free); `wan_retake`: a new take after it; `stage_as_voice_over`: a new take after it that plays its line as a voice-over; `aleph_repair`: a repair of it in place.
          - `rule` 'not_judged' | 'clean' | 'writer_kept' | 'first_remedy_is_a_new_take' | 'recurred_after_new_take' | 'clean_but_removable' | 'needs_a_new_render' | 'spoken_shot_held_from_repair' | 'repair_refused_before' | 'repair_unavailable' | 'writer_requested' | 'trim_edge' | 'writer_trimmed' | 'repair_failed_at_host' | 'line_revoiced_twice' | 'mouth_failed_twice' | 'writer_staged_voice_over' | 'trim_last_resort' | 'trim_overrun' | 'unwatched', required
          - `automatic` boolean, required: True for the engine's automatic remedy (at our cost).
        - `repairCost` TakeRepairCost: What a repair cost on our ledger: the repair host's own billed units and their dollars.
          - `hostCredits` number, nullable, required
          - `estimatedHostCredits` number, nullable, required
          - `usd` number, nullable, required
          - `billedSeconds` number, required
        - `repairQuote` TakeRepairQuoteLine: What a writer-requested repair of this take would cost now: the price table's TAKE_REPAIR line (4 credits a second, a two-second minimum). `credits` is null when the take cannot be repaired in place (`reason` says why).
          - `credits` integer, nullable, required
          - `seconds` number, required: The seconds a repair sends: the whole take, or only the shots its defect sits in.
          - `available` boolean, required
          - `reason` string, nullable, required: Why it cannot be asked for right now.
        - `trimBounds` TakeTrimBounds: What a free trim of this take may keep. A trim never cuts into a spoken line.
          - `takeSeconds` number, required
          - `speech` object, nullable, required: Where the take's spoken lines sit (the first line's start, the last one's end); a trim must keep all of it. Null for a take that speaks nothing.
            - `startSeconds` number, required
            - `endSeconds` number, required
          - `minimumSeconds` number, required: The shortest a trimmed take may be.
          - `suggested` object, nullable, required: The engine's own trim of this take (a cut it measured at an end), or null.
            - `keepStartSeconds` number, required
            - `keepEndSeconds` number, required
          - `available` boolean, required
          - `reason` string, nullable, required: Why it cannot be trimmed right now.
        - `trim` TakeTrimPlan: A trim: the span of the take that is kept (frame-exact) and what was cut off at each end.
          - `keepStartSeconds` number, required
          - `keepEndSeconds` number, required
          - `keptSeconds` number, required: The kept span's length: what the trimmed take plays in its cut.
          - `takeSeconds` number, required: The take's length before the trim.
          - `edges` TakeTrimEdge[], required
            - `edge` 'head' | 'tail', required
            - `transition` 'cut' | 'dissolve' | 'settle' | 'writer', required: `cut`: a hard cut (one frame, or a few the render smeared it over); `dissolve`: a blend over several frames, cut at its first blended frame; `settle`: the camera's move dying into a hold at the end, cut at the hold's first frame (nothing is slowed or padded); `writer`: the writer's own span (nothing measured).
            - `transitionStartSeconds` number, required
            - `transitionEndSeconds` number, required
          - `basis` 'outside_the_line' | 'dying_move' | 'last_resort_after_retakes' | 'speaker_overrun', nullable: Why the engine trimmed it, recorded with the take's checks: `outside_the_line` ("invented edge cut trimmed: outside the line": the free trim before any new take, the invented edge cut lying outside every spoken line and the chapter or beat kept within a quarter of its plan), `dying_move` ("camera move dying into a hold trimmed: outside the line": the same free trim of a camera move that dies into a hold at the end, cut at the hold's first frame, never slowed or padded) or `last_resort_after_retakes` ("invented edge cut trimmed: last resort after retakes": the shot's automatic new take was spent, so the take it plays was trimmed past the quarter, the line kept whole, at least 2 s left, the chapter or beat at least half its plan). Null for the writer's own trim.
          - `droppedLineRefs` integer[], nullable: The lines this trim cut OUT of the take (the writer cut the chapter's line out and kept the rest of its footage): the span kept is one side of them. Null for every other trim, which keeps every line whole.
        - `voiceOver` TakeVoiceOver: Lines a take plays as a VOICE-OVER that its call says on camera: the speaker seen from behind, the line heard over the picture.
          - `lineRefs` integer[], required
          - `speakers` string[], required
        - `voiceOverRestage` TakeVoiceOverRestage: What a writer's voice-over re-stage of this take would stage — the call's on-camera lines whose speaker's lips failed them on a take of it, else every line it says on camera — and its price (a new take of the call).
          - `available` boolean, required
          - `reason` string, nullable, required: Why it cannot be asked for right now.
          - `lineRefs` integer[], required
          - `credits` integer, nullable, required
      - `selectedTake` integer, nullable, required: The take the cut plays and the finish delivers. Null when the call has no accepted take yet: render it again.
      - `notices` object[]
        - `take` integer
        - `code` string
        - `message` string: Plain words for the writer. For a content refusal it is the action that can work: an IP refusal (`code: reference_render_provider_ip_refused`) names what to edit and the likely trigger.
        - `moderation` boolean: True for a content refusal: released, never retried.
      - `rendering` boolean, required: A take of this call is in flight now.
      - `retake` object, required: A priced new take of this call (the render-clip op): its take number and credits.
        - `take` integer
        - `credits` number
  - `interludes` PitchDeckInterlude[], required: The deck's black interludes, in cut order, with what the master made of each. A black interlude is a beat of pure black between two chapters (0.5 to 2 seconds), keyed by the chapter it follows (`afterChapterIndex`), that may carry one sound (a breath, a bell) or one short line heard over the dark, the narrator's or a character's own, always as a voice-over. It costs no render: the master draws the black and voices its line and its sound at no charge. Replace them with POST /pitch-decks/{jobId}/interludes.
    - `afterChapterIndex` integer, required: The `chapterIndex` of the chapter the black follows.
    - `afterChapterNumber` integer, nullable, required: The place of that chapter in the deck, from 1: "after chapter 3".
    - `seconds` number, required: How long the black holds, as planned.
    - `line` string: The words heard over the black, when it carries a line.
    - `speaker` string: Who says `line`: a canon cast name, or NARRATOR. Always heard as a voice-over.
    - `sound` string: The one sound heard in the dark, when it carries one.
    - `durationMs` integer, required: How long it holds black in the master: its seconds, or as long as its voiced line needs (at most 5 s).
    - `audioUrl` string, nullable, required: The voiced line, once an assembly has made it for the line as it stands.
    - `soundUrl` string, nullable, required: The sound, once an assembly has made it for the sound as it stands.
    - `error` string, nullable, required: Why its line or its sound could not be made, when one could not.
  - `titleSequence` PitchDeckTitleSequenceView, required: A deck's title sequence opens its master, before the first chapter: optionally an epigraph (`epigraph`: its words and where they are from) and a source credit (`sourceCredit`), each quiet on black and held long enough to read; then flash cuts of six to ten frames to the people it names (`cast`, in order; `inShadow` darkens one), each the person's LIVING PORTRAIT — looking into the lens, still, breathing, rendered for the flash (priced first, its own step) — and until it is made a still, silent close from the deck's own takes or another rendered deck of the project (free), never one in which anyone speaks or moves; a still canon portrait image only when the writer asks for one (`flashSource: 'portrait'`); then the title (`title`, one word, in capitals) in a bold sans on black. The flash cuts and the title run `seconds` (3 to 5). With `nameSupers: true` each flash cut carries the person's NAME in the TITLE'S LOOK — the face and colour the title is drawn in (blood red, the heavy condensed sans, when the title is directed so), uppercase, large enough to read at 480p — on the bell beat with the face, set in the black BESIDE the picture (or over the top of it), never over the face: LABEL is the first word of the person's canon name in capitals unless their cast entry sets `label`, and `role` (up to 40 characters, optional) is a smaller line under it; a person `inShadow` gets no name unless their `label` is set (the shadow withholds who they are); how the names look and where they sit is directed with `titleElement: nameSupers`. With `beatGrid: true` the intros cut on the bell's beat: from the sequence's first frame a beat every `beatSeconds` (0.5 to 4; 2 when left out), each flash cut starting on a beat and holding exactly one beat (the one in shadow too), the title on the next beat for `titleBeats` beats (1 to 8; 2 when left out) — their seconds are then derived (beats × beatSeconds), and a score composed to the deck strikes its bell on every intro and on the title. Saving it is free: nothing is rendered for it (a motion close is its own priced step). `enabled: false` keeps it without playing it. How its words look and move is directed separately (`titleElement` on the direct-text-motion call; read back as `textMotion`), and a save keeps those directions.
    - `enabled` boolean, required: Whether the deck opens on it. False keeps it without playing it.
    - `title` string, required: One word, shown in capitals ("KARAMAZOV").
    - `cast` object[], required: Who the flash cuts go to, in order: the father first, then each son, the one in shadow last. Each must be in the cast canon when the project has one.
      - `name` string, required: An exact canon cast name, or an alias the canon lists.
      - `inShadow` boolean: Show them in shadow: a dark flash, the face half-lost. A person in shadow gets no name super unless their `label` is set.
      - `role` string: A smaller line under their name ("the father"), shown when `nameSupers` is on. Leave it out for the name alone (the default).
      - `label` string: The name their super shows, set in capitals, instead of the first word of their canon name ("GRUSHENKA"). Setting it is also what gives a person in shadow a super.
      - `flashSource` 'deck' | 'project' | 'motion' | 'portrait': Where their flash cut is taken from first: `motion` (their living portrait: into the lens, still, breathing, rendered for the flash, priced first), `deck` (a still, silent close from this deck's shots), `project` (a still, silent close from another rendered deck of the project, free) or `portrait` (their STILL portrait image — only when the writer asks for one). Left out: their living portrait, else a still, silent close from this deck, then the project; a close in which anyone speaks or moves is never used.
    - `seconds` number, required: How long the flash cuts and the title run.
    - `epigraph` object: An epigraph shown first, alone on black, held long enough to read (about 3 words a second, at least 4 s).
      - `text` string, required: Its words, exactly as the source gives them.
      - `attribution` string: Where the words are from ("John 12:24").
    - `sourceCredit` string: A credit shown after the epigraph and before the title ("From the novel by Fyodor Dostoevsky").
    - `nameSupers` boolean, required: Whether the flash cuts carry name supers (false when the sequence leaves it out).
    - `beatGrid` boolean: Cut the intros on the bell's beat: from the sequence's first frame a beat every `beatSeconds`, each flash cut starting on a beat and holding exactly one beat (the one in shadow too), the title on the next beat for `titleBeats` beats. Their seconds are then derived (beats × beatSeconds; `seconds` is not used), and a score composed to the deck strikes its bell on every intro and on the title. Off when left out. Free.
    - `beatSeconds` number: The bell's beat in seconds (0.5 to 4; 2 when left out), kept to the millisecond.
    - `titleBeats` integer: On the grid, how many whole beats the title holds (1 to 8; 2 when left out — 4 s on a 2 s bell, long enough for a score to give the title its own section).
    - `playing` boolean, required: True when it plays in the master (enabled, with a title, someone to cut to, and a chapter after it).
    - `textMotion` object: How its words look and move, as directed (absent for words in the sequence's own type). Set by POST /pitch-decks/{jobId}/storyboard/direct-text-motion with a `titleElement`, never by a save of the sequence (which keeps them). The title sequence's words are directed like a chapter's text, in the writer's own words, through the same direct-text-motion call with a `titleElement` instead of a `chapterIndex`: `title` ("KARAMAZOV huge, blood red, a stark sans, the ends cut off by the frame"), `epigraph` ("a subtle background behind the verse: grain, a candle's flicker, a few falling seeds"), `sourceCredit`, or `nameSupers` (every name alike: its face, its colour, and where it sits — beside the face on the left or the right, over the top of the picture, or under it; never over a face). The director compiles the sentence into a motion-text spec — the face (the show's, or a bundled grotesque or condensed grotesque), the colour, the size (up to edge to edge, wider than the frame so the frame cuts the first and last letters), how it moves, and a seeded background behind it (film grain, a breathing vignette, a flickering warm light, banks of fog rolling across the frame, slowly falling motes), as quiet or as strong and moving as asked ("the same fog as the verse, but stronger"), held under the words' own brightness (behind the blood-red title it is a haze of the same red) — and saves it with the sentence on the title sequence (`textMotion`). The words stay the sequence's: a direction says how they look, never what they say. `clear: true` puts an element back in the sequence's own type. Free: an LLM call, no credits; a rendered deck's master is stitched again with it, and nothing else renders (no chapter, no shot). A save of the title sequence keeps every direction (an element whose words are removed loses its own).
      - `title` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
      - `epigraph` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
      - `sourceCredit` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
      - `nameSupers` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
    - `beatTimeline` object, nullable, required: The bell beat grid (null when `beatGrid` is off): the beat, the derived length of the flash cuts and the title (`beats` × `beatSeconds` = `seconds`), and where each intro and the title land — the beat each starts on, its frames, and its start in the sequence and in the master (frames and seconds; the master's are null while the sequence does not play).
      - `beatSeconds` number, required
      - `titleBeats` integer, required: How many beats the title holds (2 when the sequence leaves `titleBeats` out).
      - `fps` integer, required
      - `beats` integer, required: The intros (one beat each) and the title's beats.
      - `seconds` number, required: The derived length of the flash cuts and the title.
      - `intros` object[], required
        - `name` string, required
        - `beat` integer, required: The beat it starts on (beat 0 is the sequence's first frame).
        - `frames` integer, required: How long it holds: exactly one beat.
        - `sequenceFrame` integer, required
        - `sequenceSeconds` number, required
        - `masterFrame` integer, nullable, required
        - `masterSeconds` number, nullable, required
      - `title` object, required
        - `beat` integer, required
        - `beats` integer, required: Whole beats the title holds.
        - `frames` integer, required
        - `sequenceFrame` integer, required
        - `sequenceSeconds` number, required
        - `masterFrame` integer, nullable, required
        - `masterSeconds` number, nullable, required
    - `supers` object[], required: Each person's name super as the plan resolves it now, from the cast canon, in the cast's order.
      - `name` string, required
      - `text` string, nullable, required: How the super reads (`LABEL · role`, or `LABEL`), or null when they get none (supers off, or in shadow without a label).
    - `durationMs` integer, required: How long it runs in the master, its cards included.
    - `flashes` object[], required: What each flash cut goes to, once an assembly has resolved them (empty before the first). Every intro is a LIVING PORTRAIT (owner, 2026-10-07: "They should just be looking at the camera and breathing but not in motion … we don't want them to be speaking unless we're using words"). Each person's flash is, in order: their living portrait (`source: motion`: one short WAN shot rendered for the flash from their cast portrait, the person looking straight into the lens, still, breathing, an occasional blink, lips closed, lit and graded like the deck, 480p, a few seconds, PRICED FIRST through the motion-close step and never spent silently; one another deck of the project made is reused free); until one is made, a STILL, SILENT close of them from the deck's own cut (`source: cut`, free) or another rendered deck of the project (`source: reuse`, free; `fromDeck` names it), with `needsMotionClose: true` while their living portrait is not made. A close stands in only when nobody speaks on camera in its shot, the mouth check and the take watcher saw no mouth move there, the person is alone, and its picture measured still (no walk, gesture, turn or camera move) — in motion means speaking with words, and a flash plays the score, never a line, so a close in which anyone speaks or moves never opens an intro. A person `inShadow` stays in shadow, as still. A cast entry's `flashSource` (`motion`, `deck`, `project` or `portrait`) puts that source first; `portrait` is their still canon portrait image, used only when asked for. With neither, `source` is `missing` with `needsMotionClose: true`: their beat stays black, and `motionClosesNeeded` prices the living portrait that would fill it.
      - `name` string, required
      - `inShadow` boolean, required
      - `source` 'cut' | 'reuse' | 'motion' | 'portrait' | 'missing', required: `motion`: their living portrait; `cut`: a still, silent close from the deck's own cut; `reuse`: a still, silent close from another rendered deck of the project (free); `portrait`: their still portrait image (only when asked for); `missing`: nothing to cut to (the beat stays black; the note says what to do).
      - `moving` boolean, required: True when the flash is footage (a living portrait or a close), not a still image.
      - `url` string, nullable, required
      - `startSeconds` number, nullable, required: Where in its video the flash starts (a moving flash).
      - `chapterNumber` integer, nullable, required: The chapter of this deck the close comes from, by its place in the deck from 1 (a `cut` flash).
      - `framing` string, nullable, required
      - `note` string, nullable, required
      - `nameSuper` string, nullable, required: The name this flash cut carried when the master was last assembled (with its role after a ` · ` when one is given), or null.
      - `fromDeck` object, nullable, required: The other deck of the project a reused close (or a reused motion close) is from.
        - `jobId` string, required
        - `chapterNumber` integer, nullable, required: Its chapter's place in that deck (null for a motion close).
      - `needsMotionClose` boolean, required: True when their living portrait is not made: it is what would fill their beat, or replace the still close standing in.
    - `motionCloses` object[], required: The living portraits rendered (or on their way) for the intros. A motion close is a person's LIVING PORTRAIT for their title intro: one WAN shot of their face and shoulders from their cast portrait, the person looking straight into the lens and holding still — breath, an occasional blink, lips closed — lit and graded like the deck (its Series Bible's look), at 480p, silent, 3 seconds on the 2 s bell (the flash's beat plus room), in shadow when the sequence keeps them in shadow. PRICED FIRST — TWO CALLS on the API and the CLI, two tools on MCP and in chat (quote_render_pitch_deck_title_motion_closes, then render_pitch_deck_title_motion_closes): without `confirmed` it prices every person whose intro is not yet their living portrait (`motionClosesNeeded` in the read: about 6 people × 3 s at 480p for a father and his sons), or the people named in `names` (a new take of someone who has one is priced again), and spends nothing; with `confirmed: true` it reserves exactly those lines and renders them. Allowed while the deck is in review or complete. When each lands it is checked like a take (a file that decodes, silent, its length) and the master is re-assembled with it, free; a render that fails or is refused is released (nothing charged). Read each one back as `titleSequence.motionCloses` (`livingPortrait` false: a moving close made before 2026-10-07, which no longer opens an intro).
      - `name` string, required
      - `take` integer, required
      - `status` 'queued' | 'rendering' | 'accepted' | 'failed', required: `accepted`: it plays; `failed`: released, nothing charged.
      - `url` string, nullable, required
      - `seconds` number, required
      - `credits` number, required
      - `inShadow` boolean, required
      - `failure` string, nullable, required
      - `requestedAt` string, date-time, required
      - `livingPortrait` boolean, required: True for a living portrait; false for a moving close made before 2026-10-07, which no longer opens an intro.
    - `motionClosesNeeded` object[], required: Whose intro is not yet their living portrait (nothing fills their beat, or a still close stands in), with the price of each. Empty when every intro opens on one.
      - `name` string, required
      - `seconds` number, required
      - `credits` number, required
      - `renderable` boolean, required: False when they have no cast portrait to render from (give them one first).
  - `closingSequence` ClosingSequenceView, required: A deck's closing sequence ends its master, after the last chapter, and mirrors its title sequence: optionally a closing quote (`quote`: its words, quoted exactly, and where they are from, cited exactly — one that answers the opening's epigraph, often from the same source), then "Coming Soon" (`comingSoon`, up to 40 characters; "Coming Soon" when left out), then the production credit (`productionCredit`; "Sleeper Hit Studio" when left out), each quiet on black, faded in and out and held long enough to read. It ADDS to the deck's length: no chapter is shortened for it. When the title sequence cuts on its bell beat grid, each card starts on a beat of that same grid and the bell lane accents it. Across it the music (the score or the beds) and the bell lane fade out smoothly to silence on the master's last frame: what still sounds at the last chapter's cut plays on under the cards. A card with no direction of its own wears the opening's look (the quote the epigraph's, the credit the source credit's, "Coming Soon" the title's or the epigraph's background), so the deck is sandwiched by one style. It is free: nothing is rendered for it, and a rendered deck's master is stitched again with it. `enabled: false` keeps it without playing it. How its words look and move is directed separately (`closingElement` on the direct-text-motion call; read back as `textMotion`), and a save keeps those directions. THE LOGO CARD (`logoCard: true`, off when left out) ends the sequence on the project's brand logo, alone on black after the production credit, faded in and out and held 3 seconds. The logo is the project's (`brandLogoUrl` on the project, set on the site's Closing card, with the Story API project update's `brandLogo`, or on the CLI with `projects update --brand-logo-file`); a save that turns the card on while the project has no logo is refused, and the save copies the logo the project has at that moment (read back as `logoUrl`), so save the closing again after replacing the logo. Free like the rest of the sequence.
    - `enabled` boolean, required: Whether the deck or trailer ends on it. False keeps it without playing it.
    - `quote` object: A closing quote shown first, alone on black, held long enough to read (about 3 words a second, at least 4 s).
      - `text` string, required: Its words, exactly as the source gives them.
      - `attribution` string: Where the words are from, cited exactly.
    - `comingSoon` string, required: "Coming Soon" as the master sets it (the default when left out).
    - `productionCredit` string, required: The production credit as the master sets it (the studio's name when left out).
    - `logoCard` boolean, required: Whether it ends on the project's brand logo.
    - `logoUrl` string, nullable, required: The logo the logo card shows: the project's brand logo as it was when the closing was saved with the card on (null while the card is off).
    - `logo` object: The logo as stored on the closing (READ ONLY: copied from the project by the save that turns the logo card on).
      - `url` string, required
    - `playing` boolean, required: True when it plays in the master (enabled, and a chapter or beat before it).
    - `durationMs` integer, required: How long it runs in the master: what it adds to the deck's or trailer's length.
    - `startSeconds` number, nullable, required: Where it starts in the master (null while it does not play).
    - `onBeatGrid` boolean, required: Whether its cards keep the title sequence's bell beat grid (each starting on a beat).
    - `textMotion` object: How its cards look and move, as directed (absent for a card that wears the opening's look or its own type). Set by POST /pitch-decks/{jobId}/storyboard/direct-text-motion with a `closingElement`, never by a save (which keeps them). The closing sequence's words are directed like the title sequence's, in the writer's own words, through the same direct-text-motion call with a `closingElement` instead of a `chapterIndex`: `quote`, `comingSoon` or `productionCredit` ("the same candlelight and grain as the epigraph", "Coming Soon wide and slow, a faint vignette breathing behind it"). The same director compiles the sentence into a motion-text spec (face, colour, size, motion and a quiet background) and saves it with the sentence on the closing sequence (`textMotion`). The words stay the closing's: a direction says how they look, never what they say. `clear: true` puts a card back in the opening's look (or its own type). Free: an LLM call, no credits; a rendered deck's master is stitched again with it, and nothing else renders.
      - `quote` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
      - `comingSoon` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
      - `productionCredit` PitchDeckTitleTextMotion: One of the title sequence's words, directed: the writer's sentence and the motion-text spec compiled from it, which the master executes.
        - `direction` string, required: The writer's own words for how it looks and moves.
        - `spec` object, required: The motion-text spec: version, layers (each a text, atmosphere, particle… layer with its face, fit, colours and keyframed steps).
    - `cards` object[], required: Its cards in order: the quote (when it has one), "Coming Soon", the production credit, and the project's logo (when the logo card is on).
      - `card` 'quote' | 'comingSoon' | 'productionCredit' | 'logo', required
      - `text` string, required: Its words (empty on the logo card).
      - `attribution` string, nullable, required
      - `imageUrl` string, nullable, required: The image it shows: the project's logo on the logo card, else null.
      - `seconds` number, required: How long it is on screen, its fades included.
      - `startSeconds` number, nullable, required: Where it starts in the master (null while the closing does not play).
      - `beat` integer, nullable, required: The bell beat it starts on, on the grid (null off the grid).
      - `look` 'own' | 'opening' | 'null', nullable, required: `own`: its own direction; `opening`: the opening's look, borrowed; null: its own type on black.
      - `lookFrom` 'title' | 'epigraph' | 'sourceCredit' | 'nameSupers' | 'null', nullable, required: The opening element its look is borrowed from.
      - `backgroundOnly` boolean, required: True when only a background is borrowed: the card keeps its own type over it.
    - `fadeOut` object, nullable, required: Where the master fades the music (the score or the beds) and the bell lane out: from the closing's first frame to silence on the master's last (null while it does not play).
      - `fromSeconds` number, required
      - `toSeconds` number, required
  - `finish` Finish, required: The finish is a film look laid on the picture when the master is assembled: a look (camera, period-35mm, night-interior, none), an intensity (light, standard, strong; standard by default) and, optionally, single effects set to a level (adjust: { effect: off | subtle | medium | strong }; effects: steady-light, match-shots, halation, mist, shoulder, colour, vignette, weave, grain, soften). New decks and trailers start on camera. Titles and captions are laid after it, so type stays crisp, and the sound and timing are never touched. Setting it is free; on a rendered deck or trailer the master is assembled again with it (free), and setting the same finish again changes nothing.
    - `look` 'camera' | 'period-35mm' | 'night-interior' | 'none', required: The look: `camera` (Shot on a camera: fine moving grain, dense blacks under gently rolled-off highlights, a touch of mist on the lights, softer digital edges, steadied exposure and matched shots. No colour shift.); `period-35mm` (Period film: a muted 19th-century palette (warm candle and amber interiors, cold blue-grey exteriors, quieter greens and blues), a warm glow around flames, fine 35mm grain, a soft vignette and a very slight gate weave, with steadied exposure and matched shots.); `night-interior` (Candle and lamplight: cool shadows under warm highlights, a glow and a little mist around every flame, a deeper vignette and fine grain. The flame's own flicker is kept.); `none` (As rendered: no finish, the picture plays as it was rendered.).
    - `intensity` 'light' | 'standard' | 'strong', required: How strong: `light` (Barely there: every effect one step down (the grain and the invisible corrections stay on).); `standard` (Noticeable: the look as designed.); `strong` (Strong: every effect one step up.).
    - `adjust` object: Single effects set to an explicit level, over what the look and intensity give them.
      - `steady-light` 'off' | 'subtle' | 'medium' | 'strong': Steadies the exposure pumping from frame to frame, within each cut.
      - `match-shots` 'off' | 'subtle' | 'medium' | 'strong': Matches the colour and exposure of the shots inside a cut that share a room and its light, so they play as one camera; a shot set somewhere else is left alone.
      - `halation` 'off' | 'subtle' | 'medium' | 'strong': A warm red-amber glow bleeding from the brightest highlights, as on film.
      - `mist` 'off' | 'subtle' | 'medium' | 'strong': A faint mist around the lights, like a diffusion filter.
      - `shoulder` 'off' | 'subtle' | 'medium' | 'strong': A gentle highlight shoulder over dense blacks.
      - `colour` 'off' | 'subtle' | 'medium' | 'strong': Mutes over-saturated colour a little.
      - `vignette` 'off' | 'subtle' | 'medium' | 'strong': Darkens the corners a little.
      - `weave` 'off' | 'subtle' | 'medium' | 'strong': A very slight gate weave: the frame wanders a pixel or two.
      - `grain` 'off' | 'subtle' | 'medium' | 'strong': Fine moving film grain, strongest in the mid-tones and none in pure black or white.
      - `soften` 'off' | 'subtle' | 'medium' | 'strong': Takes the digital edge off, scaled to the resolution.
  - `camera` CameraReadSummary, required: The camera motion in a deck's or trailer's read: the handheld strength, and each unit the camera touches with its move and state (the full read is `/camera`).
    - `handheld` 'off' | 'subtle' | 'medium', required
    - `on` boolean, required
    - `units` object[], required
      - `unit` integer, required
      - `unitNumber` integer, required
      - `state` 'on' | 'waiting' | 'partly' | 'off', required
      - `move` CameraMove, nullable, required: A chapter's or beat's move, as chosen.
        - `move` 'snap' | 'reframe', required: `snap`: a snap zoom onto a reaction; `reframe`: a slow reframe from one face to another.
        - `shot` integer, required: The shot's number in the cut, 1-based.
        - `target` string, required: The face the move lands on.
        - `from` string, nullable, required: A reframe's first face.
        - `zoom` number, nullable, required: A snap zoom's zoom.
      - `moveState` 'applied' | 'dropped', nullable, required
      - `moveReason` 'moving' | 'speaks' | 'too_short' | 'not_found' | 'no_clean_framing' | 'letterboxed', nullable, required
      - `sentence` string, nullable, required
  - `warnings` string[], required: One per flagged take the writer kept (a line not heard or in another character's voice, an opening off its plan), which the finish quote and the export repeat; and one per chapter the master leaves out (`inMaster` false: "Chapter 6 is left out of the master: …").
  - `videoModelPreflight` PitchDeckVideoModelPreflight, required: Backend-owned asset truth for the deck's render: every chapter's cast (a body figure each on screen, a cast voice for a speaker) and location. A location with no plate yet reads `will_generate`: the render makes it first, as a plate line in the approval quote — the same list the quote prices. A location in a chapter that shows nobody by name and speaks no line in a cast voice reads `not_sent`: its render is built on no plate, so none is made or priced. `cast_face` and `character_sheet` items are informational and never block. Read only.
    - `ready` boolean, required
    - `checkedAt` string, date-time, required
    - `perCall` object, required: What ONE render call carries at most: one location plate (none for a call with no named character and no speech), `maxFigures` identity references, one speech track.
      - `plates` integer
      - `maxFigures` integer
      - `maxSpeechTracks` integer
    - `targetDurationSeconds` number
    - `blockingMissingCount` integer, required
    - `optionalMissingCount` integer, required
    - `error` string, nullable
    - `seriesBible` object
      - `ready` boolean
      - `missingFields` string[]
      - `href` string, nullable
    - `locationsMadeAtRender` string[], required: The rooms whose location plate the render makes first: exactly the rooms of the quote's plate lines (from the chapter's stored compile once it has one).
    - `chapters` object[], required
      - `chapterIndex` integer
      - `title` string
      - `compositionKind` 'image' | 'text' | 'both'
      - `visibleCharacters` string[]
      - `location` string, nullable
      - `speaker` string, nullable: The cast member whose voice speaks the chapter's line, or null (narrated, or no line).
      - `ready` boolean
      - `assets` object[]
        - `key` string
        - `kind` 'canonical_location' | 'cast_body' | 'cast_voice' | 'cast_face' | 'character_sheet' | 'text_composition' | 'cast_signature_items': `cast_signature_items`: what only this person wears or carries, required of everyone who shares a render with someone else (words in the prompt, never a file sent).
        - `label` string
        - `status` 'attached' | 'will_generate' | 'not_sent' | 'missing': `will_generate`: a plate the render makes first, a plate line in the quote. `not_sent`: the chapter's renders are built on no plate (nobody named on camera, no line in a cast voice), so none is made or priced.
        - `required` boolean
        - `sentToRender` boolean: True when the render sends this file (a plate, a body figure, a speech track in this voice).
        - `destination` 'series_bible' | 'casting' | 'table_read' | 'chapters'
        - `destinationLabel` string
        - `url` string, nullable
        - `note` string, nullable
        - `href` string, nullable: The app link that fixes this one item when it is fixed on one person's card on the project's Cast page (their signature items, pictures or voice).
      - `castBlocks` object[]: What the render would refuse this chapter for, found from its on-camera cast before anything is priced or compiled: the compile's own issue (`missing_signature_items`: a person who shares a render with someone else has no signature items), with its `message` and `action` (`add_signature_items` with `character`). The plan approval and its quote refuse with these at once (`pitch_deck_render_blocked`).
        - `code` string
        - `severity` string
        - `message` string
        - `action` object
    - `missingActions` object[], required
      - `destination` 'series_bible' | 'casting' | 'table_read' | 'chapters'
      - `label` string
      - `href` string, nullable
      - `blocking` boolean
      - `items` string[]
      - `links` object[]: The items fixed on one person's card on the project's Cast page, each with the app link straight to it.
        - `item` string
        - `href` string
    - `castHref` string, nullable: The project's Cast page in the app, where figures, signature items and voices are set (the episode's Casting tab for a screenplay in no project).
  - `assembly` MasterAssembly, required: `assembly` is the master being put together right now, null when nothing is being assembled: `stage` (the 480p `preview` or the `finished` cut), the `step` it is on (`cutting`: joining each chapter's or beat's chosen takes, with `unit` the one being joined and `done` of `total` joined so far; `text`: laying the on-screen text (a deck's finished cut only); `sound`: laying the voices, music and sound under the cut; `finish_look`: laying the finish look on the picture (only when one is set); `stitching`: stitching everything into one video, with `percent` from the renderer's own frame count; `delivering`: levelling the sound and saving the file), `steps` in order, `startedAt`, and `sentence`, which says it in words. Nothing renders and nothing is charged while a cut is assembled, and it cannot be stopped: it is free and ends on its own.
    - `stage` 'preview' | 'finished', required: Which master: the 480p preview the writer reviews, or the finished cut.
    - `step` 'cutting' | 'text' | 'sound' | 'finish_look' | 'stitching' | 'delivering', required: The step the assembly is on, in the order it runs them.
    - `unit` integer, nullable, required: `cutting`: the chapter or beat whose takes are being joined, by its number in the cut (from 1).
    - `done` integer, nullable, required: `cutting`: how many of this assembly's chapters or beats are joined so far.
    - `total` integer, nullable, required: `cutting`: how many chapters or beats this assembly joins (only the ones whose chosen takes changed).
    - `percent` integer, nullable, required: `stitching`: how far the stitch is, 0 to 100, from the renderer's own frame count.
    - `finishLook` boolean, required: Whether a finish look is laid on the picture (its step runs only then).
    - `title` string, nullable, required: What is being stitched, as the writer knows it.
    - `runtimeMs` integer, nullable, required: How long the cut being stitched runs, as planned.
    - `startedAt` string, date-time, required: When the assembly began.
    - `stepStartedAt` string, date-time, required: When the current step began.
    - `updatedAt` string, date-time, required: When the worker last reported. A record no worker has touched for twenty minutes is not returned.
    - `steps` object[], required: The steps this assembly runs, in order, each done, current or upcoming.
      - `step` 'cutting' | 'text' | 'sound' | 'finish_look' | 'stitching' | 'delivering', required
      - `label` string, required
      - `state` 'done' | 'current' | 'upcoming', required
    - `sentence` string, required: The assembly in one sentence, as every surface says it to the writer.
  - `reassembly` RenderReassembly, required: A deck's or trailer's free re-assembly. A cut whose `assemble` (the 480p preview) or `finish_assemble` (the finished master) failed for good lost nothing it paid for, and is put back together free from the takes it already has. A cut in `review` or `complete` has its master REBUILT, free and fresh, with the current sound rules: the preview assembly in review (`assemble`), the finished master stitched again at its class when complete (`restitch`, the cut stays complete).
    - `failedStage` string, nullable, required: The stage a FAILED cut failed in: rendering, assemble, finishing or finish_assemble. Null when it failed before the stage was recorded, and for a cut in review or complete.
    - `available` boolean, required: True when a re-assembly (or a rebuild) would run now (free: nothing rendered, upscaled or reserved).
    - `stage` 'assemble' | 'finish_assemble' | 'restitch' | 'null', nullable, required: The stage it runs: `assemble` / `finish_assemble` for a failed cut, `assemble` (review) or `restitch` (complete) for a rebuild; null when it is not available.
    - `refusal` string, nullable, required: Why it would be refused, in plain words (a rebuild: a master already being assembled, a take in flight, a finished take missing); null when it is available.
    - `leftOut` RenderReassemblyLeftOut[]: What a re-assembly that runs LEAVES OUT of the master. A deck's preview follows the master's rule: a chapter with no accepted take has no footage, so it is left out (the master plays the chapters around it) and named here — tell the writer which chapter is missing. Empty when nothing is, when it would not run, and always for a trailer and for the finished master (those refuse instead).
      - `name` string, required: How a person names it: "chapter 4".
      - `number` integer, nullable, required: Its place in the deck from 1 (the chapterNumber a person says).
      - `reason` string, required: Why it has no footage: the shot with no accepted take.
      - `message` string, required: The sentence to show: "Chapter 4 is left out of the master: … Render it again to put it back."
  - `verdict` VideoVerdict, required: `verdict` is the review in the writer's words — lead with it: `progress` (one line: rendering, fixing N shots the review flagged, ready to watch), `verdict` (one paragraph naming the problems that are left, by chapter or beat), `working` (true while the engine works: nothing to do but wait), and `choices` (at most two, only once it has stopped: `finish`, `finish_anyway` — the finish with `acknowledgeVideoCoverage` — or `more_fixes` with its `credits`), and `fixes` — ONE FIX FOR EACH PROBLEM `verdict` NAMES, in its order: `retake` (a new take of `callId`, or of the whole chapter or beat when it is null: the unit's render op, quoted first without `confirmed`) or `ask_slug` (nothing one action fixes from here: ask Slug with `problem` and `suggestion`). Offer each with its quoted price; never state a problem without its fix. The scores, findings, takes and checks stay in `videoCoverage`, the chapters' calls and `autoFix` for anyone who wants to step in.
    - `state` 'rendering' | 'assembling' | 'reviewing' | 'fixing' | 'ready' | 'your_call' | 'finishing' | 'finished' | 'failed', required
    - `working` boolean, required: True while the engine works and nothing needs the writer.
    - `progress` string, required: One plain progress line.
    - `verdict` string, nullable, required: One paragraph in the writer's words, naming the problems that are left.
    - `choices` object[], required: Empty while the engine works.
      - `action` 'finish' | 'finish_anyway' | 'more_fixes', required: `finish` and `finish_anyway` are the finish op (`finish_anyway` with `acknowledgeVideoCoverage: true`); `more_fixes` is the more-fixes op.
      - `label` string, required
      - `credits` integer, nullable, required: Known up front only for `more_fixes`; a finish is priced when chosen.
    - `fixes` object[], required: One fix for each problem `verdict` names, in its order. Empty when it names none, or while `more_fixes` is offered (that is the fix). Offer each with its quoted price.
      - `action` 'retake' | 'ask_slug', required: `retake`: the unit's priced render op for `callId` (null: every shot of the unit) — call it without `confirmed` for the price, then with `confirmed: true`. `ask_slug`: nothing one action fixes from here (a capture beat or title card has nothing to take again; the music; the plan): ask Slug with `problem` and `suggestion`.
      - `unitIndex` integer, nullable, required: The chapter's or beat's key; null for a problem outside one.
      - `unitNumber` integer, nullable, required
      - `callId` string, nullable, required
      - `label` string, required: The button: "Retake beat 4", "Fix beat 4 with Slug".
      - `problem` string, required: The problem it fixes, in the verdict's words.
      - `suggestion` string, required: What the review suggested; empty when it said nothing.
      - `startSeconds` number, required: Where the problem starts on the master.
  - `autoFix` AutoFix, required: `autoFix` is the AUTOMATIC FIXES: the approval quote carries an automatic-fix allowance for paid fixes beside the 480p render (`autoFixAllowance`), reserved with it — none for a cut with nothing a new take could redo (app captures, title cards) or a balance that holds only the render. FREE FIXES RUN WHATEVER THE ALLOWANCE: an app capture's narration the review hears off its picture is laid again on it (`kind: retime`, 0 credits), and a capture beat whose line is cut at the cut (or has no room to land on its press) keeps more of its recording (`kind: stretch`, 0 credits), and one whose picture goes blank for a frame at its start or end keeps a stretch that does not show it (`kind: trim`, 0 credits), and a unit whose narration is measured under the music has the music under it lowered (`kind: duck`, `duckDb`, 0 credits); free fixes run on a review that cleared the bar and after the rounds are run too. After the preview is stitched the engine watches it (video coverage) and retakes the shots the review flags — each new take told what the review saw, a shot at most twice, re-staged as a voice-over where the take rules allow — and renders flagged on-screen text again, inside the allowance; then it stitches and watches the preview again. It stops at a clean 480p preview (`state: clean`), when the allowance is spent (`no_allowance` when none was held), when the review flags nothing a fix can clear, or after `maxRounds` rounds (`state: stopped`, `stopReason`, `stoppedBecause`). `state` is `waiting` (first pass rendering), `reviewing` or `fixing` while it works — do not retake or finish then, just poll. `allowanceCredits` is the ceiling, `drawnCredits` what fixes took from it (each charged only when its take lands), `heldCredits` what is still reserved (released when it stops); `rounds[]` lists each round's fixes with `why`. When it stopped short, `moreFixes` (if not null) offers one more grant of `credits` (the more-fixes op, priced first); otherwise the writer finishes anyway. The 720p finish is always the writer's own approval.
    - `state` 'waiting' | 'reviewing' | 'fixing' | 'clean' | 'stopped', required: `waiting` (the first pass renders), `reviewing` (the preview is being watched), `fixing` (fixes are rendering), `clean`, or `stopped`.
    - `stopReason` 'clean' | 'allowance_spent' | 'cannot_clear' | 'rounds_spent' | 'review_unavailable' | 'writer_stopped' | 'finished' | 'no_allowance' | 'deleted' | 'null', nullable, required: Why it stopped (null while it works).
    - `allowanceCredits` integer, required: The ceiling approved for fixes: every grant together.
    - `drawnCredits` integer, required: What fixes drew from it (each charged only when its take lands; back to the writer when it fails).
    - `heldCredits` integer, required: What the allowance still holds for fixes; 0 once it stops (released).
    - `round` integer, required: Rounds of fixes run, never more than `maxRounds` (free fixes after the rounds are listed in `rounds` without counting as one).
    - `maxRounds` integer, required: The most rounds it runs.
    - `fixesInFlight` integer, required: Fixes still rendering.
    - `rounds` object[], required: Each round: the review it answered and the fixes it applied.
      - `round` integer, required
      - `reportId` string, nullable, required: The video coverage report it answered.
      - `overallScore` number, nullable, required
      - `startedAt` string, date-time, required
      - `fixes` object[], required
        - `kind` 'retake' | 'text' | 'retime' | 'stretch' | 'trim' | 'duck', required: `retake`: a new take of a shot; `text`: the unit's on-screen text rendered again; `retime`: an app capture's narration laid again on its picture; `stretch`: more of an app capture's recording kept so its narration fits (cut at the cut, or no room to land on its press); `trim`: an app capture's kept stretch moved off a blank frame measured at its start or end (`trim`); `duck`: the music under a unit whose narration was measured under it lowered by `duckDb`. `retime`, `stretch`, `trim` and `duck` are free, whatever the allowance.
        - `unitIndex` integer, required: The chapter's or beat's key.
        - `unitNumber` integer, required: Its place in the cut.
        - `callId` string, nullable, required
        - `take` integer, nullable, required
        - `credits` integer, required: What it drew from the allowance (0 when it could not start).
        - `ended` boolean, required: Its job has ended (landed, failed or refused).
        - `why` string[], required: What the review saw that it answers; a retake is told to avoid it.
        - `trim` object, nullable, required: `trim` only: the end of the beat the blank frames sat at and how many; null for every other kind.
          - `edge` 'head' | 'tail', required
          - `frames` integer, required
        - `duckDb` number, nullable, required: `duck` only: how many dB the music under the unit was lowered; null for every other kind.
    - `moreFixes` object, nullable, required: When it stopped short and one more grant could help: what that grant would hold (POST …/more-fixes). Null otherwise.
      - `credits` integer, required
    - `stoppedBecause` string, nullable, required: Why it stopped short of clean, in plain words.
    - `sentence` string, required: Where it stands, in one sentence.
  - `earlyLook` VideoEarlyLook, required: `earlyLook` (while the first pass renders; null once the preview exists) lists every chapter or beat whose shots all have a take, with each take's clip in shot order (`units[].clips[].url`), and `roughCut` once two have landed: they can be watched as they land, nothing to do. `musicPlan` is the music the cut will carry, known before the stitch: the beds on its timeline (`source: timeline`), or for a deck with none the table read's score as the assembly will lay it (`table_read_score`), each bed with the chapters or beats it plays under and a `url` to listen to — say it early, so a music change is made before the finish. A score to picture asked for (`score`, from a draft on) leads with its direction and, once its sketch to the planned cut is composed, `score.sketchUrl` to listen to; while one is asked for, the table read's beds are not laid or projected. When a score asked for with a direction could not be composed (`score.status: failed`), the beds are not laid in its place either: the sentence says so plainly ("The score couldn't be composed (reason in Details). The bell plays alone. Score to picture to try again.") — say it to the writer.
    - `units` object[], required
      - `unitIndex` integer, required
      - `unitNumber` integer, required
      - `title` string, required
      - `clips` object[], required
        - `callId` string, required
        - `url` string, required
        - `seconds` number, required
    - `of` integer, required: How many units have footage to render.
    - `roughCut` boolean, required: Two or more units have landed: a rough cut can play.
    - `sentence` string, required
  - `musicPlan` VideoMusicPlan, required: `earlyLook` (while the first pass renders; null once the preview exists) lists every chapter or beat whose shots all have a take, with each take's clip in shot order (`units[].clips[].url`), and `roughCut` once two have landed: they can be watched as they land, nothing to do. `musicPlan` is the music the cut will carry, known before the stitch: the beds on its timeline (`source: timeline`), or for a deck with none the table read's score as the assembly will lay it (`table_read_score`), each bed with the chapters or beats it plays under and a `url` to listen to — say it early, so a music change is made before the finish. A score to picture asked for (`score`, from a draft on) leads with its direction and, once its sketch to the planned cut is composed, `score.sketchUrl` to listen to; while one is asked for, the table read's beds are not laid or projected. When a score asked for with a direction could not be composed (`score.status: failed`), the beds are not laid in its place either: the sentence says so plainly ("The score couldn't be composed (reason in Details). The bell plays alone. Score to picture to try again.") — say it to the writer.
    - `source` 'timeline' | 'table_read_score' | 'none', required
    - `beds` object[], required
      - `label` string, required
      - `url` string, nullable, required: The bed to listen to (null while it is still being made).
      - `units` integer[], required: The chapters or beats it plays under, by their number in the cut.
    - `score` object, nullable, required: A score to picture asked for (from a draft on): its music direction, shown before anything renders, where it stands, and its sketch to the planned cut. While one is asked for, a deck projects none of the table read's beds: they are not laid under it.
      - `status` string, required: `waiting_for_master`, `queued`, `composing`, `laid` or `failed`.
      - `direction` string, nullable, required
      - `url` string, nullable, required: The laid score, once laid.
      - `sketchUrl` string, nullable, required: The sketch composed to the planned cut while the score waits for its master: listen before anything renders. Never laid; null until composed and once the score is on its way to the real cut.
    - `sentence` string, required
  - `videoCoverage` VideoCoverage, required: VIDEO COVERAGE of a deck's or trailer's stitched master: a model watched the video with its sound and scored its quality and its adherence to the shot list against a bar (`gateThreshold`, with `vetoDimensions` that fail it on their own). It runs by itself, free to the writer, when the 480p preview is stitched and again when the finished master is. While `blocksFinish` is true the finish is refused unless the writer finishes anyway; a report still running, one that could not run, an unavailable provider, or a report of an earlier master never holds the finish.
    - `status` 'missing' | 'generating' | 'complete' | 'failed', required
    - `planKind` 'pitch_deck' | 'trailer', required
    - `jobId` string, required
    - `stage` 'preview' | 'finished' | 'null', nullable, required: Which master the report watched.
    - `masterUrl` string, nullable, required: The master the report watched.
    - `currentMasterUrl` string, nullable, required: The master the cut has now.
    - `current` boolean, required: True when the report watched the master the cut has now.
    - `available` boolean, required: False when no provider can watch a video right now (that never holds the finish).
    - `gatePassed` boolean, required
    - `gateThreshold` number, required: The bar the composed overall and every veto dimension must reach.
    - `vetoDimensions` string[], required: Dimensions that fail the video on their own below the bar.
    - `gateReasons` string[], required: Every reason the bar was not cleared; empty on a pass.
    - `blocksFinish` boolean, required: True only when this report holds the paid finish: complete, of the current master, below the bar.
    - `summary` string, required: One sentence for the writer: where the coverage stands and what it means for the finish.
    - `trigger` 'auto' | 'manual' | 'null', nullable, required: `auto`: run after a stitch; `manual`: asked for.
    - `reportId` string, nullable, required
    - `reportVersion` integer, nullable, required
    - `rubricVersion` integer, nullable, required
    - `overallScore` number, nullable, required: The composed score the bar was decided on: the lower of the model's overall and the weighted dimensions — over the MEDIAN of each score when more than one watch judged it (`report.judging`).
    - `model` string, nullable, required
    - `progressDetail` string, nullable, required
    - `failureMessage` string, nullable, required: Why the run stopped, as one plain sentence for the writer — never a provider's or the database's raw wording. Populated when `status: failed`.
    - `report` VideoCoverageReport, required: What the model reported after watching the master with its sound: its quality and its adherence to the shot list, never its story.
      - `overallScore` number, required: The model's own holistic score. The bar is decided on the composed score (VideoCoverage.overallScore).
      - `verdict` 'pass' | 'needs_work' | 'fail', required
      - `oneLineDiagnosis` string, required
      - `dimensions` object, required: Each scored 0–10: lipSync (the right mouth moves to each line, in time; voice-overs over closed mouths), promptAdherence (each shot does what its call asked: framing, who is on screen, staging, room, camera), visualFidelity (artifacts, morphing, frozen or waxy faces, warped hands, burned-in text), motionNaturalness, identityContinuity (people, wardrobe, rooms), textPlacement (never over a face or other text, legible, a short dwell), audioSync, transitions (each cut follows the part before it by a link a viewer sees or hears).
        - `lipSync` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `promptAdherence` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `visualFidelity` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `motionNaturalness` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `identityContinuity` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `textPlacement` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `audioSync` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
        - `transitions` object, required
          - `score` number, required: The score the bar reads: the median across the watches that judged it, or the score carried from an earlier master with the same picture (`judging.dimensions`). A watch's dimension held down by its worst finding's severity (critical caps it at 4.0, major at 6.0) keeps the model's own number in `modelScore`.
          - `finding` string, required
          - `modelScore` number: Present only when the score was held down by a finding's severity: the model's own number.
      - `findings` VideoCoverageFinding[], required
        - `dimension` 'lipSync' | 'promptAdherence' | 'visualFidelity' | 'motionNaturalness' | 'identityContinuity' | 'textPlacement' | 'audioSync' | 'transitions', required
        - `severity` 'minor' | 'major' | 'critical', required: `critical`: a viewer cannot watch past it; `major`: clearly wrong; `minor`: noticed on a second look.
        - `startSeconds` number, required: Seconds from the start of the master (a player seeks here).
        - `endSeconds` number, required
        - `timecode` string, required: `m:ss–m:ss`, for a person.
        - `observation` string, required: Exactly what is on screen or heard that falls short.
        - `fix` string, required: The concrete production change that would fix it.
        - `shouldShow` string, required: What the picture should show there instead, in positive words that never name the problem; empty when no change to the picture fixes it. A new take of the shot (`retake_call`) is told this, never the observation.
        - `unit` object, nullable, required
          - `kind` 'chapter' | 'beat' | 'interlude' | 'title', required: `interlude` is a deck's black interlude between two chapters: `index` is the chapter it follows. `title` is a deck's title sequence.
          - `index` integer, required: The chapter's or beat's key (what every edit and render takes).
          - `number` integer, required: Its place in the cut, from 1: the number a person says.
          - `title` string, required
        - `callId` string, nullable, required: The render call playing at that moment (retake it with the render-clip op and this `callId`).
        - `shotIndex` integer, nullable, required: The shot inside that call, from 0.
        - `remedy` VideoCoverageRemedy, required: `retake_call`: render a new take of `callId` (priced); `rerender_text`: render the unit's on-screen text again (priced); `rescore`: the score laid under the master is measured silent there — score the cut to picture again (a retake never fixes dead air in the score); `revise_plan`: a cut that does not follow because the plan gives it no link (or one too weak to carry it) — give the unit its link in the plan (the chapter or beat refine: `whyItFollows`, and the look, object or sound staged in it); `trim_capture`: measured — the picture went blank for `frames` frames at the `head` or `tail` of an app-capture beat, and the beat keeps a stretch of its recording that does not show them (free, run by the automatic fixes); `lift_voice`: measured — the narration there sits only `gapLu` LU over the music between its lines, under the 6 LU it needs, and the automatic fixes lower the music under it (free; a mix, never a sync or a retake); `none`: nothing one action fixes.
          - `kind` 'retake_call' | 'rerender_text' | 'rescore' | 'revise_plan' | 'trim_capture' | 'lift_voice' | 'none', required
          - `gapLu` number: `lift_voice` only: how many LU the narration sits over the music between its lines, as measured on the master.
          - `callId` string
          - `edge` 'head' | 'tail': `trim_capture` only: the end of the beat the blank frames sit at.
          - `frames` integer: `trim_capture` only: how many blank frames were measured there.
        - `source` 'judge' | 'measured': Who saw it: `judge` (the model that watched the master) or `measured` (code measured it: a spoken line's mouth read against its voice on the take it plays from, or the score's dead air). A measured lip-sync miss holds the lip-sync score down (major 6.0, critical 4.0) whatever the judge scored: the judge cannot clear it. Absent on a finding stored before this was recorded (the judge's).
        - `uncertain` true: A measurement TOO CLOSE TO CALL: a quiet face read near its bar, or a pod reading of lips moving where no line is heard that the take watcher did not see too (a push-in, a flare or a smile reads the same). Severity minor: shown with its retake (`remedy`) for the writer to choose, never retaken by the automatic fixes and never holding a score down. Absent on every other finding.
      - `priorityFixes` string[], required: At most eight, most important first.
      - `judging` VideoCoverageJudging: HOW THE VERDICT WAS REACHED. One watch is too noisy to gate on near the bar (two watches of one frame-identical picture have scored prompt adherence 9.5 and 6.0), so a first watch within `nearGateMargin` of the bar is followed by a second, two watches on opposite sides of the bar by a third, and the bar reads the MEDIAN of each score. A master whose picture is frame-identical to an earlier judged master carries that report's picture scores (prompt adherence, visual fidelity, motion naturalness, identity continuity, text placement) and judges only lip sync, audio sync and transitions again — nothing at all when the sound is identical too. The rubric, the weights and the bar are unchanged.
        - `watches` VideoCoverageWatch[], required: This report's watches, in order (empty when every score was carried).
          - `watch` integer, required: 1, 2, 3 — in the order taken.
          - `reason` 'first' | 'near_gate' | 'disagreement', required: `first`; `near_gate`: the first watch sat within `nearGateMargin` of the bar (its composed overall or a veto dimension); `disagreement`: two watches sat on opposite sides of the bar on some gating score.
          - `model` string, required
          - `watchedAt` string, date-time, required
          - `overallScore` number, required: The model's own holistic number on this watch.
          - `composedScore` number, nullable, required: The bar's composed score for this watch alone, carried scores in place.
          - `gatePassed` boolean, required: Whether this watch alone cleared the bar.
          - `dimensions` object, required: Each dimension as this watch scored it, after its own findings' severity caps.
            - `lipSync` number, required
            - `promptAdherence` number, required
            - `visualFidelity` number, required
            - `motionNaturalness` number, required
            - `identityContinuity` number, required
            - `textPlacement` number, required
            - `audioSync` number, required
            - `transitions` number, required
          - `costUsd` number, required: What this watch counts against the extra-watch spend cap (USD).
          - `priced` boolean, required: False when the model has no price on file and `costUsd` is the flat per-watch estimate.
        - `dimensions` object, required
          - `lipSync` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `promptAdherence` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `visualFidelity` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `motionNaturalness` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `identityContinuity` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `textPlacement` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `audioSync` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
          - `transitions` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
            - `scores` number[], required: In watch order (carried: the carried report's own).
            - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
            - `watches` integer[], required: Which of this report's watches it used; empty when carried.
            - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
              - …
        - `overall` VideoCoverageScoreDistribution, required: How one score was decided: the scores of the watches it used and their median (the number the bar reads), or the report it was carried from.
          - `scores` number[], required: In watch order (carried: the carried report's own).
          - `median` number, required: The median of `scores` (an even count: the mean of the middle two) — equal to the report's score.
          - `watches` integer[], required: Which of this report's watches it used; empty when carried.
          - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
            - `reportId` string, required
            - `reportVersion` integer, nullable, required
            - `masterUrl` string, required: The master that report watched.
        - `carriedFrom` VideoCoverageCarriedFrom, required: The earlier report a score was carried from: a master of the same cut whose picture is frame-identical (its sampled decoded frames hash the same) and was asked the same things.
          - `reportId` string, required
          - `reportVersion` integer, nullable, required
          - `masterUrl` string, required: The master that report watched.
        - `stoppedBecause` 'decisive' | 'agreement' | 'max_watches' | 'spend_cap' | 'watch_failed' | 'carried', required: `decisive`: one watch, clear of the bar by the margin; `agreement`: two watches on the same side of the bar on every gating score; `max_watches`: three; `spend_cap`: another was wanted but this master's extra-watch spend cap was reached; `watch_failed`: another was wanted but could not run; `carried`: no watch, picture and sound identical to an earlier judged master.
        - `nearGateMargin` number, required: Within this many points of the bar a single watch is not trusted.
        - `maxWatches` integer, required
        - `extraSpendUsd` number, required: What this report spent on watches beyond its first (USD).
        - `extraSpendCapUsd` number, required: The most every report of one master may spend on watches beyond their first (USD).
        - `pictureFingerprint` string, nullable, required: Hash of the master's sampled decoded frames and what each part was asked to show (null: not measured).
        - `soundFingerprint` string, nullable, required: Hash of its decoded sound on that picture and what it was meant to sound like (null: not measured, or no sound).
      - `lipSync` VideoCoverageLipSync: MEASURED LIP SYNC: every spoken line of the master, measured on the take it plays from. The judge is shown these; each `miss` is also a `measured` lip-sync finding.
        - `metricVersion` string, required: The mouth check's code version the lines were judged under.
        - `lines` VideoCoverageLipSyncLine[], required
          - `unit` object, nullable, required
            - `kind` 'chapter' | 'beat', required
            - `index` integer, required
            - `number` integer, required
            - `title` string, required
          - `callId` string, required: The render call the line plays from (a miss is retaken with the render-clip op and this `callId`).
          - `take` integer, nullable, required: The selected take the master plays.
          - `lineRef` integer, required
          - `speaker` string, required
          - `text` string, required: The line's words.
          - `voice` string, required: `on_camera`, `voice_over` or `off_screen`.
          - `startSeconds` number, required: Where it is spoken, in seconds of the master.
          - `endSeconds` number, required
          - `timecode` string, required
          - `verdict` 'pass' | 'miss' | 'uncertain' | 'not_measured', required: `miss`: a measured miss — also a `measured` lip-sync finding the judge cannot clear; `uncertain`: a reading inside the band around its limit (neither); `pass`; `not_measured`: no face could be read or the check never ran (a take watcher's look is not a measurement) — the judge's own look decides it.
          - `severity` 'minor' | 'major' | 'critical', nullable, required: A miss's severity: `critical` when the mouth does not move at all or the wrong face speaks the line, else `major`. Null otherwise.
          - `criteria` object[], required: Each criterion missed or uncertain, misses first: the face, `criterion` (`correlation`, `lag`, `trailing_motion`, `articulation` — the lips barely part under the voice — `articulation_stretch`, `still_open_run`, `still_open_share`, `still_openings`, `watcher_lip_sync`), its `value`, its `limit` and its `words`.
            - `name` string, required
            - `role` 'speaker' | 'still', required
            - `criterion` string, required
            - `outcome` 'fail' | 'uncertain', required
            - `value` number, required
            - `limit` number, required
            - `words` string, required
          - `reason` string, nullable, required: Why it missed, is uncertain, or could not be measured, with the numbers. Null on a pass.
          - `faceHeightPx` number, nullable, required: The speaker's face height in the take's pixels.
          - `correlation` number, nullable, required: The speaker's mouth against the voice (r at the best lag).
          - `voicedOpenness` number, nullable, required: The speaker's mean openness under the voice, 0 closed to 3 wide (a speaking mouth averages at least 1.35).
          - `rejudged` boolean, required: True when the take's stored reading was judged again under the current numbers against the voice it was sent.
      - `transitions` VideoCoverageTransition[], nullable: EVERY CUT of the master, in order, and whether it follows the part before it. Each cut that is `weak` or `lost` is also a `transitions` finding with the same remedy. Absent on a report written before cuts were judged.
        - `from` object, nullable, required
          - `kind` 'chapter' | 'beat' | 'title', required
          - `index` integer, required
          - `number` integer, required
          - `title` string, required
        - `to` object, required
          - `kind` 'chapter' | 'beat' | 'title', required
          - `index` integer, required: The key every edit takes.
          - `number` integer, required
          - `title` string, required
        - `atSeconds` number, required: Where the cut falls, in seconds of the master.
        - `timecode` string, required: `m:ss`, for a person.
        - `verdict` 'follows' | 'weak' | 'lost', required: `follows`; `weak` (the link is faint, or half carries the viewer); `lost` (nothing connects the two: a non-sequitur).
        - `observation` string, required: What carries a viewer across the cut — the look, the object, the sound, the cause, the contrast — or what is missing.
        - `planned` string, nullable, required: The link the plan states for this cut (`whyItFollows` of `to`), or null when it states none.
        - `plannedLink` 'seen' | 'not_seen' | 'none_planned', required: Whether the watcher saw or heard the planned link: `seen`, `not_seen`, or `none_planned` (always, when the plan states none).
        - `fix` string, required: The concrete change that makes the cut follow; empty when it follows.
        - `remedy` VideoCoverageRemedy, required: `retake_call`: render a new take of `callId` (priced); `rerender_text`: render the unit's on-screen text again (priced); `rescore`: the score laid under the master is measured silent there — score the cut to picture again (a retake never fixes dead air in the score); `revise_plan`: a cut that does not follow because the plan gives it no link (or one too weak to carry it) — give the unit its link in the plan (the chapter or beat refine: `whyItFollows`, and the look, object or sound staged in it); `trim_capture`: measured — the picture went blank for `frames` frames at the `head` or `tail` of an app-capture beat, and the beat keeps a stretch of its recording that does not show them (free, run by the automatic fixes); `lift_voice`: measured — the narration there sits only `gapLu` LU over the music between its lines, under the 6 LU it needs, and the automatic fixes lower the music under it (free; a mix, never a sync or a retake); `none`: nothing one action fixes.
          - `kind` 'retake_call' | 'rerender_text' | 'rescore' | 'revise_plan' | 'trim_capture' | 'lift_voice' | 'none', required
          - `gapLu` number: `lift_voice` only: how many LU the narration sits over the music between its lines, as measured on the master.
          - `callId` string
          - `edge` 'head' | 'tail': `trim_capture` only: the end of the beat the blank frames sit at.
          - `frames` integer: `trim_capture` only: how many blank frames were measured there.
    - `createdAt` string, date-time, nullable, required
    - `updatedAt` string, date-time, nullable, required

## Other responses

- `401`: Missing, malformed, revoked, or expired API key.
- `403`: API key is valid but lacks the scope, is blocked by IP allowlist, or the account is disabled.
- `404`: The named project or source does not exist or is owned by another account.
- `429`: Rate limit for this API key + IP + route family was exceeded.
- `500`: The API failed unexpectedly. Safe to retry with the same Idempotency-Key.

---

[API](https://skmtc.dev/sleeperhit/apis/sleeper-hit-studio-story-api.md) · [All operations](https://skmtc.dev/sleeperhit/apis/sleeper-hit-studio-story-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sleeperhit/apis/sleeper-hit-studio-story-api/revisions/4534f5d25540?raw)
