Developer docs

Developer docs/API

Edit commands

Every edit the window can make, as a JSON object you send through `edit.apply`.

{
  "method": "edit.apply",
  "path": "/edits/Reel",
  "command": { "op": "trimClip", "clipId": "c2", "edge": "end", "delta": -1.5 }
}

A command is {"op": "<name>", …fields}. Fields are camelCase. The reply is an EditorView (Types) of the project after the edit; createdId names what the command made, if anything.

Cheat sheet

OpDoesMakes
Media
addMediafile into the binm…
removeMediabin item and every clip of it, out
updateMediaPathrelink a file
setMediaColorRangesay whether a file is really limited or full range
replaceClipMediapoint a clip at another filem… if new
Placing clips
addClipmedia on a named trackc…
addClipAtFirstFreemedia on the first free trackc…
addTextClipa titlec…
addLayerClipan effect layer over everything beneathc…
freezeFramea held still, cut into a clipc…
Moving and cutting
moveClipsreposition any number of clips
trimClipdrag one edge
splitClipscut at a timec… (the tail)
mergeClipsrejoin split pieces
removeClipsdelete
Changing a clip
updateClippatch: name, volume, fades, opacity, effects, transition, text, crop…
setClipTransformscale, offset, rotation, stretch
setClipSpeedplayback rate
setClipSpeedCurvespeed over time
setClipKey · clearClipKey · clearClipKeyskeyframes on scale, offset, rotation, opacity, volume
setEffectKey · clearEffectKey · clearEffectKeyskeyframes on an effect parameter
setClipCutout · addCutoutStrokebackground removal and brush corrections
detachAudio · reattachAudioa video’s sound as its own clip, and backc…
Tracks
addTracka new lanet…
removeTracka lane and its clips, out
setTrackFlagvisible / muted
Timelines
addTimelinea new timeline, made activetl…
removeTimeline · renameTimeline · selectTimeline · moveTimeline · setTimelineVideomanage timelines
Templates and fonts
setMediaPlaceholder · fillSlottemplate slots
addFont · removeFontfonts for titles
Grouping
batchseveral commands as one undo steplast id inside

Rules that apply to every command

  • Ids. Clips are c…, tracks t… (the first timeline’s starter lanes are T1–T4), timelines tl… (the first is TL1), media m…. Ids come from the EditorView replies.
  • Unknown ids are usually a tolerated no-op: the request succeeds, nothing changes, no undo step. Where a command errs instead, its entry says so.
  • Times are seconds on the timeline. A start below 0 lands at 0.
  • Numbers are clamped, not refused, into the range each field states. A NaN or infinite number is refused: “A number in that edit is not finite.”
  • A refusal is a refused error whose message is the exact sentence the window would show. The project is as it was.
  • Commands act on the active timeline, except where the entry says “all timelines”.

Refusal sentences

SentenceRaised by
That media is no longer in the bin.a clip-placing command whose media is gone
That track no longer exists.a clip-placing command whose track is gone
There are no tracks.first-free placement on a timeline with no tracks
A timeline needs at least one track.removeTrack on the last track
A project needs at least one timeline.removeTimeline on the last timeline
That template slot no longer exists.fillSlot with an unknown id
That media is not a template slot.fillSlot on ordinary media
A number in that edit is not finite.any command carrying NaN or infinity
(one of several sentences)mergeClips, saying why the pieces cannot be rejoined

Media

addMedia

Imports a probed file into the bin, minting an m id.

FieldTypeMeaning
itemNewMediaThe file as media.probe describes it (see Types)

A path already in the bin is a no-op that mints nothing.

removeMedia

Removes a bin item and every clip referencing it, on all timelines.

FieldTypeMeaning
mediaIdstringThe bin item. Unknown id: no-op

updateMediaPath

Relinks a bin item to a new path on disk.

FieldTypeMeaning
mediaIdstringThe bin item. Unknown id: no-op
newPathstringThe new absolute path

setMediaColorRange

Says what levels a media file’s picture really spans, over whatever the file claims. The fix for a washed-out or crushed picture.

FieldTypeMeaning
mediaIdstringThe bin item. Unknown id: no-op
range"limited", "full" or nulllimited is 16-235, full is 0-255. null goes back to reading the file’s own tag
{ "op": "setMediaColorRange", "mediaId": "m1", "range": "full" }

When to use which:

  • A screen recording that plays grey where it should be black is a full-range file tagged nothing. Set full.
  • A file whose shadows are crushed and highlights clipped is a video-range file tagged full. Set limited.
  • media.probe reports what the file claims as video.colorRange.

Reaches every clip of the media, on every timeline, in the monitor and the export alike. Stored in the document; absent means “as tagged”.

replaceClipMedia

Points a clip at another file, adding it to the bin first if it is not there. The clip keeps its length, looks and name, and its in-point unless sourceStart moves it: an enhanced copy stands in frame for frame, a reversed span starts at its own zero. The bin keeps the original.

FieldTypeMeaning
clipIdstringThe clip. Unknown id: no-op
itemNewMediaThe probed file
sourceStartnumberoptional. A new in-point in the copy, in seconds

Placing clips

addClip

Places a clip of a bin item on a named track.

FieldTypeMeaning
mediaIdstringThe bin item. Gone: refused
trackIdstringThe lane. Gone: refused
startnumberSeconds; floored at 0
ripplebooloptional, default false. When the drop would overlap, shift every clip at or after start right by the new clip’s length

Duration comes from the media: its own length for video and audio, 5 s for a still or a file with no reported length.

{ "op": "addClip", "mediaId": "m1", "trackId": "T1", "start": 2.5 }

addClipAtFirstFree

addClip without naming a lane: lands on the lowest track with nothing in the clip’s span, or on the bottom track (overlapping) rather than refusing.

FieldTypeMeaning
mediaIdstringThe bin item. Gone: refused
startnumberSeconds; floored at 0

addTextClip

Places a title: a clip with no media behind it, named after the text’s first line.

FieldTypeMeaning
trackIdstringoptional. The lane. Absent picks a free track; a vanished track is refused
abovebooloptional, default false. With no trackId: land on the first free lane above the highest occupied one, minting a lane at the top if needed. What the editor does for its own titles and captions
startnumberSeconds; floored at 0
styleTextStyleoptional. Only the fields you set; the rest are the window’s defaults. {"content": "Hello"} is enough
durationnumberoptional, default 4 s
offsetYnumberoptional. Vertical placement as a fraction of frame height, clamped to ±3. Lower thirds are made of this
{
  "op": "addTextClip",
  "start": 1,
  "duration": 3,
  "style": { "content": "Chapter one", "fontSize": 0.12, "color": "#ffcc00" },
  "offsetY": 0.35
}

addLayerClip

Places a layer: an effect over a span of the timeline that treats everything beneath it. The chain starts as the one package at its defaults; the clip’s opacity is how hard it is applied.

FieldTypeMeaning
trackIdstringoptional. Absent picks the first free track
startnumberSeconds; floored at 0
durationnumberoptional, default 5 s
effectIdstringA package id from catalogue.list, e.g. concat.warm
namestringWhat the lane calls it

freezeFrame

Splits a clip at time, inserts a held still, and ripples later clips on that track by the hold’s length. createdId is the freeze clip.

FieldTypeMeaning
clipIdstringA picture clip under the playhead
timenumberMust fall strictly inside the clip
durationnumberoptional, default 1 s; floored at 1/60 s
stillNewMediaThe probed still (a JPEG of the frame). Required for video; an image clip may omit it and reuse its media

Audio and text clips: no-op.


Moving and cutting

moveClips

Repositions any number of clips as one undo step.

FieldTypeMeaning
movesarray of {clipId, start, trackId}Where each clip goes. start floors at 0. Unknown clipId: that move is skipped. Unknown trackId: moved in time, kept on its track
{
  "op": "moveClips",
  "moves": [
    { "clipId": "c2", "start": 0, "trackId": "T1" },
    { "clipId": "c3", "start": 6.1, "trackId": "T1" }
  ]
}

trimClip

Drags one edge of a clip.

FieldTypeMeaning
clipIdstringUnknown id: no-op
edge"start" or "end"Which edge
deltanumberSigned timeline seconds. Positive drags the head right (shortening) or the tail right (lengthening)
ripplebooloptional, default false. Close the lane up behind the trim: later clips on the track move by the change in length

How the edges differ:

  • start moves the in-point with the edge (scaled by speed), so the remaining frames stay where they were.
  • end only lengthens or shortens.
  • Either edge stops at the 1/60 s minimum duration.

splitClips

Cuts each named clip in two at one time.

FieldTypeMeaning
clipIdsstring[]The clips under the playhead
timenumberThe cut point, in timeline seconds
  • The head keeps the id and the transition; the tail is minted fresh and stays source-continuous.
  • A clip the time misses, or grazes within 1/60 s of an edge, is skipped.

mergeClips

Rejoins split pieces into the earliest piece, which keeps its id.

FieldTypeMeaning
clipIdsstring[]The pieces, any order

Refused unless the pieces sit on one track, come from one file at one speed, touch within a microsecond, and are in source order. The message says which condition failed.

removeClips

Deletes clips from the active timeline.

FieldTypeMeaning
clipIdsstring[]Unknown ids are ignored
ripplebooloptional, default false. Leave no gap: on each touched track, later clips move left by the removed spans before them. Untouched tracks stay put

Changing a clip

updateClip

Applies a patch: only the fields present change.

FieldTypeMeaning
clipIdstringUnknown id: no-op
patchClipPatchThe fields to change

ClipPatch fields (all optional):

FieldTypeClamp / meaning
namestringTaken verbatim
volumenumberFloored at 0; not capped at 1
fadeIn, fadeOutnumberSeconds, floored at 0
opacitynumber0..=1
preservePitchboolKeep voices at pitch when speed ≠ 1
mutedboolSilence the clip’s own sound
flipH, flipVboolMirror
blendstringnormal (or empty), multiply, screen, add, lighten, darken
filtersAppliedFilter[]Replaces the whole audio chain
videoEffectsAppliedFilter[]Replaces the whole video chain
cropCrop or nullSee below
transitionInTransition or nullThe transition on the cut into the clip
textTextStyle or nullTitle styling; also renames the clip after its first line
audioStreaminteger or nullWhich of the media’s audio streams to play; null means the file’s first
{
  "op": "updateClip",
  "clipId": "c2",
  "patch": {
    "volume": 0.5,
    "fadeIn": 0.5,
    "videoEffects": [{ "id": "concat.gaussian-blur", "params": { "radius": 4 } }],
    "transitionIn": { "id": "concat.dissolve", "duration": 0.75 }
  }
}

setClipTransform

Places the picture. Send only the fields you moved.

FieldTypeClamp
clipIdstringUnknown id: no-op
scalenumber0.05..=8
offsetXnumberFraction of frame width, ±3
offsetYnumberFraction of frame height, ±3
rotationnumberDegrees, wrapped into (-180, 180]
stretchX, stretchYnumber0.1..=10, a multiplier beyond scale

setClipSpeed

Changes the playback rate while holding the source covered constant: the timeline length is what stretches.

FieldTypeClamp
clipIdstringUnknown id: no-op
speednumber0.0625..=16

setClipSpeedCurve

Speed that changes over the clip.

FieldTypeMeaning
clipIdstringThe clip
curveSpeedPoint[] or nullPoints of {at, speed}, at a fraction 0..=1 of the clip. null returns to a constant rate at the current mean

setClipKey

Puts a keyframe on one property at one point of the clip.

FieldTypeMeaning
clipIdstringThe clip
property"scale", "offsetX", "offsetY", "rotation", "opacity", "volume"Which property
atnumberWhere in the clip, 0..=1
valuenumberThe value there, in the property’s own units
ease[x1, y1, x2, y2]optional, default linear. A CSS-style cubic bezier; the names "linear", "in", "out", "inOut" are accepted too

A key within 0.002 of at on the same property is replaced.

clearClipKey

Removes the key at at on one property, if there is one.

FieldType
clipIdstring
propertyas above
atnumber, 0..=1

clearClipKeys

Removes every key on one property.

FieldType
clipIdstring
propertyas above

setEffectKey

A keyframe on one parameter of one link in the clip’s video chain.

FieldTypeMeaning
clipIdstringThe clip
entryintegerIndex into videoEffects. Out of range: no-op
keystringThe parameter’s key from catalogue.list
atnumber0..=1
valuenumberThe parameter’s own value; keep it within the package’s range yourself
ease[x1, y1, x2, y2]optional, default linear

clearEffectKey

Removes the key at at on one parameter of one link.

FieldType
clipIdstring
entryinteger
keystring
atnumber

clearEffectKeys

Removes every key on one parameter of one link.

FieldType
clipIdstring
entryinteger
keystring

setClipCutout

Sets or clears a picture’s cutout: the mask that removes its background.

FieldTypeMeaning
clipIdstringUnknown id: no-op
cutoutCutout or null{"mode": "auto"} is the usual start; null takes it off

Cutout fields: mode (auto or custom), subject (auto, person, object; default auto), feather (edge softness as a fraction of the picture’s width), strokes (corrections, see next).

Masks are found at export time; export.run reports it as cutout.progress.

addCutoutStroke

Paints one brush stroke onto a clip’s cutout. A clip with no cutout gets a custom one; an automatic cutout becomes custom.

FieldTypeMeaning
clipIdstringUnknown id: no-op
strokeStroketool (smartBrush, brush, smartEraser, eraser), size (diameter as a fraction of picture width), points ([[x, y], …] as fractions of the source picture), at (optional source second the stroke was painted at)

A stroke with no points is a no-op.

detachAudio

Pulls a video clip’s sound out into its own audio clip on a free lane, muting the video and moving its audio filters to the sound.

FieldType
clipIdstring, the video clip

No-op unless the clip is an unmuted video whose media has audio and is not already detached.

reattachAudio

Undoes a detach: deletes the detached sound, unmutes the video, hands the filters back.

FieldType
clipIdstring, the video or its detached sound

Tracks

addTrack

Appends a lane, named after the highest “Track N” in use. No fields.

removeTrack

Deletes a lane and every clip on it.

FieldType
trackIdstring

Refused on the last track.

setTrackFlag

Flips one of a track’s two toggles.

FieldTypeMeaning
trackIdstringUnknown id: no-op
flag"visible" or "muted"Which toggle
valueboolThe new setting

Timelines

addTimeline

Adds a fresh timeline with four lanes and makes it active. No fields.

removeTimeline

Deletes a timeline; the active tab moves to a neighbour if it was this one.

FieldType
timelineIdstring. Unknown id: no-op

Refused on the last timeline.

setTimelineVideo

Sets a timeline’s output frame and rate.

FieldType
timelineIdstring. Unknown id: no-op
videoVideoSettings

A zero dimension or rate is a no-op, not clamped.

renameTimeline

FieldType
timelineIdstring
namestring, trimmed. Whitespace-only is ignored

selectTimeline

Switches which timeline later commands act on.

FieldType
timelineIdstring. Unknown id: selection stays

moveTimeline

Moves a timeline tab to a new position.

FieldType
timelineIdstring
indexinteger, 0-based, counted with the tab already removed; clamped to the end

Templates and fonts

setMediaPlaceholder

Marks a bin item as a template slot, or back to ordinary media.

FieldType
mediaIdstring. Unknown id: no-op
placeholderbool

fillSlot

Swaps a file into a template slot in place, on all timelines. The slot keeps its id, so clips keep working.

FieldType
mediaIdstring, a placeholder
itemNewMedia

Refused if the id is unknown or the item is not a placeholder. template.instantiate does this for every slot for you.

addFont

Registers a font file for titles.

FieldType
familystring, the name titles refer to
pathstring, the font file

A path already registered is a no-op.

removeFont

FieldType
familystring

Clips keep the family name; the face returns when the file does.


Grouping

batch

Several commands as one atomic edit and one undo step.

FieldType
commandsCommand[], applied in order. Nesting is allowed
  • Applied to a staged copy; committed only if every command succeeds.
  • createdId in the reply is the last id minted inside.
{
  "op": "batch",
  "commands": [
    { "op": "addTrack" },
    { "op": "addTextClip", "start": 0, "duration": 2, "style": { "content": "One" } },
    { "op": "addTextClip", "start": 2, "duration": 2, "style": { "content": "Two" } }
  ]
}

Edit this page on GitHub