Update one or more clips in a single call — background, transition, duration, title, visibility, position, and (video clips) the footage transform via video_styling. Always batch.
Each entry: { clip_index, duration?, title?, background_color? | background?, transition?, hidden?, position?, voiceover_volume?, video_styling?, after_clip?, subtitle_settings? }
- duration: sets the clip's length WITHOUT rescaling anything (unlike generating speech, which rescales the whole clip). A shrink clamps every end_time past the new end to it; a grow carries an element that ended at the old end to the new end and leaves the rest where they were. A placed trim animation keeps its animation_duration: it holds its last frame on a grow and is cut on a shrink; only a stretch animation placed to fit keeps filling its window at the same speed. Keyframes keep their timestamps. Each clip's result lists what moved as extended / clamped.
- voiceover_volume: 0-100. This is how you make a clip SILENT — set 0 to mute the narration while keeping the text and its word timings. get_clip and get_project report the current value, so read it before muting to restore it later. There is no "delete voiceover" tool; muting is the supported way.
- background_color: hex (keeps the existing pattern/image, changes color). background: replaces the whole background — a full object from find(type='backgrounds'), or any image/video: { src (URL or upload id), media_type?: 'image'|'video' (inferred), color?, padding? (% around the footage, 0-100), border_radius? (px), shadow? (0-100), volume? (a video's audio, 0-100, default 100) }.
- transition: { type, duration, direction?, color?, bezier? }, or null to remove. Set on the OUTGOING clip — the transition plays at the END of clip_index, into the next clip. Types: circleWipe, rainbowWipe, cornerWipe, stack, colorWipe, dissolve, pushPull, fadeToColor, flip. Directions: rainbowWipe/cornerWipe take topLeft|topRight|bottomLeft|bottomRight; colorWipe left|right; stack/pushPull left|right|top|bottom; flip (3D card turn) horizontalLeft|horizontalCenter|horizontalRight|verticalTop|verticalCenter|verticalBottom. bezier [x1,y1,x2,y2] eases flip.
- position: move the clip to a new zero-based index. Moves apply FIRST (in array order), then property patches — keep reorders in a separate call from property edits so indices stay predictable.
- video_styling (VIDEO CLIPS ONLY — ignored on slide clips): reposition/resize the clip's recording on the canvas, e.g. into a designed window slot. { position?: [cx, cy], size?: [w, h] } as canvas fractions 0–1 ([1,1] = full-bleed, position is the footage CENTER), plus crop? and border?. Fields merge onto the clip's existing video_styling.
- after_clip (interactivity beta): where playback goes when the clip ends — { mode: 'next_clip' | 'end_video' | 'jump_clip', target_clip_id? }, or null for the default (next clip). Use it to end a branch or rejoin the main path; target_clip_id must be a visible clip_id from get_project.
- subtitle_settings: captions on this clip, { showSubtitles?, size? (px), style?, subtitlesStyle? }. Omitted showSubtitles/size reset to true/24. style = a caption library style by id, filled in for you: basic_shadow (Basic: white with a soft shadow, words fade in one by one; the default), basic (Basic + box), gradient (bottom of the letters fades out), box_karaoke (frosted glass box, each word brightens as it is spoken), karaoke, box_highlight, box_highlight_bg, color_word, highlight_word, paragraph_builder, word_by_word. subtitlesStyle fields sent with style override it, e.g. { style: 'gradient', subtitlesStyle: { text: { fontSize: 60 } } }. Without style, subtitlesStyle is a whole SubtitlesStyle copied from a clueprint, template or the clip's current style (its id is only a label; an invalid one falls back to the default with a warning). Styling lives only inside subtitlesStyle; a key that can't be mapped is dropped with a warning. Useful fields: text.{font, fontSize, fontColor, gradientSetting}; background {show, style: {color, opacity 0–100, line_style 'split'|'combo', sidePadding, cornerRadii}}; animation.{entry_type / exit_type 'slide'|'lift_fade'|'fade'|'none', entry_duration / exit_duration ms (Normal 400/250, Slow 800/500, Fast 150/100), transition_scope 'caption'|'line'|'word' with stagger ms (0–200), color_current_word|color_upcoming_words: {show, color, opacity}}; position {x, y} fractions of the caption centre.
- video_styling.border frames the recording, as the editor's Stroke panel does: omnibox (browser toolbar with a URL bar over the footage — e.g. { type: "omnibox", color: "#0052CC" }), browser (window chrome), notch (phone notch), solid (plain stroke; takes stroke), glass, animated, or none. Width and color default per type like the editor; a bare { color } restyles the current border.
Concurrency: parallel-safe per clip — all property updates land in ONE save. Safe to fan out across DIFFERENT clips. Do NOT run concurrently with element/voiceover edits on the SAME clip, or whole-project mutations (add_clips, add_audio, update_project). When adding audio + resizing clips, run update_clips BEFORE add_audio.