Connection check
verified live · 20h ago
framesail
Create long-form YouTube videos end to end: script, storyboard, voiceover, final MP4.
Tools
72
GitHub stars
—
Installs / wk
—
Licence
—
Transport
streamable-http
Last checked
20h ago
Tools & capabilities
72 toolsRead from the running server on 20h ago.
activate_script_version
script_id*
Switch the project's active script to another saved version (ids come from get_script's version list — each generate_script run creates one; save_script edits the active ve… Switch the project's active script to another saved version (ids come from get_script's version list — each generate_script run creates one; save_script edits the active version in place). Re-run scan_script / rescan_voice_blocks afterwards if the text differs, since downstream artifacts follow the active version.
add_music_track
loopnamevolumeproject_id*start_framelibrary_track_id*
Add background music to the project from the audio library (find track ids with browse_audio_library, category="music"). Defaults loop the track under the whole video at be… Add background music to the project from the audio library (find track ids with browse_audio_library, category="music"). Defaults loop the track under the whole video at bed level (volume 0.12 ≈ -18.4 dB under narration — don't raise it without being asked); re-run export_video to hear it.
add_segment_sfx
project_id*segment_number*library_track_id*
Attach a sound effect from the audio library to a segment (find track ids via browse_audio_library with category="sfx"). Re-run build_scenes to get it onto the timeline. Attach a sound effect from the audio library to a segment (find track ids via browse_audio_library with category="sfx"). Re-run build_scenes to get it onto the timeline.
analyze_style
can modify data
style_id*
Re-run style analysis (after changing a style's inputs). Async — await_jobs(style_id=...) until the style_analysis job completes. Re-run style analysis (after changing a style's inputs). Async — await_jobs(style_id=...) until the style_analysis job completes.
animate_segment
voiceproject_id*segment_number*
Animate one segment in a single call: flip it to a generated video shot (keeping its rendered image as the clip's first frame) and START the clip render immediately. BILLS… Animate one segment in a single call: flip it to a generated video shot (keeping its rendered image as the clip's first frame) and START the clip render immediately. BILLS video credits on this call — the segment's image must already be rendered (400 otherwise). A refused generation (out of credits, already running) rolls the flip back, so the segment is either animating or exactly as it was. This is the ONLY way to a generated video (voice=true for a Talking Head) — change_segment_type refuses that target; it owns the other kind switches (real media, overlay scene, back to a still — segment_type "image" with carry_frame=true reverts an animated shot for free). Async — returns {ai_job_id, segment}; await_jobs until the clip completes.
await_jobs
read-only
style_idproject_idtimeout_seconds
Block (server-side) until the scope has no pending/running jobs, or the timeout passes — use this instead of polling get_workflow_status yourself. Returns {done, jobs}. If… Block (server-side) until the scope has no pending/running jobs, or the timeout passes — use this instead of polling get_workflow_status yourself. Returns {done, jobs}. If done=false the work is still running: just call await_jobs again (a 3-5 minute storyboard takes a few consecutive calls). Keep timeout_seconds <= 50 so the client doesn't time out the tool call.
browse_audio_library
read-only
moodgenresearchcategory
Browse the audio library for background music and sound effects. category: "music" | "sfx". Returns {tracks} — track ids feed add_music_track / add_segment_sfx. Zero matche… Browse the audio library for background music and sound effects. category: "music" | "sfx". Returns {tracks} — track ids feed add_music_track / add_segment_sfx. Zero matches also returns the mood and genre tags the library actually carries, so retry with one of those rather than guessing new filter words.
build_scenes
can modify data
project_id*
Compile segments + assets + voiceover into the editor/render timeline (scenes). Run after segment assets are complete, before export. Returns a receipt — {scene_count, scen… Compile segments + assets + voiceover into the editor/render timeline (scenes). Run after segment assets are complete, before export. Returns a receipt — {scene_count, scenes: [{scene_id, segment_number, duration_frames, status, layer_count}]}; composition detail via list_scenes.
change_segment_type
can modify data
dry_runproject_id*carry_framemedia_sourcesegment_type*segment_number*
Change what a segment's base visual IS: a generated still ("image"), fetched real media (media_source="real" — a real photo for "image", stock b-roll footage for "video"),… Change what a segment's base visual IS: a generated still ("image"), fetched real media (media_source="real" — a real photo for "image", stock b-roll footage for "video"), or an overlay scene. Generated video is NOT set here — it's the state a rendered still reaches through animate_segment (voice=true for a Talking Head), and a "video" target without media_source="real" is refused with that guidance. segment_type "image" with carry_frame=true reverts an animated shot back to its still for free. media_source="real" turns the shot into fetched media with no start frame and no generation. carry_frame=true reuses the already-rendered image instead of recreating it; ignored for a real target. SFX and overlays always survive a type change. dry_run=true previews what would be kept / staled / recreated / deleted before you commit.
combine_segments
can modify data
keepdry_runproject_id*segment_number*with_segment_number*
Merge a segment with an adjacent one (segment numbers must be neighbors). keep: "this" | "other" — whose creative data survives: its assets are kept (rendered frame/clip ma… Merge a segment with an adjacent one (segment numbers must be neighbors). keep: "this" | "other" — whose creative data survives: its assets are kept (rendered frame/clip marked stale against the combined narration and its prompts re-derived); the other segment's assets are deleted. Later segments renumber — re-check get_segments before further edits.
create_asset
name*asset_type*project_id*description
Manually add a character/environment/object the scan missed. asset_type: "character" | "environment" | "object". The description is the generation-facing spec of its look —… Manually add a character/environment/object the scan missed. asset_type: "character" | "environment" | "object". The description is the generation-facing spec of its look — be specific. The scan reads narration and `[SCENE: ...]` directions, so the common miss is anyone NEITHER ever names — a host the video needs but no text mentions, a recurring set the script only implies. Name the asset exactly as the script or directions will refer to it so the storyboard binds the two, then generate_asset_reference it like any scanned asset.
create_channel
name*description
Create a new channel — the container for projects and their reusable styles. Use when the user wants a fresh creative identity rather than adding to an existing channel. Create a new channel — the container for projects and their reusable styles. Use when the user wants a fresh creative identity rather than adding to an existing channel.
create_project
title*channel_id*descriptionvideo_format
Create a project. The description (the video concept/topic) seeds script generation, so write a meaningful one. Pass video_format='portrait' for a vertical video — every sh… Create a project. The description (the video concept/topic) seeds script generation, so write a meaningful one. Pass video_format='portrait' for a vertical video — every shot, overlay, and the export are then composed for a 9:16 frame. The response's web_url is the project's page in the web app — share it so the user can follow along.
create_style
name*inputspresetschannel_id*
Create a style. Two mutually exclusive paths: References (best): inputs=[{"input_type": "youtube" | "text", "value": "<url or description>"}] — YouTube videos are watched… Create a style. Two mutually exclusive paths: References (best): inputs=[{"input_type": "youtube" | "text", "value": "<url or description>"}] — YouTube videos are watched (a channel link or @handle resolves to that channel's newest usable upload) and text directions read; async analysis writes the style's art/narrative/director fields: await_jobs(style_id=...) before using the style. (Image/video FILE references require the multipart REST endpoint POST /styles.) Presets (instant, no analysis): presets={"art_style": id, "narrative_style": id, "director_style": id} — all three axes, ids from list_style_presets.
delete_asset
can modify data
asset_id*
Delete a project asset (e.g. one the scan over-extracted). Delete a project asset (e.g. one the scan over-extracted).
delete_project
can modify data
project_id*
Permanently delete a project and everything in it (script versions, assets, voiceover, segments, renders). Irreversible — confirm with your user first. Permanently delete a project and everything in it (script versions, assets, voiceover, segments, renders). Irreversible — confirm with your user first.
delete_style
can modify data
style_id*
Delete a style (e.g. a failed analysis experiment). Don't delete a style that projects still use as their default — rebind them first with set_project_style. Delete a style (e.g. a failed analysis experiment). Don't delete a style that projects still use as their default — rebind them first with set_project_style.
director_note
message*scene_idproject_idsegment_numberconversation_history
Edit ONE scene with a natural-language note (the same director chat the editor UI uses): move/restyle/add/remove layers and overlays, retime, etc. Synchronous — returns the… Edit ONE scene with a natural-language note (the same director chat the editor UI uses): move/restyle/add/remove layers and overlays, retime, etc. Synchronous — returns the applied mutations + updated scene. Address the scene by project_id + segment_number (preferred — always resolves to the current scene) or by scene_id from a fresh list_scenes call. Scene durations are locked to the narration track: don't ask to extend/shorten a scene except the final one — for a held-shot feel mid-video, ask for calmer/static motion on the scene instead. For notes spanning the whole video use project_director_note instead.
export_video
project_id*
Render the final MP4 (Remotion). Fetches the current timeline and queues the render. Async — poll get_workflow_status for the video_export job, then call get_video_url. Render the final MP4 (Remotion). Fetches the current timeline and queues the render. Async — poll get_workflow_status for the video_export job, then call get_video_url.
generate_asset_reference
modelasset_id*settingseditable_sections
Render an asset's reference image in the channel's art style — the visual anchor that keeps a character/environment looking identical across every shot. EVERY character, en… Render an asset's reference image in the channel's art style — the visual anchor that keeps a character/environment looking identical across every shot. EVERY character, environment, and object asset needs one before generate_voiceover (the server enforces this; fire the jobs for all assets, then one await_jobs). Async — the job writes the image onto the asset row: await_jobs(project_id), then list_assets and view_image the file_path to check likeness.
generate_script
modelsettingsproject_id*editable_sections
Generate the project's script from its description/concept and the channel's narrative style. Async — returns {job_id}; poll get_workflow_status. Generate the project's script from its description/concept and the channel's narrative style. Async — returns {job_id}; poll get_workflow_status.
generate_segments
dry_runproject_id*asset_scopesegment_numbers
Render every actionable segment asset (images, video clips, overlays) across the project, in dependency order. THE most expensive call in the pipeline: ALWAYS dry_run=true… Render every actionable segment asset (images, video clips, overlays) across the project, in dependency order. THE most expensive call in the pipeline: ALWAYS dry_run=true first, show your user the estimate next to get_credit_balance, and wait for a fresh yes before the real run — prior blanket permission ("do the whole thing") does not cover this spend. The staged flow is cheapest: asset_scope="no_clips" first (images + overlays), review, then animate_segment the shots that deserve motion. Pass segment_numbers to render only a subset — e.g. segments 1-18 for the opening minute before committing to the full video. Safe to re-run: completed and currently-generating assets are skipped, so a second call only picks up new/failed work. Async — one job per asset; await_jobs until all complete.
generate_storyboard
can modify data
modelsettingsproject_id*editable_sections
Plan the full visual storyboard: segments, shot pacing, image/video prompts, overlays, continuation chains — driven by the channel's director and art styles. Requires voice… Plan the full visual storyboard: segments, shot pacing, image/video prompts, overlays, continuation chains — driven by the channel's director and art styles. Requires voiceover to exist (timing comes from it). Plans generated stills + real media only (real media requires the style's @real-media tag); generated video is added per segment after the images render, with animate_segment. Async — returns {job_id}; this is the longest LLM step.
generate_style_template
modelreplacestyle_id*template_type*editable_sections
Render one of a style's two template images — a REAL step of style setup, not an optional extra: a style isn't finished until both its character and environment templates a… Render one of a style's two template images — a REAL step of style setup, not an optional extra: a style isn't finished until both its character and environment templates are rendered (the app shows them on the style card). Asset reference images render against them (characters → character template; environments and objects → environment template), and segment renders fall back on them when a shot has no asset reference — so finish BOTH before generate_asset_reference. Run once per template_type ("character" | "environment") for every new style; skip types the style already has (get_style's `templates`). A template already exists is a hard stop here — the call refuses unless replace=True, because overwriting one silently re-anchors every future render. Async — await_jobs(style_id=...), then get_style.
generate_voiceover
modelsettingsproject_id*voice_block_idseditable_sections
Generate TTS audio for the project's voice blocks. Without voice_block_ids it fills gaps: only blocks with no audio yet run, so re-calling it is always safe (already-genera… Generate TTS audio for the project's voice blocks. Without voice_block_ids it fills gaps: only blocks with no audio yet run, so re-calling it is always safe (already-generated and currently-generating blocks are skipped, never re-billed). Pass voice_block_ids to explicitly REgenerate those blocks (e.g. after changing a block's voice). Speakers must have voices bound first — set_narrator_voice / set_character_voice. Optional editable_sections/settings apply to every selected block (see get_section_template("voice_block") and list_models("voice_block")). Async — returns one job per block.
get_credit_balance
read-only
Current credit balance + plan info. Check before expensive steps (a full segment render can cost hundreds of credits — generate_segments dry_run gives the estimate). Jobs c… Current credit balance + plan info. Check before expensive steps (a full segment render can cost hundreds of credits — generate_segments dry_run gives the estimate). Jobs covered by a BYOK provider key bill 0.
get_pipeline_progress
read-only
project_id*
THE resume/orientation tool: one call returns every pipeline step's state (script -> scan -> reference_images -> voices -> voiceover -> style_templates -> storyboard -> seg… THE resume/orientation tool: one call returns every pipeline step's state (script -> scan -> reference_images -> voices -> voiceover -> style_templates -> storyboard -> segment_assets -> scenes -> export), any running jobs, and a next_action telling you exactly what to do next. Call this when picking up an existing project, after any await_jobs, or whenever you're unsure where a video stands — never guess pipeline position. Every step carries a web_url — the page in the Framesail web app where your user can see that step's output. Share it whenever you present a step's results ("review the storyboard here: ...") so they can inspect and edit in the browser; the app and this API act on the same live state.
get_project
read-only
project_id*
Fetch a project row — settings, voice config, default style, export URL. Fetch a project row — settings, voice config, default style, export URL.
get_script
read-only
project_id*
Read the active script's full text + the version list. Use this to show the script to your user for review/feedback before scan_script — the review-edit-resave loop (get_sc… Read the active script's full text + the version list. Use this to show the script to your user for review/feedback before scan_script — the review-edit-resave loop (get_script -> discuss -> save_script) is the expected workflow when the user wants input.
get_section_template
read-only
job*
Inspect the prompt sections a generation job exposes for per-call override via editable_sections (jobs: script, script_scan, storyboard, segment_image, segment_video, voice… Inspect the prompt sections a generation job exposes for per-call override via editable_sections (jobs: script, script_scan, storyboard, segment_image, segment_video, voice_block, ...). Sections marked locked cannot be overridden.
get_segment_assets
read-only
project_id*segment_number*
List one segment's assets (images/video/overlays) including their status, config (prompts, model), and public URLs of rendered files — pass an image's public_url to view_im… List one segment's assets (images/video/overlays) including their status, config (prompts, model), and public URLs of rendered files — pass an image's public_url to view_image to actually look at it.
get_segments
read-only
limitoffsetproject_id*
List the storyboard's segments (narration span, type, duration, creative direction). The 1-based segment_number is the handle every segment tool takes (update/split/combine… List the storyboard's segments (narration span, type, duration, creative direction). The 1-based segment_number is the handle every segment tool takes (update/split/combine/continuation/regenerate) — you never need a UUID. Returns {total, offset, returned, segments}; on big projects page through with offset/limit rather than fetching all segments in one call. Each segment also reports `continues_from_segment`. When set, this shot is a CONTINUATION of that earlier segment: its rendered frame carries over (same composition, characters, and setting) and only the delta changes — an added overlay, a shifted expression, a closer angle, a slow reframe. Null means a fresh, independent shot. The storyboard plans these chains automatically; adjust them with set_segment_continuation.
get_style
read-only
style_id*
Fetch one style row — its inputs (reference material), analyzed fields (art_style, narrative_style, director_style, script_prompt, ...), and `templates`: {"character": url|… Fetch one style row — its inputs (reference material), analyzed fields (art_style, narrative_style, director_style, script_prompt, ...), and `templates`: {"character": url|null, "environment": url|null}, the two template images. A null there means that template is genuinely missing and needs generate_style_template; a URL means it exists (view_image it) — don't re-render it. Show fields to the user for review; fine-tune with update_style_fields. `inputs_stale: true` means the references changed since the last analysis run — the analyzed fields don't reflect them; offer the user analyze_style (it rewrites those fields).
get_video_url
read-only
project_id*
Download URL for the most recent completed export. Download URL for the most recent completed export.
get_workflow_status
read-only
style_idproject_id
Poll this between steps: returns active + recently-finished AI jobs (scope by project_id, or style_id for style analysis), plus per-segment- asset render statuses for proje… Poll this between steps: returns active + recently-finished AI jobs (scope by project_id, or style_id for style analysis), plus per-segment- asset render statuses for projects. A step is done when its jobs reach status=complete (or error, with a user-readable message). NOTE: finished jobs drop out of `jobs` after ~30s — a short list does NOT mean work was lost; judge render batches by `segment_assets` statuses (or get_pipeline_progress), never by counting jobs. Prefer await_jobs over polling this in a tight loop.
list_assets
read-only
asset_typeproject_id*
List the project's assets extracted by scan_script — characters, environments, objects. Each has a description (the spec every shot uses to render it — surfaced top-level h… List the project's assets extracted by scan_script — characters, environments, objects. Each has a description (the spec every shot uses to render it — surfaced top-level here; the raw row nests it at ai_output.description), an optional reference image (file_path is a public URL — view_image it), and for characters a voice_id. Review these after scan_script: fix descriptions, then generate_asset_reference for each one (all of them need a reference image before voiceover). asset_type filter: "character" | "environment" | "object".
list_channels
read-only
List your channels. Every project lives in a channel, which owns the reusable styles (art/narrative/director) that drive generation. List your channels. Every project lives in a channel, which owns the reusable styles (art/narrative/director) that drive generation.
list_models
read-only
job*
List the models allowed for a generation job, with display names, credit estimates, and each model's settings_schema — the valid keys for that tool's `settings` param (e.g.… List the models allowed for a generation job, with display names, credit estimates, and each model's settings_schema — the valid keys for that tool's `settings` param (e.g. image quality/orientation, video duration). When model is omitted the server picks: the account's saved expert-drawer choice for that job/scope if one exists, else the first entry here. Voice models carry a `provider` field — a voice_block model must match the project's voice_tts_provider or generate_voiceover rejects it.
list_music_tracks
read-only
project_id*
List the project's background music tracks (volume, loop, timing). List the project's background music tracks (volume, loop, timing).
list_projects
read-only
channel_id*
List projects in a channel. List projects in a channel.
list_provider_keys
read-only
List registered BYOK providers (masked — only the last 4 characters). Returns {keys: [...]}; an empty list means no keys are registered (every job bills platform credits). List registered BYOK providers (masked — only the last 4 characters). Returns {keys: [...]}; an empty list means no keys are registered (every job bills platform credits).
list_scenes
read-only
limitoffsetproject_id*include_composition
List the project's scenes in timeline order. Default rows are light summaries ({scene_id, segment_number, duration_frames, status, layer_count}) — enough to address a scene… List the project's scenes in timeline order. Default rows are light summaries ({scene_id, segment_number, duration_frames, status, layer_count}) — enough to address a scene by number or id; include_composition=True returns the full layer/layout JSON (bulky — page with offset/limit on long projects). Returns {total, offset, returned, scenes}.
list_style_presets
read-only
The curated preset catalog for the no-AI style creation path, grouped by axis (art_style / narrative_style / director_style). Show the user the labels + descriptions and le… The curated preset catalog for the no-AI style creation path, grouped by axis (art_style / narrative_style / director_style). Show the user the labels + descriptions and let THEM pick one per axis — don't choose silently. Art presets include preview image URLs (view_image works on them). Create with create_style(presets={axis: id, ...}) — instant, no analysis job. Full field text lands on the style row (get_style shows it after creation).
list_styles
read-only
channel_id*
List the channel's style rows (variable groups). Styles hold the art_style / narrative_style / director_style / script_prompt fields that drive every generation step, plus… List the channel's style rows (variable groups). Styles hold the art_style / narrative_style / director_style / script_prompt fields that drive every generation step, plus any custom @variables.
list_voice_blocks
read-only
project_id*include_subtitle_data
List the project's voice blocks (per-speaker narration chunks) with their audio status and assigned voices. A block's `scene_direction` is the script's `[SCENE: ...]` direc… List the project's voice blocks (per-speaker narration chunks) with their audio status and assigned voices. A block's `scene_direction` is the script's `[SCENE: ...]` direction governing it (never spoken; null when the span carries none). Word-level subtitle timings are stripped unless include_subtitle_data=True.
list_voices
read-only
groupprovider
List available TTS voices (id, label, preview audio URL) for a provider: "minimax" (default engine) or "elevenlabs". Match the project's voice_tts_provider (see get_project… List available TTS voices (id, label, preview audio URL) for a provider: "minimax" (default engine) or "elevenlabs". Match the project's voice_tts_provider (see get_project) so picked ids work with its engine. Returns {groups: {name: count}, voices}; the ElevenLabs catalogue is 150+ voices, so pass group (names from `groups`) rather than reading it all at once.
project_director_note
message*project_id*
Apply a project-WIDE director note ("make the intro punchier", "all captions bigger", "tighten pacing in the back half"). A routing pass picks only the scenes the note appl… Apply a project-WIDE director note ("make the intro punchier", "all captions bigger", "tighten pacing in the back half"). A routing pass picks only the scenes the note applies to and edits each one. Synchronous — a few seconds per affected scene. Returns the per-scene results; re-run export_video afterwards to see changes in the final render.
regenerate_segment_asset
modelsettingsasset_type*project_id*segment_number*editable_sections
Regenerate a segment's primary image or video with optional overrides — the API equivalent of the editor's expert drawer. asset_type: "image" | "video" (for a video segment… Regenerate a segment's primary image or video with optional overrides — the API equivalent of the editor's expert drawer. asset_type: "image" | "video" (for a video segment, "image" targets its start frame). Use a different model, override prompt sections (see get_section_template("segment_image")), or tweak settings (e.g. image quality), then re-run just this asset. Async — returns {job_id}.
remove_music_track
can modify data
track_id*
Remove a music track from the project. Remove a music track from the project.
remove_segment_sfx
can modify data
sfx_nameproject_id*segment_number*
Remove a sound effect from a segment. With one SFX attached, no name needed; with several, pass sfx_name (the asset name shown by get_segment_assets). Remove a sound effect from a segment. With one SFX attached, no name needed; with several, pass sfx_name (the asset name shown by get_segment_assets).
rescan_voice_blocks
can modify data
project_id*
Re-extract voice blocks from the active script WITHOUT touching assets or their reference images — the non-destructive alternative to scan_script after a script edit. Block… Re-extract voice blocks from the active script WITHOUT touching assets or their reference images — the non-destructive alternative to scan_script after a script edit. Blocks whose spoken text is unchanged keep their audio; only edited blocks come back empty, so a follow-up generate_voiceover fills just the gaps. Synchronous and free — the split is deterministic. Returns {block_count}.
revise_script
project_id*instruction*selected_text
AI-rewrite a passage of the active script in the project's narrative voice (the same in-editor revise the UI offers). selected_text must appear verbatim in the script; omit… AI-rewrite a passage of the active script in the project's narrative voice (the same in-editor revise the UI offers). selected_text must appear verbatim in the script; omit it to revise the whole script. `[SCENE: ...]` directions in range are preserved exactly, in place, unless the instruction asks to change them. Synchronous — returns {revised_text}, which is NOT saved: splice it over selected_text (or replace the full script) and call save_script to keep it.
rollback_segment_asset
indexasset_type*project_id*segment_number*
Restore a previously rendered version of a segment's image or video — every regeneration archives the render it replaces (last 5), so a regen that came out worse is reversi… Restore a previously rendered version of a segment's image or video — every regeneration archives the render it replaces (last 5), so a regen that came out worse is reversible for free. The current render is archived in its place, making the rollback itself reversible. The frame/clip pair restales as usual: rolling the image back marks a rendered clip out of date.
save_script
content*project_id*
Save script text (your own draft, or an edited version of the generated one). Saving UPDATES the active version in place — the previous text is not kept, so show the user t… Save script text (your own draft, or an edited version of the generated one). Saving UPDATES the active version in place — the previous text is not kept, so show the user the current script (get_script) before overwriting it. New versions are created by generate_script runs, and activate_script_version switches between those. Run scan_script afterwards so assets and voice blocks reflect the new text. Three notations the script text carries, none of them ever spoken: SCENE DIRECTIONS — `[SCENE: <visual direction>]` as its OWN paragraph (blank line before and after; brackets inside a narration paragraph are never matched). It directs the storyboard for the narration that follows it, until the next direction. For that span it OUTRANKS the channel director style's shot choices — say what is on screen, who is in frame, and any on-screen text you need baked in verbatim — while the director style still governs look and rhythm. It is NOT a segmentation constraint: the storyboard still cuts the span into as many segments as the pacing wants. scan_script's asset extraction reads directions too: a character or place named ONLY inside a direction is still extracted, under the exact name the direction uses — no manual create_asset needed for it. PAUSES — `<break time="1.5s" />` is the ONLY thing that makes the voice pause. Ellipses, em dashes and paragraph breaks produce no silence at all, so a script without break tags is read as one continuous sprint. Both engines honor it (MiniMax natively, ElevenLabs masked out of the caption alignment). Use ~0.5s between thoughts, ~1.0s at act seams, and longer where a card or list needs reading time on screen; write ONE tag with the total ("4.0s"), never two tags back to back. Breaks are also the pacing lever the project's narrator_speed can't reach: speed changes how fast words are said, breaks add the silence between them. SPEAKERS — a paragraph starting `Name: "..."` assigns that line to a character, who gets their own voice (set_character_voice) and their own shot. Narration with no prefix is the narrator's.
scan_script
can modify data
modelproject_id*editable_sections
Analyze the active script: extracts character/environment/object assets and splits narration into voice blocks. DESTRUCTIVE on re-run (assets are recreated, not merged — cu… Analyze the active script: extracts character/environment/object assets and splits narration into voice blocks. DESTRUCTIVE on re-run (assets are recreated, not merged — curated descriptions, reference images, and voices are lost; prefer rescan_voice_blocks after script edits). Extraction reads the narration AND any `[SCENE: ...]` directions — a character or place named only inside a direction is still extracted, under the exact name the direction uses. Directions never leak into voice blocks (they ride onto the blocks they govern as staging instead). Review list_assets afterwards and create_asset anything the video needs that neither narration nor directions ever name. Async — returns {job_id}.
set_character_voice
asset_id*voice_id*
Bind a TTS voice to a character asset — required before generate_voiceover for every character with dialogue (the narrator's voice is separate: set_narrator_voice). Browse… Bind a TTS voice to a character asset — required before generate_voiceover for every character with dialogue (the narrator's voice is separate: set_narrator_voice). Browse ids with list_voices.
set_narrator_voice
voice_id*project_id*
Set the project's narrator TTS voice — required before generate_voiceover whenever the script has narration. Browse ids with list_voices. (Character dialogue voices are sep… Set the project's narrator TTS voice — required before generate_voiceover whenever the script has narration. Browse ids with list_voices. (Character dialogue voices are separate: set_character_voice.)
set_project_style
style_id*project_id*
Set the project's default style — the style whose art/narrative/director fields drive its generations. Use after create_style to put a new visual identity into effect, or t… Set the project's default style — the style whose art/narrative/director fields drive its generations. Use after create_style to put a new visual identity into effect, or to switch a project between channel styles.
set_provider_key
key*provider*
Register a BYOK provider API key (encrypted at rest, BYOK plan only). Jobs whose model belongs to this provider then run on YOUR key and charge 0 credits. Providers: openai… Register a BYOK provider API key (encrypted at rest, BYOK plan only). Jobs whose model belongs to this provider then run on YOUR key and charge 0 credits. Providers: openai, gemini, anthropic, fal, elevenlabs, minimax.
set_segment_continuation
project_id*continues_fromsegment_number*
Make a segment's image render as a continuation of an EARLIER segment's frame (same composition evolving — the storyboard's continues_from_segment, settable after the fact)… Make a segment's image render as a continuation of an EARLIER segment's frame (same composition evolving — the storyboard's continues_from_segment, settable after the fact). continues_from is that earlier segment's number; pass 0 to clear the link. Regenerate the segment's image afterwards — the reference is applied at generation time.
split_segment
can modify data
dry_runoffsets_ms*project_id*inherit_indexsegment_number*
Split a segment at the given time offsets (ms, 1-3 cuts → 2-4 parts). inherit_index picks which resulting part keeps the original creative data — that part keeps its render… Split a segment at the given time offsets (ms, 1-3 cuts → 2-4 parts). inherit_index picks which resulting part keeps the original creative data — that part keeps its rendered assets, SFX, overlays and continuation links (a rendered clip goes stale; re-render it). The other parts start fresh. Later segments renumber — re-check get_segments before further edits.
update_asset
nameasset_id*description
Rename an asset and/or rewrite its description. If the look changed, regenerate its reference image afterwards so renders match. Rename an asset and/or rewrite its description. If the look changed, regenerate its reference image afterwards so renders match.
update_caption_config
project_id*caption_config*
Merge a patch into the project's burned-in caption config (keys like enabled, plus styling). Read the current value from get_project (caption_config). Applies at the next e… Merge a patch into the project's burned-in caption config (keys like enabled, plus styling). Read the current value from get_project (caption_config). Applies at the next export — no rebuild needed.
update_music_track
fields*track_id*
Tweak a music track. fields keys: name, volume (0-1), loop, start_frame, duration_frames, position, trim_start_frame, trim_end_frame. Tweak a music track. fields keys: name, volume (0-1), loop, start_frame, duration_frames, position, trim_start_frame, trim_end_frame.
update_project
fields*project_id*
Patch project fields. Updatable: title, description, sfx_level, video_concept, voice_mix, voice_tts_provider, script_target_minutes, narrator_speed, video_format. (The narr… Patch project fields. Updatable: title, description, sfx_level, video_concept, voice_mix, voice_tts_provider, script_target_minutes, narrator_speed, video_format. (The narrator's TTS voice is NOT here — use set_narrator_voice.) narrator_speed is the narration rate (0.5-2.0, default 1.0; clamped to 0.7-1.2 on ElevenLabs). It changes how fast words are SAID and nothing else — it adds no silence between them, so "slow this down" usually wants `<break>` tags in the script text too (see save_script). video_format ('landscape' | 'portrait') is only changeable until the storyboard exists — after that the shots and overlays are composed for the current frame and the patch 409s. Switch it before generate_storyboard.
update_segment_content
can modify data
dry_runproject_id*user_input*segment_number*
Rewrite one segment's creative direction from feedback ("make this shot a close-up", "show the machine from above") — an LLM rewrites the shot's prompts; continuation links… Rewrite one segment's creative direction from feedback ("make this shot a close-up", "show the machine from above") — an LLM rewrites the shot's prompts; continuation links, SFX, and overlays are preserved. The visual assets reset to not_started: re-render them afterwards (generate_segments or regenerate_segment_asset). When you already know the exact prompt text, use update_segment_prompts instead — it writes your words verbatim with no LLM in the loop.
update_segment_prompts
project_id*image_promptvideo_promptmedia_queriessegment_number*start_frame_prompt
Set one segment's final prompts VERBATIM — no LLM rewrite. The direct counterpart to update_segment_content: your text is written as-is to the segment's creative direction… Set one segment's final prompts VERBATIM — no LLM rewrite. The direct counterpart to update_segment_content: your text is written as-is to the segment's creative direction and to the matching asset configs the renderer reads. Asset statuses are untouched: an already-rendered asset stays complete, and generate_segments skips complete assets — so to see the edit rendered, call regenerate_segment_asset on that segment (the ONLY re-render path after a prompt edit). Continuation links, SFX, and overlays are untouched. Pass only the prompt(s) you want to change; media_queries edits a fetched segment's stock-search text the same way.
update_style_fields
can modify data
fields*style_id*
Hand-edit a style's analyzed fields after reviewing them — e.g. tighten the art_style wording or adjust the director_style pacing rules. `fields` is a PATCH, merged over w… Hand-edit a style's analyzed fields after reviewing them — e.g. tighten the art_style wording or adjust the director_style pacing rules. `fields` is a PATCH, merged over what the style already has: send only the keys you are changing and leave the rest out — there is no need to read the whole dict back with get_style and round-trip it. Pass {key: null} to delete a user-added key (the well-known art_style / narrative_style / director_style / script_prompt cannot be deleted, only rewritten, and cannot be set empty). Editing fields does NOT trigger re-analysis, so your edits stick. Real media is switched by the literal `@real-media` tag inside director_style's prose: add the tag plus prose describing when/how/how much real media appears to turn it on; remove the tag (or its passage) to turn it off.
update_style_references
can modify data
inputs*style_id*
Replace a style's reference set — add or remove references without touching the analyzed fields. FULL REPLACE: read the current list with get_style first and send every… Replace a style's reference set — add or remove references without touching the analyzed fields. FULL REPLACE: read the current list with get_style first and send every entry you're keeping plus the changes. New entries are youtube (video link, or a channel link/@handle) or text; new image/video FILES can only be added via the multipart REST endpoint PATCH /styles/{id}, but existing ones round-trip fine. Optional `contributes_to` scopes an entry to a subset of the analyzed fields (art_style / narrative_style / director_style); omit it for all three. Saving does NOT re-run analysis: the response's `inputs_stale` flips true and the analyzed fields keep their current text until the user asks for analyze_style (which rewrites them from the new set).
update_voice_block
volumevoice_idvoice_block_id*
Override one voice block's voice or playback volume (block ids from list_voice_blocks). Re-run generate_voiceover for the block afterwards if you changed its voice — existi… Override one voice block's voice or playback volume (block ids from list_voice_blocks). Re-run generate_voiceover for the block afterwards if you changed its voice — existing audio is not regenerated automatically.
view_image
read-only
url*
Fetch a rendered Framesail image so you (and your user) can SEE it — pass a URL from get_segment_assets, get_style, or asset endpoints. Returns the image inline. Only Frame… Fetch a rendered Framesail image so you (and your user) can SEE it — pass a URL from get_segment_assets, get_style, or asset endpoints. Returns the image inline. Only Framesail media URLs are allowed.
whoami
read-only