Projects & history
Create, read and list projects, walk the append-only operation journal every mutation writes to, and move between saved versions. THE JOURNAL AND THE VERSIONS ARE TWO DIFFERENT THINGS. The journal is WHAT HAPPENED — one row per operation, its name and arguments, never the document it produced. A version is WHAT THE PROJECT WAS: a full stored copy the server can hand back on its own, with editor_restore_version, no client memory required. A VERSION IS NOT A CHANGE. Every operation bumps the project's mutation number, but a version is only taken when you ask for one (editor_save_version) or when editing stops and the server freezes where you left off — so nudging a clip two pixels does not make a version. Version numbers are the mutation numbers they froze, so they are sparse: 3, 7, 12, not 1, 2, 3. editor_restore_snapshot still exists for the other direction — handing back a document YOU are holding — and is unchanged. Both the project and its history are kept for the life of the project; exports are not, a render is a delivery with a 24-hour TTL, reproduced by exporting again.
Create a fresh, empty timeline project and return its summary, including the project_id every other tool needs.
Parameters
editor_create_project parameters
| Name |
Type |
Required |
Description |
| metadata |
dict | None |
default None
|
An opaque client-owned tag set the editor never interprets, e.g. {"client": "my-agent"}. |
| aspect_w |
int |
default 1080
|
Frame width of the canvas, in pixels. |
| aspect_h |
int |
default 1920
|
Frame height of the canvas, in pixels. |
| fps |
int |
default 30
|
Frames per second of the timeline. |
| target_sec |
float | None |
default None
|
Intended finished duration, for validation. |
| min_clips |
int |
default 1
|
Lower clip-count bound checked by the "shorts" validation profile. |
| max_clips |
int | None |
default None
|
Upper clip-count bound for the same profile. |
| min_duration_sec |
float |
default 0.0
|
Lower duration bound for the same profile. |
| max_duration_sec |
float | None |
default None
|
Upper duration bound for the same profile. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- the bounds are only enforced by editor_validate(profile="shorts")
- metadata is stored verbatim and is searchable via editor_list_projects
Read the full serialized project — tracks, elements, assets and every transform — as one JSON document.
Parameters
editor_get_project parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsThe whole project document, the same shape editor_restore_snapshot accepts back.
- this is the agent's 'eyes' on the edit between calls
- an unknown or foreign project id returns {"error": ...}
List this account's project summaries, newest first, optionally narrowed to those whose metadata matches a filter.
Parameters
editor_list_projects parameters
| Name |
Type |
Required |
Description |
| metadata |
dict | None |
default None
|
Keep only projects whose metadata is a superset of these key/value pairs. |
ReturnsA list of project summaries.
- only projects owned by the calling account are ever listed
Read the complete append-only operation journal for a project, oldest first — what was done, never the states it passed through.
Parameters
editor_get_history parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsA list of journal rows — every mutation ever applied, in order, each naming an operation and its arguments.
- every mutating tool appends exactly one row
- the journal is append-only and kept for the life of the project — nothing prunes it
- it records the op name and arguments, NOT the project document each op produced
- so it is an audit trail, not a version store: reading it tells you what happened, it does not hold the states themselves
- for the states, use editor_list_versions / editor_restore_version — the server keeps those separately
- the two line up by number: a version is identified by the mutation number it froze, which is the same number this journal reports
Freeze the project's current state as a version in the server-side history.
Parameters
editor_save_version parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
Returns{project_id, version, created_at, trigger, created} — ``created`` is false when this state was already saved.
- there is no save button in this editor: every operation persists immediately, so this marks a state worth returning to rather than writing anything new
- a version is NOT taken per change — that is why this tool exists, and why nudging a clip does not fill your history with noise
- idempotent: calling it twice without editing in between returns the same version and creates nothing
- the server also saves a version by itself once a project has been left alone for a while, so an abandoned session is not lost
- the number returned is the project's mutation number, the same one editor_get_history reports
List the versions the server holds for a project, newest first — what the project WAS, as opposed to what was done.
Parameters
editor_list_versions parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsA list of {version, created_at, trigger, op_name, op_args} — newest first.
- trigger says why the version exists: "manual" (you asked) or "idle" (editing stopped and the server froze it)
- version numbers are mutation numbers, so they are sparse — expect 3, 7, 12, never a 1,2,3 sequence
- op_name/op_args name the operation that produced the frozen state, joined from the operation journal
- versions live and die with the project: no TTL, nothing prunes them, and deleting the account removes them with everything else
Roll the project back to a version the SERVER holds, by number — no client-held document needed.
Parameters
editor_restore_version parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| version |
int |
required
|
A version number from editor_list_versions. |
| reason |
str |
default "restore"
|
Note recorded in the operation journal. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- rolling back moves FORWARD: the old state is persisted as the project's next version, and the mutation counter never rewinds
- the journal records which version you came back from, so the history shows where a rollback went
- this is the public counterpart to editor_restore_snapshot — same effect, but the document comes from the server rather than from you
- an unknown version number, or another account's project, returns {"error": ...}
- an exported project refuses this like any other edit — call editor_reopen_project first
Persist a project document YOU still hold as this project's next version — the undo/redo primitive, for states the server never saved as a version.
Parameters
editor_restore_snapshot parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| data |
dict |
required
|
A full project document as returned by editor_get_project. |
| reason |
str |
default "undo"
|
Note recorded in the operation journal. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- operator tier — invisible to a public caller's tools/list
- it writes an arbitrary project blob, bypassing every mutation guard — that is why it is operator tier while editor_restore_version, which only replays states the server itself recorded, is public
- the blob you send is deliberately NOT journaled — only the reason is, so the journal stays a log of intent rather than a copy of every state
- it is for FINE-GRAINED undo, between versions: the server holds saved versions, not every intermediate state, so stepping back one operation still needs the document you are holding
- to go back to a SAVED version you do not need this at all — editor_restore_version takes a number and needs nothing from you
Unlock a project that has already been exported so it can be edited and exported again.
Parameters
editor_reopen_project parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- an exported project refuses further edits until this is called
- call it before a second editor_export on the same project
Permanently delete a project: its timeline, operation journal, annotations, version history and rendered files.
Parameters
editor_delete_project parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsA receipt — {project_id, deleted, operations_deleted, annotations_deleted, checkpoints_deleted, files_deleted, released_bytes}.
- operator tier — invisible to a public caller's tools/list
- THIS CANNOT BE UNDONE — the version history goes with the project, so there is no checkpoint left to restore from; that is why it is operator tier while every other project mutation is public
- your UPLOADED FILES are not deleted: they belong to your account, not to the project, and stay on your media library shelf
- refused while an export is still rendering — retry once it finishes
- a project that is not yours, or one already deleted, reports the same 'unknown project id' as any other unknown id
- failure is reported as {"error": ...} in the result, never as a raised exception
Timeline & clips
Place assets on tracks and reshape them: trim the source window, resize, split, move between lanes, delete.
Place a registered asset on a track and return the new element_id.
Parameters
editor_add_clip parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| media_id |
str |
required
|
An asset already registered on this project. |
| track_type |
str |
default "video"
|
Which kind of track to land on ("video" or "audio"). |
| start_time |
float | None |
default None
|
Absolute timeline start; None appends after the last element. |
| duration |
float | None |
default None
|
On-timeline length; defaults to the asset's own duration. |
| trim_start |
float |
default 0.0
|
In-point inside the source, in seconds. |
| trim_end |
float | None |
default None
|
Out-point inside the source, in seconds. |
| track_id |
str | None |
default None
|
Target one exact track; None uses the first track of that type. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus the new element_id.
- requires a media_id registered earlier — upload the file or add it as an asset first
- an asset with no known duration needs an explicit duration, otherwise the call fails
- adding a clip also schedules background analysis of that media
Adjust a clip's in and out points inside its source.
Parameters
editor_trim_clip parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The clip to trim. |
| trim_start |
float | None |
default None
|
New in-point; None keeps the current one. |
| trim_end |
float | None |
default None
|
New out-point; None keeps the current one. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- this changes the source window only — use editor_resize_clip to move the clip at the same time
- failure is reported as {"error": ...} in the result, never as a raised exception
Change a clip's placement and source window together in one journaled operation — the edge-drag gesture.
Parameters
editor_resize_clip parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The clip to resize. |
| start_time |
float | None |
default None
|
New absolute start; None keeps it. |
| duration |
float | None |
default None
|
New on-timeline length; None keeps it. |
| trim_start |
float | None |
default None
|
New in-point; None keeps it. |
| trim_end |
float | None |
default None
|
New out-point; None keeps it. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- None means 'keep the current value' for every field
- one journaled op, so undo is one step
Cut one clip into two adjacent clips at an absolute timeline time.
Parameters
editor_split_clip parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The clip to split. |
| at_time |
float |
required
|
Absolute timeline time of the cut. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- at_time must fall strictly inside the clip — its own start and end are both rejected
- the original element is replaced by two NEW element ids; the old id no longer exists
Move an element to a new absolute start time, and optionally onto another track.
Parameters
editor_move_clip parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The element to move. |
| start_time |
float |
required
|
New absolute timeline start, in seconds. |
| track_id |
str | None |
default None
|
Also move it onto this exact track — the vertical lane drag. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- an unknown track_id fails the call rather than moving anything
Remove an element from whichever track holds it.
Parameters
editor_delete_element parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The element to delete. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- works for clips, texts, overlays and audio alike
- the deletion is journaled, so it can be undone from history
Tracks
Add upper video tracks that composite over the main lane, add extra audio lanes, and remove tracks you no longer need.
Add an empty upper video track whose clips composite over the main one.
Parameters
editor_add_video_track parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus the new track_id.
- clips on an upper track allow gaps, arbitrary positions and per-clip opacity
- pass the returned track_id to editor_add_clip or editor_move_clip to target it
Add an empty audio track after the last existing one.
Parameters
editor_add_audio_track parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus the new track_id.
- audio elements may not overlap within one track — a second bed needs its own
- editor_generate_voiceover creates its own track this way
Remove a track together with every element on it.
Parameters
editor_remove_track parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| track_id |
str |
required
|
The track to remove. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- the first (main) video track cannot be removed
- every element on the track goes with it
Audio & voice
Per-clip volume and mute, fades and volume envelopes, a music bed under the edit, and a synthesized voiceover over it.
Set a clip's mute and volume, or a music bed's volume and gain.
Parameters
editor_set_clip_audio parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The clip or music bed to adjust. |
| muted |
bool | None |
default None
|
Mute or unmute a clip's own audio. |
| volume |
float | None |
default None
|
Linear volume multiplier. |
| gain_db |
float | None |
default None
|
Gain in decibels, for a music bed. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- muted applies to clips only and gain_db to music beds only — the wrong pairing is rejected
- only the fields you pass change
Give a clip's audio or a music bed a fade-in, a fade-out and/or a volume-keyframe envelope.
Parameters
editor_set_audio_envelope parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The clip or music bed to shape. |
| fade_in_sec |
float | None |
default None
|
Fade-in length in seconds. |
| fade_out_sec |
float | None |
default None
|
Fade-out length in seconds. |
| volume_keyframes |
list[dict] | None |
default None
|
[{"time": t, "volume": v}, ...] replacing the whole envelope. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- MLT render engine only
- omitting volume_keyframes leaves them untouched; an explicit empty list clears them
- keyframe times are local to the element's own start
Register a source as the music bed and lay it on the audio track under the edit.
Parameters
editor_add_music parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| source |
str |
required
|
The audio source to use as the bed. |
| volume |
float |
default 0.15
|
Bed volume — quiet by default, under speech. |
| start |
float |
default 0.0
|
Absolute timeline start of the bed. |
| duration |
float | None |
default None
|
Bed length; defaults to the total length of the video track. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus the new media_id and element_id.
- with no duration and an empty timeline the call fails — add clips first, or pass duration
- audio elements may not overlap on one track; a second bed needs its own audio track
Synthesize a spoken voiceover for every auto-caption, lay it on a new audio track, and duck any music underneath.
Parameters
editor_generate_voiceover parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| voice |
str | None |
default None
|
TTS voice name; defaults by the project's detected caption language (ru / en). |
| duck_music |
bool |
default True
|
Dip existing music beds while the voiceover plays. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus voiceover_added, fitted and the new track_id.
- requires editor_auto_captions to have run first — with no captions the call fails
- a caption language other than ru or en needs an explicit voice
- each line is fitted to its slot, and a line that still overruns the next caption is clamped
- the whole pass is ONE journaled op
Text & captions
Captions derived from the clips' own speech, and hand-placed text layers — added one at a time or edited in an atomic batch.
Transcribe every video clip's own trimmed audio and add the result as caption text elements.
Parameters
editor_auto_captions parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| style_overrides |
dict | None |
default None
|
Caption style fields merged over the defaults, e.g. {"size": 48, "color": "#FFFF00"}. |
| max_chars_per_line |
int |
default 42
|
Split point for long transcript segments. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus captions_added and the detected language.
- speech recognition is lazy — without the 'asr' extra and its model the call returns a clear error
- captions land at the bottom of the frame by default and are marked with role "caption"
- the detected language is stored in the project metadata as captions_lang
Add a text overlay — a hook title, a label, a manual caption — at a given time.
Parameters
editor_add_text parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| content |
str |
required
|
The text; \n forces a line break. |
| start |
float |
required
|
Absolute timeline time it appears. |
| duration |
float | None |
default None
|
How long it holds; None means persistent to the end of the timeline. |
| pos |
str |
default "center"
|
Named preset: "top", "center" or "bottom". |
| size |
int |
default 64
|
Font size in pixels. |
| color |
str |
default "#FFFFFF"
|
Fill colour as a hex string. |
| pos_x |
float | None |
default None
|
Override the horizontal axis with a 0..1 fraction of the frame. |
| pos_y |
float | None |
default None
|
Override the vertical axis with a 0..1 fraction of the frame. |
| role |
str | None |
default None
|
Optional origin marker, e.g. "caption"; None leaves it unmarked. |
| font_id |
str | None |
default None
|
Typeface, as the id of a .ttf/.otf in your media library; None uses the service's own font. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus the new element_id.
- pos_x and pos_y are 0..1 fractions anchored at the text's top-left corner
- an unknown pos preset, or a fraction outside 0..1, is rejected
- font_id names a font on YOUR media library shelf; a font path is never accepted from a caller
Edit one existing text element in place — content, timing, size, colour or placement — keeping its id.
Parameters
editor_update_text parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The text element to edit. |
| content |
str | None |
default None
|
New text. |
| start_time |
float | None |
default None
|
New absolute start time. |
| duration |
float | None |
default UNSET
|
New hold length; explicit null makes it persistent. |
| size |
int | None |
default None
|
New font size. |
| color |
str | None |
default None
|
New hex colour. |
| pos |
str | None |
default None
|
New named position preset. |
| pos_x |
float | None |
default UNSET
|
New horizontal fraction; explicit null falls back to the preset. |
| pos_y |
float | None |
default UNSET
|
New vertical fraction; explicit null falls back to the preset. |
| font_id |
str | None |
default UNSET
|
New typeface, by media-library file id; explicit null goes back to the service's own font. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- duration, pos_x, pos_y and font_id use an UNSET sentinel: omitting the field KEEPS the value, passing an explicit null CLEARS it
- the element id is stable across the edit
- this is the only text tool that can change placement
Rewrite the content of many text elements atomically in one journaled operation.
Parameters
editor_update_texts parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| updates |
list[dict] |
required
|
[{"element_id": str, "content": str}, ...]. |
| reason |
str | None |
default None
|
Optional note recorded in the journal. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- changes content only — timing, style and placement are untouched
- an unknown id or a non-text element fails the WHOLE batch and nothing is applied
- one op, so a whole re-translated caption track undoes in one step
Overlays & transitions
Picture-in-picture and stickers placed over the frame, and cross-dissolves between consecutive clips.
Place a registered image or video over the frame as a picture-in-picture or sticker.
Parameters
editor_add_overlay parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| media_id |
str |
required
|
An asset already registered on this project. |
| duration |
float |
required
|
How long the overlay is on screen. |
| x |
float |
required
|
Left edge as a 0..1 fraction of the frame. |
| y |
float |
required
|
Top edge as a 0..1 fraction of the frame. |
| w |
float |
required
|
Width as a 0..1 fraction of the frame. |
| h |
float |
required
|
Height as a 0..1 fraction of the frame. |
| start_time |
float | None |
default None
|
Absolute start; None appends after the last overlay. |
| opacity |
float |
default 1.0
|
Opacity as a 0..1 fraction. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}. Plus the new element_id.
- MLT render engine only
- x, y, w, h and opacity are 0..1 fractions of the frame, anchored at the top-left; w and h must be positive
- duration may not exceed the source's own length — a longer overlay would VANISH partway through, so it is refused
Move, resize, retime or fade an existing overlay in place, keeping its id.
Parameters
editor_update_overlay parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The overlay to edit. |
| start_time |
float | None |
default None
|
New absolute start. |
| duration |
float | None |
default None
|
New on-screen length. |
| x |
float | None |
default None
|
New left edge, 0..1. |
| y |
float | None |
default None
|
New top edge, 0..1. |
| w |
float | None |
default None
|
New width, 0..1 and positive. |
| h |
float | None |
default None
|
New height, 0..1 and positive. |
| opacity |
float | None |
default None
|
New opacity, 0..1. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- only the fields you pass change
- growing duration past the source's length is refused, exactly as on editor_add_overlay
- the element must be an overlay — anything else is an error
Cross-dissolve into a clip from whichever clip precedes it on the same video track.
Parameters
editor_add_transition parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| to_element |
str |
required
|
The clip being dissolved INTO. |
| kind |
str |
default "dissolve"
|
Transition kind. |
| duration |
float |
default 0.5
|
Overlap length, in seconds. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- MLT render engine only
- there is no from_element — the predecessor is inferred from the track's own order, so a non-adjacent pair cannot be named by mistake
- the first clip on a track has no predecessor and cannot take a transition
- the overlap eats the last seconds of the predecessor and the first seconds of to_element
Clear the incoming transition on a clip — the off switch for editor_add_transition.
Parameters
editor_remove_transition parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| element_id |
str |
required
|
The clip whose incoming transition goes. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- only the incoming transition is cleared; the clips themselves are untouched
Preview, validate & export
See a frame before committing, pick the cover, check the timeline against its own rules, and render the finished mp4.
Render one frame of the timeline and return it as an image the agent can actually look at.
Parameters
editor_render_preview parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| at_time |
float |
default 0.0
|
Absolute timeline time of the frame. |
ReturnsA PNG image — the ONLY tool here that returns an image rather than a dict. A render failure comes back as {"error": ...} instead.
- this is the agent's eyes on the edit before export — call it instead of guessing
- rendering happens in this process; there is no separate render service to poll
Choose the timeline time whose frame is exported as the project's cover image.
Parameters
editor_set_cover parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| at_time |
float |
required
|
Absolute timeline time of the cover frame. |
ReturnsThe project summary — {project_id, version, metadata, aspect, fps, target_sec, tracks, elements, assets}.
- the cover PNG is rendered by the next editor_export, beside the mp4
- a cover render failure never fails the export itself
Check the project for problems before spending a render on it.
Parameters
editor_validate parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| profile |
str |
default "structural"
|
"structural" checks only for a broken render; "shorts" also enforces the project's own bounds. |
Returns{errors, ok}.
- editor_export runs the same validation and refuses to render when it fails
- the "shorts" profile enforces the duration, clip-count and audio-coverage rules set at project creation
Validate the project and, when it passes, render it synchronously to an mp4.
Parameters
editor_export parameters
| Name |
Type |
Required |
Description |
| project_id |
str |
required
|
The project to act on. |
| profile |
str |
default "structural"
|
Validation profile applied before rendering. |
| preset |
str |
default "shorts_1080"
|
Encoder preset: "shorts_1080", "preview_720" or "master". |
Returns{ok, output_path, cover_path, version, validation_errors}.
- re-exporting an already-exported project is refused — call editor_reopen_project first
- export IS the render: the call blocks until the file exists, there is no job to poll
- a resolution override never changes the stored project, only that one render
- the rendered file is a DELIVERY, not an archive: take it within 24 hours (download it, or POST /api/media/from-export to keep it in your media library) or the server drops it
- taking it deletes the server's copy immediately — that is the point, and re-exporting the current version reproduces the file
- what survives indefinitely is the project, its operation journal and its saved versions, not the mp4; a re-render of a project whose source clips have since gone offline can fail
- a saved version stores the TIMELINE, not the render: restoring one and exporting again re-renders from the sources, it does not bring an expired mp4 back
No tools match that filter. Clear the field, or press
Esc, to see all 44 again.