Edit-Token Endpoints
Once you have an editToken from Create Video, the following
endpoints are reachable without an API key (the token is the auth). All paths
are prefixed with /v1/platform/videos/edit/:editToken.
| Method | Path | Purpose |
|---|---|---|
GET | / | Get full video + scenes |
PATCH | / | Update video metadata (title, aspect, BGM volume, etc.) |
POST | /scenes | Add a new scene |
PATCH | /scenes/:sceneId | Update a scene's script, keywords, durations, transitions |
DELETE | /scenes/:sceneId | Delete a scene |
PUT | /scenes/reorder | Reorder scenes by ID list |
POST | /scenes/:sceneId/tts | Regenerate TTS audio for a scene |
POST | /scenes/:sceneId/clip/search | Search Pexels + Pixabay for stock clips |
POST | /scenes/:sceneId/clip/select | Apply a selected stock clip |
POST | /scenes/:sceneId/clip/upload | Upload a custom video clip (multipart) |
POST | /sync-durations | Recompute scene durations from TTS audio buffers |
POST | /thumbnail | Upload a thumbnail image (multipart) |
POST | /bgm/search | Search BGM presets |
POST | /bgm/select | Apply a BGM preset |
DELETE | /bgm | Remove BGM |
POST | /render | Start a Remotion render |
POST | /render/cancel | Cancel an in-progress render |
The token rotates on demand only — it does not rotate on read. Each GET
extends editTokenExpiresAt by 1 hour from now (sliding window), so any URL
you've already shared keeps working as long as someone uses it.
GET /
Returns the full video including all scenes.
curl https://api.tutorflow.io/v1/platform/videos/edit/{editToken}Returns a VideoEditResDto:
{
"videoRequestId": "e41a085a-e43f-4f63-92f4-9e11250f6e63",
"platformVideoId": "e10b8286-94ad-4139-a946-3548b46f6d07",
"title": "What Is Photosynthesis for Kids?",
"description": null,
"aspectRatio": "16:9",
"visibility": "PRIVATE",
"renderStatus": "IDLE",
"videoKey": null,
"thumbnailKey": null,
"bgmAudioKey": null,
"bgmVolume": 0.15,
"bgmOffset": 0,
"userNarrationScript": null,
"slug": "what-is-photosynthesis-for-kids-d6a02f3b",
"metadata": { "language": "en", "sceneCount": 4, "targetDurationSeconds": 30 },
"scenes": [
{
"id": "uuid-1",
"order": 0,
"script": "Photosynthesis is how plants make their own food…",
"displayText": null,
"ttsAudioKey": "platform/{workspaceId}/videos/{videoId}/scenes/uuid-1/tts.mp3",
"videoClipKey": null,
"videoClipSource": null,
"remotionTemplate": "keyword",
"keywords": ["plant", "sunlight"],
"duration": 7.2,
"audioOffset": 0,
"audioDuration": 6.2,
"videoOffset": 0,
"videoDuration": null,
"subtitleOffset": 0,
"subtitleDuration": 6.2,
"subtitles": [{ "text": "Photosynthesis is how plants make their own food", "offset": 0, "duration": 3.1 }],
"transitionOut": null,
"transitionDuration": 1,
"videoEffect": null,
"metadata": null
}
],
"editToken": "2dce...",
"editTokenExpiresAt": "2026-04-25T15:15:28.628Z",
"shareToken": "b64a..."
}PATCH /
Update video-level metadata.
curl -X PATCH https://api.tutorflow.io/v1/platform/videos/edit/{editToken} \
-H "Content-Type: application/json" \
-d '{ "title": "Updated Title", "aspectRatio": "9:16", "bgmVolume": 0.2 }'| Field | Type | Description |
|---|---|---|
title | string | Updated title |
description | string | null | Updated description |
aspectRatio | string | 16:9, 9:16, or 1:1 |
visibility | string | PUBLIC or PRIVATE |
bgmAudioKey | string | null | S3 key for custom BGM (use bgm/select for presets) |
bgmVolume | number | 0.0–1.0 |
bgmOffset | number | Seconds into BGM track to start |
userNarrationScript | string | null | Manual narration override |
videoKey | string | null | Override the rendered mp4 key |
thumbnailKey | string | null | Override the thumbnail key |
metadata | object | Free-form metadata |
Returns the updated VideoEditResDto.
Scene Mutations
POST /scenes
Add a scene at the end (or at a specific order).
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes \
-H "Content-Type: application/json" \
-d '{
"script": "And that is how the carbon cycle returns oxygen to the atmosphere.",
"duration": 6,
"keywords": ["forest", "atmosphere"],
"remotionTemplate": "keyword"
}'| Field | Type | Required | Description |
|---|---|---|---|
script | string | Yes | Narration text. Used for TTS and subtitle generation. |
order | number | No | Position in the scene list (0-indexed). Defaults to end. |
displayText | string | No | On-screen text overlay (for title/quote templates). |
remotionTemplate | string | No | keyword, title, quote, or none. Defaults to keyword. |
keywords | string[] | No | Used for clip search and overlay. |
duration | number | No | Scene duration in seconds. Auto-computed from TTS if omitted. |
transitionOut | string | No | Transition to the next scene: fade, slide, wipe. |
Returns the created VideoSceneResDto.
PATCH /scenes/:sceneId
Update any scene field. Common fields:
| Field | Type | Description |
|---|---|---|
script | string | New narration. Does not regenerate TTS — call POST /scenes/:sceneId/tts after. |
displayText | string | null | On-screen overlay text. |
keywords | string[] | Keywords for clip search / overlay. |
remotionTemplate | string | keyword, title, quote, or none. |
duration | number | Scene duration in seconds. |
audioOffset / audioDuration | number | TTS clip timing within the scene. |
videoOffset / videoDuration | number | Stock clip timing. |
subtitleOffset / subtitleDuration | number | Subtitle timing. |
subtitles | array | Override subtitle chunks: [{ text, offset, duration }, …]. |
transitionOut | string | null | Transition style. |
transitionDuration | number | Transition duration in seconds. |
videoEffect | string | null | none, overlay-dark, vignette, blur, grayscale, etc. |
Returns the updated VideoSceneResDto.
DELETE /scenes/:sceneId
Removes a scene.
curl -X DELETE https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes/{sceneId}Returns 204 No Content.
PUT /scenes/reorder
Replace the scene order in a single call.
curl -X PUT https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes/reorder \
-H "Content-Type: application/json" \
-d '{ "sceneIds": ["uuid-3", "uuid-1", "uuid-2", "uuid-4"] }'Returns the updated VideoEditResDto.
TTS
POST /scenes/:sceneId/tts
Regenerate the TTS audio for a single scene. Use after editing the scene's
script. Re-distributes subtitle timing based on the new audio length.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes/{sceneId}/ttsReturns the updated VideoSceneResDto with the new ttsAudioKey,
audioDuration, subtitleDuration, and subtitles.
Stock Clips
POST /scenes/:sceneId/clip/search
Search Pexels + Pixabay for matching stock clips. Returns interleaved results so the UI shows variety.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes/{sceneId}/clip/search \
-H "Content-Type: application/json" \
-d '{ "keyword": "sunlight on leaves" }'Response:
[
{ "source": "pexels", "sourceId": 7845321, "thumbnailUrl": "...", "previewUrl": "...mp4", "duration": 12 },
{ "source": "pixabay", "sourceId": 142398, "thumbnailUrl": "...", "previewUrl": "...mp4", "duration": 8 }
]POST /scenes/:sceneId/clip/select
Apply a selected clip. The server downloads the clip from previewUrl and
re-uploads it to the workspace's S3 path.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes/{sceneId}/clip/select \
-H "Content-Type: application/json" \
-d '{
"source": "pexels",
"sourceId": 7845321,
"previewUrl": "https://videos.pexels.com/.../clip.mp4"
}'Returns the updated VideoSceneResDto with the new videoClipKey.
POST /scenes/:sceneId/clip/upload
Upload your own clip as multipart/form-data.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/scenes/{sceneId}/clip/upload \
-F "file=@my-clip.mp4"Returns the updated VideoSceneResDto.
Background Music
POST /bgm/search
Search the BGM preset library.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/bgm/search \
-H "Content-Type: application/json" \
-d '{ "keyword": "uplifting" }'Response:
[
{ "id": "preset-001", "title": "Sunny Acoustic", "tags": ["uplifting", "warm"], "durationSeconds": 142, "s3Key": "..." }
]Pass keyword: "" (or omit) to list all presets.
POST /bgm/select
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/bgm/select \
-H "Content-Type: application/json" \
-d '{ "presetId": "preset-001" }'Returns the updated VideoEditResDto with bgmAudioKey set and metadata
populated with bgmTitle and bgmPresetId.
DELETE /bgm
curl -X DELETE https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/bgmClears bgmAudioKey and removes bgmTitle / bgmPresetId from metadata.
Sync Durations
After editing scripts or replacing TTS audio, run sync-durations to recompute scene durations from the actual audio buffers. This is normally automatic but can be useful after bulk edits.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/sync-durationsResponse:
{ "updated": 3 }Thumbnail
POST /thumbnail
Upload a thumbnail image as multipart/form-data.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/thumbnail \
-F "file=@thumb.jpg"Returns the updated VideoEditResDto with thumbnailKey set.
Render
POST /render
Start a Remotion render. The Lambda runs asynchronously and updates
renderStatus via callback. Pre-sets videoKey to where the mp4 will land.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/renderReturns the updated VideoEditResDto:
{
"renderStatus": "RENDERING",
"videoKey": "platform/{workspaceId}/videos/{videoId}/rendered/photosynthesis-1dvr.mp4",
"...": "..."
}Poll GET /v1/platform/videos/edit/:editToken until renderStatus is
COMPLETED or FAILED. Typical render time: 1–3 minutes.
POST /render/cancel
Reset a stuck or unwanted render to IDLE. The Lambda may still finish in the
background, but its callback is ignored.
curl -X POST https://api.tutorflow.io/v1/platform/videos/edit/{editToken}/render/cancelReturns the updated VideoEditResDto.