Video Editor
Create editable videos, upload media, add clips, and apply edits.
The editor API lets you create editable videos, upload media, add existing media to a timeline, and apply direct edits.
Editor videos created through this API use status: "ready" because ready means the editor project exists and can be opened. Exporting or downloading an MP4 is a separate action.
POST /editor/videos
Creates an editable project that is ready to open immediately.
Requires generations:write.
curl -X POST https://videotok.app/api/v1/editor/videos \
-H "Authorization: Bearer vt_live_..." \
-H "Content-Type: application/json" \
-d '{
"title": "TikTok ad draft",
"aspect_ratio": "9:16",
"fps": 30
}'
GET /editor/videos
Lists editable videos.
Requires generations:read or generations:write.
curl https://videotok.app/api/v1/editor/videos \
-H "Authorization: Bearer vt_live_..."
GET /editor/videos/{id}
Returns one editable video.
Requires generations:read or generations:write.
curl https://videotok.app/api/v1/editor/videos/1234 \
-H "Authorization: Bearer vt_live_..."
POST /editor/media
Uploads media to the workspace media library.
It can also add the uploaded media directly to an editor video.
Requires generations:write.
Use one upload source per request:
| Source | When to use it |
|---|---|
media | Inline base64 or data URL for small files already available in memory. |
source_url | HTTPS URL that Videotok downloads into My Media. Best for large agent-generated files, signed URLs, and rendered videos. |
multipart file | REST clients uploading a local image, video, or audio file with multipart/form-data. |
Hosted APIs cannot read a local file:// path directly. Upload the file as multipart data, pass inline base64 for small files, or make it available through a temporary HTTPS URL and use source_url.
Inline JSON:
curl -X POST https://videotok.app/api/v1/editor/media \
-H "Authorization: Bearer vt_live_..." \
-H "Content-Type: application/json" \
-d '{
"media_type": "image",
"title": "Product image",
"video_id": 1234,
"add_to_editor": true,
"media": {
"filename": "product.png",
"content_type": "image/png",
"data": "iVBORw0KGgo..."
},
"placement": {
"from_seconds": 0,
"duration_seconds": 4,
"fit": "cover"
}
}'
Remote URL:
curl -X POST https://videotok.app/api/v1/editor/media \
-H "Authorization: Bearer vt_live_..." \
-H "Content-Type: application/json" \
-d '{
"media_type": "video",
"title": "Hyperframes export",
"source_url": "https://files.example.com/hyperframes-export.mp4",
"filename": "hyperframes-export.mp4"
}'
Local file:
curl -X POST https://videotok.app/api/v1/editor/media \
-H "Authorization: Bearer vt_live_..." \
-F "media_type=video" \
-F "title=Hyperframes export" \
-F "file=@/path/to/hyperframes-export.mp4"
The response includes a completed My Media media.id. Use that id with publish_media_to_social, POST /editor/videos/{id}/media, or generation media-id fields such as source_video_media_id.
GET /editor/media
Lists media available to the editor.
Requires generations:read or generations:write.
| Parameter | Notes |
|---|---|
media_type | image, video, audio, or voice. audio includes voice assets; use voice for voice-only. |
query | Searches filename and indexed text. |
limit | 1 to 100. Default is 30. |
curl "https://videotok.app/api/v1/editor/media?media_type=image&limit=20" \
-H "Authorization: Bearer vt_live_..."
POST /editor/videos/{id}/media
Adds existing media or a direct URL to an editor timeline.
Use from_seconds for timeline placement, duration_seconds for visible timeline length, and source_start_seconds when trimming into a source video or audio file.
Requires generations:write.
curl -X POST https://videotok.app/api/v1/editor/videos/1234/media \
-H "Authorization: Bearer vt_live_..." \
-H "Content-Type: application/json" \
-d '{
"media_id": "0c2796d2-43ef-4e13-b1d4-4187696929d6",
"from_seconds": 0,
"duration_seconds": 5,
"fit": "cover"
}'
Direct URL:
{
"url": "https://example.com/clip.mp4",
"media_type": "video",
"filename": "clip.mp4",
"duration_seconds": 8,
"from_seconds": 0,
"fit": "cover"
}
PATCH /editor/videos/{id}
Applies direct edits.
Requires generations:write.
curl -X PATCH https://videotok.app/api/v1/editor/videos/1234 \
-H "Authorization: Bearer vt_live_..." \
-H "Content-Type: application/json" \
-d '{
"instructions": "Move the product image later and rename the project.",
"operations": [
{
"type": "set_title",
"title": "Final TikTok ad"
},
{
"type": "set_item_timing",
"item_id": "item_abc",
"from_seconds": 1.5,
"duration_seconds": 4
}
]
}'
Supported Edit Operations
| Type | Fields |
|---|---|
set_title | title |
remove_item | item_id |
set_item_timing | item_id, from_seconds, duration_seconds |
set_item_source | item_id, source_start_seconds, playback_rate |
set_item_audio | item_id, volume_db, audio_fade_in_seconds, audio_fade_out_seconds |
set_audio_levels | item_ids, exclude_item_ids, item_types, audio_roles, volume_db, audio_fade_in_seconds, audio_fade_out_seconds |
set_item_animation | item_id, enter, exit |
apply_item_transition | from_item_id, to_item_id, overlap_seconds, enter, exit |
split_item | item_id, at_seconds |
set_item_transform | item_id, left, top, width, height, opacity |
move_item_to_track | item_id, track_id |
set_item_layer_order | item_id, position |
add_text | text, from_seconds, duration_seconds, style |
update_text | item_id, text, style |
add_captions | captions, from_seconds, duration_seconds, style |
add_sound_effect | sound_effect_id, url, media_id, from_seconds, duration_seconds, volume_db |
add_voiceover | text, voice_id, from_seconds, volume_db, voice_settings |
update_captions | item_id, captions, style |
generate_captions_from_items | source_item_ids, captions_item_id, language, style |
Caption entries use Remotion-style JSON timing: text, startMs, endMs, optional timestampMs, optional confidence, and optional word-level words.
When track_id is omitted, added media is packed onto compatible existing tracks when timelines do not overlap. Only force a new or explicit track when layer order or overlap requires it.
Music, voiceovers, voice assets, and SFX are audio timeline items. Use set_item_audio for one item, or set_audio_levels to lower/duck groups by audio_roles (sound_effect, music, voiceover, voice, source_video, audio) or by item_types. Older audio items without audioRole are inferred from asset metadata and normalized when matched. Do not remove SFX just to lower their volume.
Use add_voiceover to generate a fresh TTS voiceover from text and add it as an audio item on the timeline. Use set_item_audio on video/audio items to mute, lower, duck, or fade original audio around the voiceover. Use add_editor_media for background music from My Media or an HTTPS URL with audio_role: "music", then lower it with set_item_audio or set_audio_levels.
Use set_item_layer_order with position: "front" for captions and text overlays that must appear above video. New add_text, add_captions, and generated caption items are placed on a front layer by default. When top is omitted, new text overlays choose a safe vertical slot to avoid overlapping existing timed text/captions.
Use set_item_animation for native editor visual transitions on videos, images, GIFs, text, and captions. Supported transition types are fade, slide, scale, bounce, flip, zoom, glitch, swipe, float, and snap. Set enter for how an item appears and exit for how it leaves. Pass null for enter or exit to clear an existing transition. Use apply_item_transition when you want a crossfade-style edit: it moves the incoming item earlier so it overlaps the outgoing item, then applies enter/exit animations. Use add_sound_effect for audible transition hits.
Use generate_captions_from_items to create native editor captions from the actual audio in selected video or audio items. It respects each item's timeline placement, source trim, playback rate, and duration, then creates or replaces a front-layer captions item. This requires transcribable remote media on the source items and the configured transcription provider.