Agents & MCPTool reference

Look and check

Frames, motion strips, sync and layout findings over any stretch of the film. 21 tools.

On the main list

The tools a client sees when it connects.

look

Main list

Look at a stretch of the film

Free. One feedback call over any window on the FILM clock: a scene, a chapter, or {from, to} seconds across cuts. show: "frames" (one sheet across the window, each cell labelled #scene and film seconds), "motion" (review_motion over each scene's part: filmstrips, faults outlined), "sync" (picture against sound), "compare" (each scene against the project reference: DINO/CLIP distances per moment, worst moments side by side, density, layout overlap and palette, and any gap in the source store under it; with against_image_url it compares the scene with ONE picture instead; with against {scene_id} it scores the scene against ANOTHER scene, same project or any you can read, e.g. a cheap model's scene against a known-good one), "timing" (each aligned scene's start offset, length and added drift against the reference and its nearest cut), "sound" (tempo, cuts on the beat and on hits, sound density and SFX on cuts, reference against replica), "curve" (one element's motion measured on both sides: fitted ease, travel, shape error, halfway-point offset; needs window {scene_id} and curve {roi, dim}), "player" (the same film times shot in the chapter document the share page and editor player play, preview | player side by side, a finding where viewers see a different picture; implies frames: run it before calling a scene done). Every finding comes back in ONE list on the film clock, worst first; errors names any part that could not be checked. Default show ["frames"], 8 frames. Use it after landing a run of scenes instead of one preview per scene; async: true for a chapter with motion.

async: true answers at once with a job_id; jobs {id} reads the result (no 60 s timeout).

InputTypeDescription
project_id requiredstringProject id.
windowobject{scene_id} | {chapter_id} | {from, to} (film seconds). Omit for the whole film.
showarrayEvidence to gather. Default ["frames"].
preset"quick" | "motion-check" | "layout-check" | "sync-check" | "player-check" | "dense-motion"A saved look: fills show, frames and fps you leave out.
against_image_urlstringWith show "compare": compare each scene in the window with this one picture instead of the reference (no alignment needed).
againstobjectWith show "compare": score each scene in the window against ANOTHER scene instead of the reference: {scene_id} (same project or any project you can read; no alignment needed). Both scenes are previewed at the same proportional moments; same DINO/CLIP distances, density, layout and palette as the reference compare.
atnumberWith against_image_url: scene time (s) to take the replica frame at (one-scene window).
curveobjectWith show "curve" (window {scene_id}): which element to follow. roi = region as fractions of the frame [x0, y0, x1, y1] around the element; dim = w | h | cx | cy (default w); from/to = scene seconds; thr = ink threshold (default 215 light, 60 dark); polarity = light | dark ink; samples 6-24 (default 12); ref_shift = seconds to shift the reference clock.
framesnumberFrames on the sheet (1-24, default 8; every scene in the window gets one).
fpsnumberMotion samples per second (default 2).
detail"auto" | arrayWith show "compare": also measure realism cues (glow falloff and strength, lit rim, edge width, grain, screen weave, colour fringe) on one region of each scene's worst-matching moment, reference against replica, as numbers plus a finding per cue that misses. "auto" = the centre of the frame, or [x0, y0, x1, y1] as fractions of the frame (0-1) around the pane or hero.
asyncbooleanStart the call as a job and answer at once with {job_id}. Read it with jobs {id, wait_sec: 50}: the same result this call returns. Use it whenever the call may take more than about 30 s.
idempotency_keystringWith async: any string unique to this call. A retry with the same key joins the job already started instead of starting another.

analyze_video

Main list

See a reference video shot by shot

Shots, sheets, transcript, beats. Long? sections=parts.

InputTypeDescription
urlstringA direct http(s) url of the video file.
media_asset_idstringA library video (from list_media, ingest_video_url or an upload).
transcribebooleanTranscribe the audio (default true).
sectionsarray[{start,end}] s: only these parts.

Callable by name

Not listed on connect, to keep the list short. Call them directly by name, or find them with tools.

check_continuity

Check continuity at every cut

The continuity receipt: for each shot (scene, in film order) reads the state the pinned modules RENDERED at its first and last frame — the frame_report mount and seek — and compares it against the bible's ledger rows (get_bible parts:["ledger"]: per shot, declared entry/exit of cast, props with their layer, and the set with pan and camera) and against where each object was last on screen. Only module-drawn state counts: a prop a shot merely claims is flagged. seed:true writes rows for shots that declare nothing, from what they rendered. Up to 24 shots per call. Free.

InputTypeDescription
project_id requiredstringProject id.
scene_idsarrayOnly these scenes. Default: the project, in order (first 24).
seedbooleanFill undeclared ledger rows from the rendered probe and write the bible.

check_requirements

Read-only

Check what a template needs

Ask what a template requires BEFORE creating anything. Creates nothing, spends nothing. Returns what the workspace presets already cover, what is still missing and why, and what is optional — so you ask the user the two questions that actually matter instead of guessing at twenty fields or eating a 400. For a configured workspace the answer is usually just "a topic or a script".

InputTypeDescription
template_slug requiredstringTemplate slug from list_catalog("templates").
workspace_idstringWorkspace the project would belong to.

check_sync

Do picture and sound hit together?

Proof, for a model that cannot hear, that the picture and the sound land together — and exactly where they do not. Free; a few seconds per scene.

Picture: every scene's composition is mounted and its tweens read off the timeline, reduced to hit-like moments — cuts (big instant visibility changes, and the cut into each scene), instant sets/jumps, and scale/opacity/position/rotation/shape moves with a SHARP ease (expo, power3, back, bounce; not linear or sine), timed where the move's speed peaks (an inOut also counts where it arrives). A stagger or a cascade is one gesture. Sound: the music beds' analysis (onsets, kick/snare/hat, notes, salient hits, section changes), SFX / seam / marker cues, a placed score's own trigger map (read automatically: its impacts, whooshes, pops and other sound-design hits), and any extra onsets you pass (film seconds).

Returns, on the FILM clock with bar:beat: unsounded_motion (a hit with no sound within tolerance, and the nearest sound's signed offset), unmotivated_sound (an ACCENT — salient hit, section change, placed SFX, score cue, your onsets unless accent:false — with nothing moving on it), weak_sync (it hits, but only a sound too quiet to hear), and a summary with median/p90 offsets. The steady pulse of a bed is not an accent. detail: true lists every matched pair.

InputTypeDescription
project_id requiredstringProject id.
scene_idsarrayOnly these scenes (and the sound under them). Default every placed scene (max 40).
tolerance_msnumberHow far apart still counts as together. Default 40.
onsetsarrayExtra sound onsets on the FILM clock (a placed score's triggers are already read; this is for hand-placed hits): { t, source?, kind?, strength? 0-1, accent? (default true), label? }.
detailbooleanAlso list every matched pair [film s, offset ms, picture kind, sound].

compare_images

Compare pictures side by side

Up to 12 pictures side by side on ONE numbered sheet, with numbers per picture: sharpness, contrast, brightness, colourfulness (0..1) and, with reference_url, match (0..1, how close it stays to the reference in layout and colour). For the end of a fan-out: one prompt across several models (generate_image each over models → compare_images {items: "$imgs"}), several models editing one picture (reference_url = the original), several video models (video_frame each → compare). by picks best by one measure (default match when there is a reference), outlines it and draws a bar per cell; a chain carries it on as "$cmp.best.url". These are measurements, not taste: look at sheet_url before you trust best. items takes urls or step results with a url; a failed element (null) shows as a grey cell. Labels default to the model that made each picture. Free; seconds.

InputTypeDescription
items requiredarrayPictures: urls, or results with a url (e.g. "$imgs" after an each step).
labelsarrayOptional names, one per item (default: the model, when the result says).
reference_urlstringThe picture they should stay close to (the original being edited, the frame a clip starts from).
by"match" | "sharpness" | "contrast" | "colourfulness"Pick best by this measure.

compare_takes

Compare two versions of a scene

Two versions of one scene side by side: title, length, thumbnail, script size and the list of composition fields that differ. a and b are take ids from scene_takes, or "current" for the scene as it is now (b defaults to current). To SEE them, switch with scene_takes and share_scene / preview_composition. Scripts are not returned. Free.

InputTypeDescription
scene_id requiredstringScene id.
a requiredstringA take id, or "current".
bstringA take id, or "current" (default).

compare_to_reference

How close is this project to the one it was made from — measured

Check a replica against its reference WITHOUT a person watching two videos. Both projects are read with the same extractor (get_project_gist) and diffed on the things that make a video feel like itself: the ground, ink and accent colours (measured from pixels), how long scenes run, how much the picture changes inside them, how much text arrives, narration pace and sentence length. Returns an overall figure and each measure lowest first, with what to change ("the dominant ground is 91 ΔE away: use #ffffff"). Build from get_project_gist, then call this, then fix what scores low. Fidelity of FORM only: it cannot say whether the replica is any good. project_id is the replica; reference_id is the project it should match. Free; draws the two gists when they are not cached (a cold draw can take a few minutes). When the reference is a VIDEO (a link, an upload) rather than a project, and the question is the PACE (cuts, camera, punches, subject motion, cadence): analyze_video your render and read it with get_video_analysis compare_to: <the reference's analysis id>.

InputTypeDescription
project_id requiredstringThe replica — the project being checked.
reference_id requiredstringThe reference — the project it was meant to match.

frame_report

What is actually on screen

Check what a composition REALLY shows at given times — as facts, no screenshots. Free. Use it after every write, and before you call a scene done: it is how a model without eyes (or with weak ones) sees its own work.

Pass scene_id (times on the scene clock) or html (a draft you have not landed; times on its own clock), and up to 64 times. Per time, every visible element (named by data-tc-anchor, data-wire-id, id, or tag.class plus what it says) comes back with its box on the composition canvas, how much is in frame, whether an overflow:hidden ancestor clips it (and which), whether its text overflows its box, its glyph size when the frame is shown 360 px wide on a phone (portrait and square frames, or any frame when you pass width; a 16:9 film is not phone-checked by default), its contrast against what is painted underneath (null over an image), whether something covers it and which text it overlaps. Also: when each element is visible across the whole timeline, fonts that failed to load, and — when the composition carries a tc-wire spec — planned vs real box per layer per beat.

findings is the short version: one line per defect per element, with every time it was seen (TEXT-CLIPPED, TEXT-SPILLS-BOX, TEXT-OFF-FRAME, TEXT-SMALL-ON-PHONE, TEXT-LOW-CONTRAST, TEXT-COVERED, TEXT-OVERLAP, TEXT-FAINT, and the wire flags). Empty findings means nothing measurable is wrong — not that it looks good.

InputTypeDescription
scene_idstringScene to inspect. Times are scene-clock seconds. Give this OR html.
htmlstringA composition you hold (not yet landed). Times are on its own clock. Give this OR scene_id.
timesarrayWhen to inspect: seconds (3.2), or text resolved against the scene length: "end" (the last frame), "50%", "end-0.5s", "start", "1:05". Numbers are unchanged. Text that needs the scene length (end, %) needs scene_id. Max 64. Default with scene_id: start, 50%, end; with html: 0.
element_idstringScene form only: limit to one composition element.
widthnumberWidth the glyph-size check scales the frame to (a phone is 360). Passing it turns the check on for a landscape frame too; portrait and square frames are checked at 360 by default.
stepnumberVisibility-timeline sample step in seconds. Default 0.5; 0 turns the scan off.

inspect_composition

Read-only

Inspect a composition's inner units

Read the inner structure of a scene's gen:html motion-design composition(s): every visual UNIT with its key, label, text, kind, colour, group structure (parent/children) and animation windows. Call this BEFORE edit_composition_unit — unit keys come from here. Keys starting "sel:" or "@" are inspect-only (not editable directly).

InputTypeDescription
scene_id requiredstringScene id.
element_idstringLimit to one composition element. Omit for all.

inspect_image

See what is in a picture (edges, colours, depth)

What is in ONE picture, since a description is not the picture: one sheet, cells numbered as sheet_cells (picture, edges, depth), with its palette underneath, plus numbers: width, height, has_alpha, tone {brightness, contrast}, sharpness and colourfulness (0..1), palette [{hex, share}] most used first, edges {density (0.05 calm, 0.25+ busy), focus {x, y} (where the detail sits), quietest (the emptiest third: a place for type), grid}, and with depth depth {near, far, spread (0 flat, 0.3+ layered), url}. Use it on a picture you made or found before you place it: does it leave room for the title, is it too busy behind text, which colours to pull into the theme, does it have layers for parallax? show: edges and palette (default, free: one look frame); add "depth" for the depth model (1 credit, needs project_id). generate_image takes the same as check.

InputTypeDescription
urlstringThe picture: an https url (a generate_image or find_media result; "$img.image.url" in a chain).
asset_idstringOr a library image asset id.
project_idstringNeeded only for depth (the credit is billed to it).
showarrayViews (default edges + palette).

listen

Hear a stretch of the film

Free. HEAR the film the way look sees it: the export's own mix of {from_sec, to_sec} on the film clock (at most 120 s; default 60 s), measured whole and per group: dialogue (narration + scene speech), music (cues, beds), effects (SFX, scene sounds). Returns short-term LUFS every 0.5 s per group, integrated LUFS and true peak with a delivery verdict against -14 LUFS / -1 dBTP, outliers (any sound more than outlier_db, default 6, above its surroundings, named by its cue / sound / scene and film second), masking (where music or effects come within mask_db, default 6, of the voice in 1-2 / 2-4 kHz while it speaks; the voice-over-bed ratio), and verdicts in words ("sound "whoosh" in scene #4 at 12.4 s is 9 dB above everything around it"). bounce: true also hosts an m4a of the window for an audio model. Use it after set_music, voicing or placing sounds, before render. Fix with apply_changes (levels, ducking) and listen again.

async: true answers at once with a job_id; jobs {id} reads the result (no 60 s timeout).

InputTypeDescription
project_id requiredstringProject id.
from_secnumberWindow start, film seconds (default 0).
to_secnumberWindow end, film seconds (default from_sec + 60; at most from_sec + 120).
bouncebooleanAlso host a short m4a of the full mix of the window (bounce_url).
mask_dbnumberMasking threshold: the bed within this many dB of the voice in the speech band (default 6).
outlier_dbnumberOutlier threshold: dB above the surroundings (default 6).
fixbooleanAlso turn each outlier down to 3 dB above its surroundings (one undoable change); sounds a person leveled by hand are only flagged.
asyncbooleanStart the call as a job and answer at once with {job_id}. Read it with jobs {id, wait_sec: 50}: the same result this call returns. Use it whenever the call may take more than about 30 s.
idempotency_keystringWith async: any string unique to this call. A retry with the same key joins the job already started instead of starting another.

measure_elements

How two elements relate

The relation between TWO elements, as numbers: the offset from a to b (centre to centre), the edge gap (positive = clear space, 0 = touching, negative = how deep they overlap), overlap (IoU) and containment both ways, alignment on each edge and axis, and which one is painted on top. Over a range (default) you also get the closest and farthest moment, when they first touch, the intervals they overlap and the intervals they are centre-aligned; with at you get exactly those seconds. Read straight from the page, exact, a couple of seconds, free. Use it for "how far is this label from that card", "does the callout ever cover the caption", "when do the two meet".

a and b: a CSS selector, a name (an id, data-tc-anchor, data-wire-id or data-k) or "text:some words". basis:"ink" measures the text's own rectangles instead of the element boxes (a wide centred title is not as wide as its box). Times are the scene clock (scene_id) or the draft's own (html). track_element follows one element's own motion.

InputTypeDescription
scene_idstringScene to probe (scene clock). With html, the draft is probed inside this scene.
htmlstringA draft composition (not yet landed). Without scene_id, times are on its own clock.
a requiredstringFirst element: a CSS selector, a name, or "text:some words".
b requiredstringSecond element. Offsets are b minus a.
atarrayThe relation at exactly these seconds. Omit for a range.
basis"box" | "ink"box (default) or ink (the text's own rectangles).
fromnumberRange start, seconds. Default 0.
tonumberRange end, seconds. Default the end.
hznumberRange samples per second. Default 20.
element_idstringScene + html: which composition element the draft replaces.
widthnumberBare draft only: canvas width (default: the draft's own, else 1920).
heightnumberBare draft only: canvas height.
durationnumberBare draft only: duration in seconds (default: the draft's own, else 10).

preview_composition

See the real frames

Render real frames of a composition EXACTLY as the final MP4 will show them — the same document, on the same GPU renderer, through the same capture pipeline. Free. Use it when you need to SEE the picture (frame_report gives facts without pixels and is cheaper; use both).

Pass scene_id (times on the scene clock) or a draft you have not landed — html, or src_url (a create_upload public_url: upload once, preview it as often as you like, nothing landed and nothing heavy in your context); add scene_id to see the draft inside that scene — and up to 24 times. Returns frames (one PNG URL per time), determinism, kernels, findings, summary and mounted (false when an element failed to mount: a MOUNT-FAILED finding, and the frames show an empty scene).

determinism is the render-twice check that decides whether the composition is safe to render at all: each check time is taken COLD and after seeking elsewhere and back (seek-order — fails on per-frame counters, rAF loops, unseeded randomness), and before and after the composition's scripts run a SECOND time (double-mount — fails on a from() that ends hidden, or DOM appended twice). Each failure carries a diff_url image. kernels lists what the kernels compiled and every moment they could not resolve (a data-tc-at that named no word, an unresolved relation); their raw tables only with verbose:true. A cold renderer or a heavy scene can take over a minute: then the call answers within ~40 s with {status: "running", preview_id} and keeps rendering — call again with just preview_id: it holds up to 45 s for the frames, so one read-back usually covers it. Retry on unavailable. With more than one time you also get sheet_url — all frames in ONE labelled image — and it is attached to the result as an image, so you look once instead of reading N URLs (sheet:false turns it off; a single time attaches its frame). quick:true answers in seconds (CPU, half scale, sheet on, no determinism): iterate with it, then prove once without.

async: true answers at once with a job_id; jobs {id} reads the result (no 60 s timeout).

InputTypeDescription
scene_idstringScene to render. Times are scene-clock seconds. With html, the draft is previewed inside this scene.
htmlstringA draft composition (not yet landed). Without scene_id, times are on its own clock.
src_urlstringThe draft by URL instead of html: a create_upload public_url. Prefer it for anything larger than a few KB.
timesarraySeconds to render, e.g. just after each beat lands. Max 24.
element_idstringWhich composition element the draft replaces (scene + html).
widthnumberBare draft only: canvas width. Default 1920.
heightnumberBare draft only: canvas height. Default 1080.
durationnumberBare draft only: duration in seconds. Default 10.
determinismbooleanRun the render-twice determinism check. Default true.
compare_mp4booleanScene form only: also diff each frame against the scene's rendered MP4 at the same frame.
verbosebooleanAlso return the kernels' raw tables (tc-tick bindings, root stamps; ~15 KB). Default false.
sheetbooleanReturn sheet_url (every frame in ONE labelled image, attached inline). Default true when more than one time; false turns it off.
quickbooleanDraft speed: seconds instead of a GPU minute — the warm CPU renderer at half scale, sheet_url included, no determinism check. Iterate with quick; run once without it to prove the final frames.
preview_idstringRead back a preview that answered {status: "running"} — pass only this.
asyncbooleanStart the call as a job and answer at once with {job_id}. Read it with jobs {id, wait_sec: 50}: the same result this call returns. Use it whenever the call may take more than about 30 s.
idempotency_keystringWith async: any string unique to this call. A retry with the same key joins the job already started instead of starting another.

preview_frames

See the real frames

Real PNG frames of a scene (or a draft: scene_id + html) at chosen seconds, with a determinism check. Look frames.

InputTypeDescription
scene_idstringScene to render.
htmlstringA draft composition (not yet landed).
timesarraySeconds to render, e.g.
preview_idstringRead back a preview that answered {status: "running"} — pass only this.
asyncboolean

preview_scenes

Check what is on screen

Check ≤10 landed scenes at given seconds: clipping, contrast, phone glyph size → findings ("full" adds boxes). Free.

InputTypeDescription
scenes requiredarrayScenes (+ own times).
timesarrayDefault times.
detail"findings" | "full"Default findings.

review_motion

How does it move?

Watch a scene MOVE, as ONE image: a filmstrip of the whole scene (default 2 frames a second, each labelled with its time) with every motion fault outlined where and when it fires, plus flags. Stills cannot show these — a scene can pass every preview frame and still look wrong in motion. Free, a few seconds; call it after landing any scene that moves pictures around, and before you call the scene done.

Flags (each with found, fix, at/until seconds and evidence):

  • plate-smear (error): a cutout leaves its spot on a clean plate and the hole it uncovers is a SMEAR (the inpaint shows; measured on the plate under the cutout's silhouette). Outlined red.
  • plate-hole: the same hole uncovered, texture plausible — look at it. Orange.
  • sticker-slide: a flat photographic cutout slides across a photographic plate as one rigid picture (nothing in it moves) — it reads as a sticker. Yellow while it moves.
  • jump: an element moves far more in one sample than anywhere else on its path (a teleport). Magenta.
  • blank-start / blank-end (warn): the first / last 0.25 s is near-empty (ink under 1.5 %): a hero not visible by t<=0.15 s, or an empty close. blank-run: near-empty for 0.4 s or more (error from 1 s). sparse-run (info): under 2 % ink for 1.5 s. Each gives the ink % and time; silence means pass. Fix before rendering: hero in by 0.15 s, never wait for the word. position first|last exempts the film's ends.
  • dead-stretch (nothing changes for seconds), flicker, slow-frames (per-frame render ms over budget, usually a heavy WebGL shader — production renders WebGL in software too), webgl, mount-failed (the composition never registered its timeline: fix that first).

Pass scene_id (a landed scene; add html or src_url to review a draft inside it) or html / src_url alone (a draft on its own clock; src_url is a create_upload public_url). from/to narrow the window, fps samples denser (max 8; at most 48 frames). mp4_url (+ from/to) checks a FINISHED MP4 instead (ink flags only, no filmstrip). critique: true also asks a vision model about the filmstrip with your brief and questions (e.g. "does the tram read as pulling away?") — about a tenth of a cent, booked to us. backend: "gpu" renders it on the MP4 renderer instead (slower; for milestone checks). Use preview_composition for MP4-exact stills at chosen times, frame_report for layout facts.

async: true answers at once with a job_id; jobs {id} reads the result (no 60 s timeout).

InputTypeDescription
scene_idstringScene to review (scene clock). With html, the draft is reviewed inside this scene.
htmlstringA draft composition (not yet landed). Without scene_id, times are on its own clock.
src_urlstringThe draft by URL instead of html: a create_upload public_url.
element_idstringScene + html: which composition element the draft replaces.
mp4_urlstringA finished MP4 URL: blank flags only.
position"first" | "last" | "only"Scene position in the film; first/last exempt the open/close.
fpsnumberSamples per second. Default 2; max 8 (capped at 48 frames).
fromnumberWindow start, seconds. Default 0.
tonumberWindow end, seconds. Default the end.
widthnumberBare draft only: canvas width (default: the draft's own, else 1920).
heightnumberBare draft only: canvas height.
durationnumberBare draft only: duration in seconds (default: the draft's own, else 10).
backend"cpu" | "gpu"cpu (default) or gpu (the MP4 renderer, for milestone checks).
critiquebooleanAlso ask a vision model about the filmstrip (with brief + questions).
briefstringWhat the scene is meant to show — sharpens the critique.
questionsarrayMotion questions for the critique, ≤300 chars each.
asyncbooleanStart the call as a job and answer at once with {job_id}. Read it with jobs {id, wait_sec: 50}: the same result this call returns. Use it whenever the call may take more than about 30 s.
idempotency_keystringWith async: any string unique to this call. A retry with the same key joins the job already started instead of starting another.

review_scene

Accept or reject a scene

Record the person's explicit verdict on a scene: accept (keep it as it is) or reject (it is not what they want), with a one-line reason. Use it when the user says so ("this one is perfect", "scene 3 is wrong"). It changes nothing about the scene: it is the signal that the generation was right or wrong. A reject is usually followed by a fix; link the fix to the comment with resolve_comment. Free.

InputTypeDescription
scene_id requiredstringThe scene.
verdict required"accept" | "reject"
reasonstringWhy, in the person's words (≤1000 chars).
comment_idstringThe review comment this verdict answers, if any.

score

Read or write the project SCORE — music and sound design as one document on the film clock

One sound document per project, rendered server-side into stems, placed under the film, and returned with a trigger map (hit:<track>.n rulers the picture can bind to) and EARS (loudness, per-track level against the mix, music under the voice, plain-language verdicts). Tracks play groove voices (kick, clap, hat, fmbass, stab, pluck, strings, piano, …), sound design (impact, boom, braam, riser, whoosh, downlifter, sub-drop, zap, blip, zip, chime, …), foley.<job>, library samples (lib:<slug>, see search_sfx) or a raw synth, on anchors that follow the film: seconds, bar:3:2, beat:17, word:launch#2, scene:<id>[@end], each with an optional musical offset (+1/8, -0.2s, +1bar). Buses, reverb/delay sends, ducking and automation. dry_run validates and resolves for free; range renders a window to audition; place renders ONLY the span a sound uses (a chapter, a scene or from/at + span) and lays it there: on a chapter, as that chapter's score cue (each chapter keeps its own; placing again replaces it), otherwise as a bed that STARTS there, so a 60 s piece on a chapter at 216 s of a 277 s film costs 60 s, not 277 s, and carries no padded silence; a full render lays the mix under the film as its music bed. The format is in typecut://studio/guide ("Score"). For real sound design pass code instead: a SOUND PROGRAM, a short Python script on the tcsound library (voices like growl/blip/kick you can shape per note or write yourself in NumPy, patterns like "x..x|X.3.", buses, sends, and edits on the rendered audio: stutter, tape_stop, gate, chop), run on our servers. Same mix/stems/ears; every trigger also says what that sound measured (level, attack, decay, brightness, then bands lo/mid/hi %, onset_ms, flags). Designed UI voices click2/pop2/whoosh2: get_authoring_contract {view:"sound"}. Every full render also returns a HEARING SHEET, render.sheet: url is ONE image on the film clock (spectrogram with numbered bars, beats and picture cuts; loudness vs target; hit ticks per track; low/mid/high energy per stem), bands the same energy as numbers and flags in words ("empty middle", "dark", "harsh"). Look at it before judging the sound. Sounds are kept per project between renders (render.cache): an edit re-makes only the voices it changed. Guide: "Sound programs". To keep the program as FILES instead of an inline string, project_write music/main.py, music/voices.py, music/cues/<name>.py and music/mix.json, then pass source:"music" (no tempo(): the conductor is the clock); edit \{path, old, new\} patches a file without re-sending it (answer < 2 KB, no code echo); plan:true returns the PLAN (events, curves published with publish(), the beat axis) in well under a second, free; async:true answers with a key at once and status:"\<key\>" reads it (state, ears, trigger summary). A render that was still going when its call returned (pending) is laid where that call said (the chapter's score cue, or the film bed) by the first status read after it finishes, and the read says placement: \{placed, clip_id | reason\}; no need to send the program again. status + place lays any finished render explicitly, even after the film changed. Long chapters and films (over 90 s) render in chunks, so there is no 300 s limit. Renders list 20 triggers (triggers for more) plus a count per track. Guide: "Music as files". Only project_id = READ. Free.

InputTypeDescription
project_id requiredstringProject id.
scoreobject{ seed?, key?, tempo?, buses?, tracks: [{ id, voice | sample, bus?, gain?, pan?, sends?, duck?, params?, events?: [{at, every?, until?, count?, vel?, len?, p?}], notes?: [{at, d, p, v?}] }], automation?, master? }
codestringA sound program (Python, tcsound) instead of score. Guide: "Sound programs". dry_run runs it and places every sound without rendering.
sourcestring"music": play the program kept as project files (music/main.py, voices.py, cues/*.py, mix.json). Guide: "Music as files".
editobject
planbooleanWith source: the Plan (events, curves, beat axis, chords), free, no audio. Returns key + hash + url + summary.
statusstringA key from a render or a plan: state (rendering/planning/failed/done), ears, trigger summary. When it is done, a render that was pending is placed where its call said (see placement); add place to lay a finished render explicitly.
asyncbooleanAnswer with the key at once; read it with status.
triggersnumberTriggers to list in a render (default 20, max 400); the rest is a count per track.
referencestringWith code: an audio analysis id whose production sheet the program writes against (analyze_audio production:true) — film.production, fit("kick") and a scorecard on the render. Remembered.
dry_runbooleanValidate and resolve every anchor; render nothing.
rangeobject
placeobject
applybooleanLay the mix under the film (default true for a full render; for place the mix is laid at the placement: a chapter's score cue, else a bed).

track_element

How one element moves

Follow ONE element through a scene and get its motion as numbers, not pictures: when it is visible, each move (direction, distance, duration, easing class, and the GSAP ease it fits — e.g. power2.out, 0.7% off, with the tween's own start/end — peak speed and when, how long it takes to settle), stills, jumps (a teleport), loops (period and amplitude), scale, rotation and size change, and a one-line sparkline per property. Read straight from the page at each sample, so it is exact and takes a couple of seconds. Free. Use it to check that a move does what you meant (eases out, lands on the beat, does not overshoot), to see when something appears, or when review_motion flags a jump.

targets: 1-6 elements, each a CSS selector, a name (an id, data-tc-anchor, data-wire-id or data-k) or "text:some words" it says. An unknown name comes back with the real names to try. Times are the scene clock (scene_id) or the draft's own (html). from/to narrow the window; hz (default 20) samples denser for a fast move. props picks the sparklines (default speed, opacity); detail:"features" adds the numbers behind the prose, "series" also at most 60 rows of [t, x, y, w, h, scale, rotation, opacity]. Motion drawn on a canvas, video or WebGL has no element to read: use review_motion. measure_elements is the same for the relation between two elements.

InputTypeDescription
scene_idstringScene to probe (scene clock). With html, the draft is probed inside this scene.
htmlstringA draft composition (not yet landed). Without scene_id, times are on its own clock.
targets requiredarray1-6 elements: a CSS selector, an id / data-tc-anchor / data-wire-id / data-k name, or "text:some words".
fromnumberWindow start, seconds. Default 0.
tonumberWindow end, seconds. Default the end.
hznumberSamples per second. Default 20, max 60 (at most 400 samples).
propsarraySparklines to draw. Default speed and opacity.
detail"summary" | "features" | "series"summary (default): prose and sparklines. features: also the numbers. series: also at most 60 rows.
element_idstringScene + html: which composition element the draft replaces.
widthnumberBare draft only: canvas width (default: the draft's own, else 1920).
heightnumberBare draft only: canvas height.
durationnumberBare draft only: duration in seconds (default: the draft's own, else 10).

validate_composition

Would the pipeline accept this?

Check a composition against the REAL gates before you land it. Free — no hosting, no writes, no credits — and it is the difference between a loop that converges and one that burns credits guessing.

It runs the actual chain at its live configuration: the same normalisation every generated candidate gets, the hard structural gates (exactly one closed <template>, a composition id, a registered timeline, and the containment bans on appends to document.body and getElementsBy*), the configurable gate stack, and the vocabulary checks from get_authoring_contract. A refusal comes back in the gate's own words, with per-stage results so you know which one fired. It also WARNS, without refusing, about hygiene that renders fine today but breaks if a host re-runs your script (a .from() tween, DOM built into a container that is never cleared), var() names nothing defines, a top-level const/let/class (the video runs every composition in a scene in ONE shared scope, so wrap your script in an IIFE), and a script that does not compile. What it accepts is what put_scene_composition lands: the same normalised document, the same verdict.

Pass check: true to SEE it before you land it: the composition is rendered and you get what the checker measured (text visible at its word and inside the canvas, empty stage, dead air, exposure, runtime errors) plus contact_sheet — ONE image of the whole scene, a frame every 0.5 s labelled with its time. A few seconds. Use preview_composition when you need MP4-exact frames at chosen times.

Frame-driven code is judged by rendering, not by a regex. A <canvas> passes when the timeline paints it; requestAnimationFrame or a wall clock comes back as a WARNING — the renderer SEEKS a paused timeline and screenshots, it never runs a frame loop, so that renders in a browser and FROZEN in the video. check: true shows you the frozen frames; declare motion on the timeline instead.

It tells you whether the composition is CONFORMANT, never whether it is any good.

InputTypeDescription
htmlstringThe composition source to check: a full HyperFrames document, a <template> sub-comp, or the bare root. Max 2,000,000 characters. Pass exactly one of html / src_url.
src_urlstringAn https URL to fetch the composition from instead of html (private and internal addresses are refused).
widthnumberCanvas width it is authored against. Default 1920.
heightnumberCanvas height. Default 1080.
durationnumberScene duration in seconds. Default 10.
element_idstringElement id it mounts as. Default "comp". Pass the real one from get_authoring_context when you have it.
contract_onlybooleanRun only the vocabulary checks and skip the gate stack. Rarely what you want.
checkbooleanAlso render it and return the checker findings plus contact_sheet (one image of the whole scene over time). Recommended before landing.
briefstringWhat the scene is meant to say (the voiceover line or brief); sharpens the text check.

On this page