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
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).
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
window | object | {scene_id} | {chapter_id} | {from, to} (film seconds). Omit for the whole film. |
show | array | Evidence 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_url | string | With show "compare": compare each scene in the window with this one picture instead of the reference (no alignment needed). |
against | object | With 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. |
at | number | With against_image_url: scene time (s) to take the replica frame at (one-scene window). |
curve | object | With 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. |
frames | number | Frames on the sheet (1-24, default 8; every scene in the window gets one). |
fps | number | Motion samples per second (default 2). |
detail | "auto" | array | With 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. |
async | boolean | Start 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_key | string | With async: any string unique to this call. A retry with the same key joins the job already started instead of starting another. |
analyze_video
See a reference video shot by shot
Shots, sheets, transcript, beats. Long? sections=parts.
| Input | Type | Description |
|---|---|---|
url | string | A direct http(s) url of the video file. |
media_asset_id | string | A library video (from list_media, ingest_video_url or an upload). |
transcribe | boolean | Transcribe the audio (default true). |
sections | array | [{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.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
scene_ids | array | Only these scenes. Default: the project, in order (first 24). |
seed | boolean | Fill undeclared ledger rows from the rendered probe and write the bible. |
check_requirements
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".
| Input | Type | Description |
|---|---|---|
template_slug required | string | Template slug from list_catalog("templates"). |
workspace_id | string | Workspace 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.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
scene_ids | array | Only these scenes (and the sound under them). Default every placed scene (max 40). |
tolerance_ms | number | How far apart still counts as together. Default 40. |
onsets | array | Extra 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? }. |
detail | boolean | Also 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.
| Input | Type | Description |
|---|---|---|
items required | array | Pictures: urls, or results with a url (e.g. "$imgs" after an each step). |
labels | array | Optional names, one per item (default: the model, when the result says). |
reference_url | string | The 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.
| Input | Type | Description |
|---|---|---|
scene_id required | string | Scene id. |
a required | string | A take id, or "current". |
b | string | A 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>.
| Input | Type | Description |
|---|---|---|
project_id required | string | The replica — the project being checked. |
reference_id required | string | The 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.
| Input | Type | Description |
|---|---|---|
scene_id | string | Scene to inspect. Times are scene-clock seconds. Give this OR html. |
html | string | A composition you hold (not yet landed). Times are on its own clock. Give this OR scene_id. |
times | array | When 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_id | string | Scene form only: limit to one composition element. |
width | number | Width 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. |
step | number | Visibility-timeline sample step in seconds. Default 0.5; 0 turns the scan off. |
inspect_composition
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).
| Input | Type | Description |
|---|---|---|
scene_id required | string | Scene id. |
element_id | string | Limit 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.
| Input | Type | Description |
|---|---|---|
url | string | The picture: an https url (a generate_image or find_media result; "$img.image.url" in a chain). |
asset_id | string | Or a library image asset id. |
project_id | string | Needed only for depth (the credit is billed to it). |
show | array | Views (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).
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
from_sec | number | Window start, film seconds (default 0). |
to_sec | number | Window end, film seconds (default from_sec + 60; at most from_sec + 120). |
bounce | boolean | Also host a short m4a of the full mix of the window (bounce_url). |
mask_db | number | Masking threshold: the bed within this many dB of the voice in the speech band (default 6). |
outlier_db | number | Outlier threshold: dB above the surroundings (default 6). |
fix | boolean | Also turn each outlier down to 3 dB above its surroundings (one undoable change); sounds a person leveled by hand are only flagged. |
async | boolean | Start 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_key | string | With 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.
| Input | Type | Description |
|---|---|---|
scene_id | string | Scene to probe (scene clock). With html, the draft is probed inside this scene. |
html | string | A draft composition (not yet landed). Without scene_id, times are on its own clock. |
a required | string | First element: a CSS selector, a name, or "text:some words". |
b required | string | Second element. Offsets are b minus a. |
at | array | The relation at exactly these seconds. Omit for a range. |
basis | "box" | "ink" | box (default) or ink (the text's own rectangles). |
from | number | Range start, seconds. Default 0. |
to | number | Range end, seconds. Default the end. |
hz | number | Range samples per second. Default 20. |
element_id | string | Scene + html: which composition element the draft replaces. |
width | number | Bare draft only: canvas width (default: the draft's own, else 1920). |
height | number | Bare draft only: canvas height. |
duration | number | Bare 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).
| Input | Type | Description |
|---|---|---|
scene_id | string | Scene to render. Times are scene-clock seconds. With html, the draft is previewed inside this scene. |
html | string | A draft composition (not yet landed). Without scene_id, times are on its own clock. |
src_url | string | The draft by URL instead of html: a create_upload public_url. Prefer it for anything larger than a few KB. |
times | array | Seconds to render, e.g. just after each beat lands. Max 24. |
element_id | string | Which composition element the draft replaces (scene + html). |
width | number | Bare draft only: canvas width. Default 1920. |
height | number | Bare draft only: canvas height. Default 1080. |
duration | number | Bare draft only: duration in seconds. Default 10. |
determinism | boolean | Run the render-twice determinism check. Default true. |
compare_mp4 | boolean | Scene form only: also diff each frame against the scene's rendered MP4 at the same frame. |
verbose | boolean | Also return the kernels' raw tables (tc-tick bindings, root stamps; ~15 KB). Default false. |
sheet | boolean | Return sheet_url (every frame in ONE labelled image, attached inline). Default true when more than one time; false turns it off. |
quick | boolean | Draft 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_id | string | Read back a preview that answered {status: "running"} — pass only this. |
async | boolean | Start 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_key | string | With 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.
| Input | Type | Description |
|---|---|---|
scene_id | string | Scene to render. |
html | string | A draft composition (not yet landed). |
times | array | Seconds to render, e.g. |
preview_id | string | Read back a preview that answered {status: "running"} — pass only this. |
async | boolean |
preview_scenes
Check what is on screen
Check ≤10 landed scenes at given seconds: clipping, contrast, phone glyph size → findings ("full" adds boxes). Free.
| Input | Type | Description |
|---|---|---|
scenes required | array | Scenes (+ own times). |
times | array | Default 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.
positionfirst|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).
| Input | Type | Description |
|---|---|---|
scene_id | string | Scene to review (scene clock). With html, the draft is reviewed inside this scene. |
html | string | A draft composition (not yet landed). Without scene_id, times are on its own clock. |
src_url | string | The draft by URL instead of html: a create_upload public_url. |
element_id | string | Scene + html: which composition element the draft replaces. |
mp4_url | string | A finished MP4 URL: blank flags only. |
position | "first" | "last" | "only" | Scene position in the film; first/last exempt the open/close. |
fps | number | Samples per second. Default 2; max 8 (capped at 48 frames). |
from | number | Window start, seconds. Default 0. |
to | number | Window end, seconds. Default the end. |
width | number | Bare draft only: canvas width (default: the draft's own, else 1920). |
height | number | Bare draft only: canvas height. |
duration | number | Bare 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). |
critique | boolean | Also ask a vision model about the filmstrip (with brief + questions). |
brief | string | What the scene is meant to show — sharpens the critique. |
questions | array | Motion questions for the critique, ≤300 chars each. |
async | boolean | Start 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_key | string | With 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.
| Input | Type | Description |
|---|---|---|
scene_id required | string | The scene. |
verdict required | "accept" | "reject" | |
reason | string | Why, in the person's words (≤1000 chars). |
comment_id | string | The 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.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
score | object | { 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? } |
code | string | A sound program (Python, tcsound) instead of score. Guide: "Sound programs". dry_run runs it and places every sound without rendering. |
source | string | "music": play the program kept as project files (music/main.py, voices.py, cues/*.py, mix.json). Guide: "Music as files". |
edit | object | |
plan | boolean | With source: the Plan (events, curves, beat axis, chords), free, no audio. Returns key + hash + url + summary. |
status | string | A 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. |
async | boolean | Answer with the key at once; read it with status. |
triggers | number | Triggers to list in a render (default 20, max 400); the rest is a count per track. |
reference | string | With 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_run | boolean | Validate and resolve every anchor; render nothing. |
range | object | |
place | object | |
apply | boolean | Lay 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.
| Input | Type | Description |
|---|---|---|
scene_id | string | Scene to probe (scene clock). With html, the draft is probed inside this scene. |
html | string | A draft composition (not yet landed). Without scene_id, times are on its own clock. |
targets required | array | 1-6 elements: a CSS selector, an id / data-tc-anchor / data-wire-id / data-k name, or "text:some words". |
from | number | Window start, seconds. Default 0. |
to | number | Window end, seconds. Default the end. |
hz | number | Samples per second. Default 20, max 60 (at most 400 samples). |
props | array | Sparklines 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_id | string | Scene + html: which composition element the draft replaces. |
width | number | Bare draft only: canvas width (default: the draft's own, else 1920). |
height | number | Bare draft only: canvas height. |
duration | number | Bare 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.
| Input | Type | Description |
|---|---|---|
html | string | The 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_url | string | An https URL to fetch the composition from instead of html (private and internal addresses are refused). |
width | number | Canvas width it is authored against. Default 1920. |
height | number | Canvas height. Default 1080. |
duration | number | Scene duration in seconds. Default 10. |
element_id | string | Element id it mounts as. Default "comp". Pass the real one from get_authoring_context when you have it. |
contract_only | boolean | Run only the vocabulary checks and skip the gate stack. Rarely what you want. |
check | boolean | Also render it and return the checker findings plus contact_sheet (one image of the whole scene over time). Recommended before landing. |
brief | string | What the scene is meant to say (the voiceover line or brief); sharpens the text check. |