The editor render payload: one JSON, one video
The editor-render endpoint takes one timeline document covering clips, transitions, text, audio, and captions, and returns a single video.
POST /api/v1/features/editor-render takes one timeline document and returns one video. Clips, transitions, overlays, burned-in text, music, voiceover, and captions all ride in that JSON. The alternative is chaining cut_video, attach_audio, and caption tools and hoping the intermediate URLs survive. For a multi-clip assembly, send the EDL once.
The call is blocking. You wait until data.video_url comes back, or you get an error. There is no request id to poll. Time out your HTTP client above ten minutes; the pipeline gives up at ten. Auth is required. preview is a required boolean, not an optional flag.
The document
Minimum body: preview, and clips with at least one item. Everything else has a default.
{
"preview": true,
"aspect_ratio": "reel",
"resolution": "1080p",
"transition": "concat",
"transition_duration": 0.5,
"clips": [
{
"url": "https://videos.versely.studio/clip-a.mp4",
"type": "video",
"trim_start": 0,
"trim_end": 4,
"speed": 1,
"volume": 1
},
{
"url": "https://img.versely.studio/still.jpg",
"type": "image",
"duration": 3
}
],
"texts": [
{
"text": "Week 12 drop",
"start": 0,
"end": 2.5,
"position": "bottom",
"font_size": 64,
"font_color": "white",
"bold": true
}
],
"musics": [
{
"url": "https://audio.versely.studio/bed.mp3",
"music_volume": 0.25,
"video_volume": 1,
"start": 0
}
],
"voiceovers": [
{
"url": "https://audio.versely.studio/vo.wav",
"start": 0.4,
"volume": 1
}
],
"overlays": [
{
"url": "https://img.versely.studio/logo.png",
"type": "image",
"x": 0.85,
"y": 0.08,
"scale": 0.18
}
],
"captions": {
"mode": "auto",
"language": "auto",
"position": "bottom"
}
}
That is a full cut. A lot of production payloads are smaller: clips plus a transition, preview until the timing is right, then the same document with preview: false.
Clips. 1–20 items. Each needs url and type (video or image). Video may carry trim_start / trim_end (seconds, trim_end > trim_start ≥ 0), speed (0.25–4, default 1), volume (0–2, default 1). Image may carry duration (1–15 seconds, default 3); speed is ignored. Preview itself is capped at 10 clips and 3 minutes of content. Export is capped at 15 minutes of output after speed is applied, which is how a 20-clip slow-motion bomb is refused before encode.
URLs. http or https only. file:// is rejected. So are localhost, .local, and private IPv4 ranges. Stage media in the library (or any public HTTPS URL you already generated) first. This is an SSRF guard, not a taste preference.
Transition. concat (default), fade, dissolve, or wipe. transition_duration defaults to 0.5 seconds and is ignored in spirit by a pure concat.
Aspect and resolution. aspect_ratio is reel (1080×1920), landscape (1920×1080), or square (1080×1080). Default reel. resolution is 720p, 1080p (default), or 4k, and is ignored on preview: preview always renders at 480p. You still have to send preview as a boolean; omitting it is a 400.
Texts. Up to 20. Each needs text (1–200 characters), start, and end. position is top / middle / bottom. font_color is a #rrggbb hex or a named colour from a short allowlist (white, black, yellow, red, green, blue, cyan, magenta, orange, purple, pink). Optional background, outline, border_radius, font_id, font_size (8–200, default 64), bold (defaults true). Free-form colour strings are rejected because they reach the ASS file.
Audio and overlays. Prefer the arrays: musics (max 4), voiceovers (max 4), overlays (max 3). The singular music / voiceover / overlay still work and fold into a one-item list. Music volume is 0–1; voiceover and clip volume are 0–2. Each track can start on the timeline, end trim, and (music / voiceover) start_offset into the file. Overlay needs url, x and y in [0, 1], and scale as a canvas fraction in (0, 2] or a percent in [20, 200]. type is video or image, inferred from the extension if omitted.
Captions. mode is auto or manual. Manual requires captions.text. Auto transcribes and burns. These are burned-in captions, not a sidecar.
The interactive version of this document is the video editor. The agent equivalent is build a video from clips, music, and captions, which posts the same pipeline.
Preview, then export
preview: true renders 480p, does not charge credits, and is rate-limited per user to one pass every 5 seconds. A second preview inside that window is 429 with retry_after_ms. Respect it. The 480p pass is the only free thing on the platform, and the cooldown is how it stays that way. Preview is also capped at 10 clips and 3 minutes; above that, export or trim.
preview: false is the charged export. One charge, one video, regardless of clip count. Overlay, music, voiceover, and captions add to that single charge; burned-in texts[] do not. If the pipeline fails after the charge, the credits are refunded. A 402 on export includes credits_required. There is no free export path, and no free allowance to fall back on.
Iterate in preview. Export once. That is the whole billing shape; previews and the final export is the long version, and a client review loop built on previews is the product version of the same idea.
The 200 looks like:
{
"success": true,
"data": {
"video_url": "https://videos.versely.studio/…",
"credits_charged": 0,
"preview_notes": []
}
}
credits_charged is 0 on preview and the actual charge on export. preview_notes is a list of strings for preview-only skips (background removal on a video overlay is export-only, for example). Read them. They are why the preview and the export can differ.
Paid exports are also filed in the user's library (model: "Editor Render"). Previews are not. If the HTTP client drops after a paid export, look in the library before you POST again.
The pipeline, in order
Knowing the order is how you debug a missing track.
- Merge clips (trim, speed, volume, transition).
- Overlays, in array order. Image overlays composite in-process; video overlays go through the overlay tool and remux the base audio back.
- Texts, burned as ASS.
- Music tracks, mixed.
- Voiceover tracks, mixed.
- Captions, auto or manual.
If captions fight the lower-third texts[], that is this order: both are burned, captions last. Keep title cards in texts and speech in captions, or you will stack two lines on the same pixels. The caption generator is the right place to draft the speech track; this endpoint is where it becomes pixels.
Prefer this one call over stitching clips and then attaching audio in a second hop. Intermediate URLs are how a mix goes missing. The AI video editor tool is the same pipeline with a UI.
Construct the JSON from your own timeline, not from a screenshot of the editor. The editor is an EDL; the payload is that EDL. A rebuild from memory will drift on trim_end and music.start first.
FAQ
Why is preview required if it has a default in my head?
Because the handler will not guess. Omitting it is a 400: preview (boolean) is required. Send true while you iterate, false when you mean to pay. A client that defaults to false in code will charge on every keystroke.
Can I send a local path?
No. file://, localhost, and private IPs are rejected as invalid media URLs. Upload first, then put the HTTPS URL in clips[].url.
Does a preview consume the same clip-count budget as an export?
No. Preview: 10 clips, 3 minutes of content, 5-second per-user cooldown, 480p, no charge. Export: 20 clips, 15 minutes of output, one charge. If your timeline is 12 clips, skip preview and export, or split the cut.
Where did my overlay's black-background removal go on preview?
Preview turns that flag off and tells you in preview_notes. It runs on export. Check the note list before you assume the 480p file is pixel-identical to the paid one.