Episodes
An episode belongs to a project and contains scenes, creator assignments, and a lifecycle status.
Endpoints overviewβ
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /api/episodes | authenticated | List all episodes |
GET | /api/episodes/project/:projectId | authenticated | List episodes by project |
GET | /api/episodes/:id | authenticated | Get episode by ID |
GET | /api/episodes/roles | authenticated | Get workflow roles |
GET | /api/episodes/assignment-template | authenticated | Get assignment template |
PUT | /api/episodes/assignment-template | template:edit | Save assignment template |
POST | /api/episodes | episode:create | Create an episode |
PUT / PATCH | /api/episodes/:id | episode:edit | Update an episode |
DELETE | /api/episodes/:id | episode:delete | Delete an episode |
POST | /api/episodes/preview/upload | episode:preview:upload | Upload episode preview video |
GET | /api/episodes/preview/file/:projectId/:episodeId/preview/:filename | authenticated | Get preview video file |
DELETE | /api/episodes/preview/:projectId/:episodeId | episode:preview:delete | Delete episode preview |
POST | /api/episodes/import/prepare | episode:import | Prepare episode import |
POST | /api/episodes/import | episode:import | Import episode from video |
GET | /api/episodes/import/:jobId/progress | authenticated | Get import job progress |
Endpointsβ
List all episodesβ
GET /api/episodes β Auth required
Supports optional filters. When no params are supplied, all episodes are returned.
Query params (all optional)
| Param | Type | Description |
|---|---|---|
projectId | string | Filter by project UUID |
search | string | Full-text search on title |
status | string | draft | active | completed | paused |
sortBy | string | episodeNumber | title | createdAt | updatedAt |
sortOrder | string | asc | desc |
limit | number | Page size |
offset | number | Page offset |
Response β 200
{
"episodes": [
{
"id": "ep-uuid-001",
"code": "ep01",
"projectId": "proj-uuid-001",
"episodeNumber": 1,
"title": "Episode 1 β The Beginning",
"description": "Pilot episode",
"titleI18n": { "uk": "ΠΠΏΡΠ·ΠΎΠ΄ 1", "en": "Episode 1 β The Beginning", "es": "Episodio 1" },
"descriptionI18n": { "uk": "ΠΡΠ»ΠΎΡΠ½ΠΈΠΉ Π΅ΠΏΡΠ·ΠΎΠ΄", "en": "Pilot episode", "es": "Episodio piloto" },
"icon": null,
"previewUrl": null,
"targetDuration": 300,
"status": "draft",
"safety": null,
"isLocked": false,
"tasks": [
{
"taskId": "task-uuid",
"status": "to-do",
"roleId": "role-uuid",
"roleName": "Script Writer",
"roleNameI18n": { "uk": "Π‘ΡΠ΅Π½Π°ΡΠΈΡΡ", "en": "Script Writer", "es": "Guionista" },
"userId": "user-uuid",
"userEmail": "writer@example.com",
"userEnName": "Alice",
"userEnSurname": "Brown",
"userUaName": "ΠΠ»ΡΡΠ°",
"userUaSurname": "ΠΡΠ°ΡΠ½",
"order": 1
}
],
"createdAt": "2025-01-11T09:00:00.000Z",
"updatedAt": "2025-01-11T09:00:00.000Z",
"approved": false,
"templateId": null
}
],
"total": 1,
"filtered": 1
}
List episodes by projectβ
GET /api/episodes/project/:projectId β Auth required
Response β 200
{
"episodes": [ /* same shape as list above */ ],
"total": 3,
"filtered": 3
}
Get episode by IDβ
GET /api/episodes/:id β Auth required
Response β 200 β single episode object (same shape as list item)
Get workflow rolesβ
GET /api/episodes/roles β Auth required
Returns the list of roles available for episode workflow assignments.
Response β 200
[
{ "id": "role-uuid-1", "name": "Script Writer", "nameI18n": { "uk": "Π‘ΡΠ΅Π½Π°ΡΠΈΡΡ", "en": "Script Writer", "es": "Guionista" } },
{ "id": "role-uuid-2", "name": "Editor", "nameI18n": { "uk": "Π Π΅Π΄Π°ΠΊΡΠΎΡ", "en": "Editor", "es": "Editor" } }
]
Get assignment templateβ
GET /api/episodes/assignment-template β Auth required
Returns the current global assignment template used when creating new episodes.
Response β 200
{
"stages": [
{ "order": 1, "roleId": "role-uuid-1", "roleName": "Script Writer" },
{ "order": 2, "roleId": "role-uuid-2", "roleName": "Editor" }
]
}
Save assignment templateβ
PUT /api/episodes/assignment-template β Auth required, Permission: template:edit
Request body
{
"stages": [
{ "order": 1, "roleId": "role-uuid-1" },
{ "order": 2, "roleId": "role-uuid-2" }
]
}
Response β 200 β updated template object
Create episodeβ
POST /api/episodes β Auth required, Permission: episode:create
Request body
{
"projectId": "proj-uuid-001",
"title": "Episode 1 β The Beginning",
"description": "Pilot episode",
"icon": null,
"targetDuration": 300,
"templateId": "template-uuid"
}
| Field | Required | Notes |
|---|---|---|
projectId | yes | UUID of the parent project |
title | yes | Auto-translated to all locales |
description | no | Auto-translated if provided |
icon | no | |
targetDuration | no | Duration in seconds; defaults to 300 |
templateId | no | If provided, template scenes/blocks are applied after creation |
Response β 201 β created episode object
Update episodeβ
PUT /api/episodes/:id or PATCH /api/episodes/:id β Auth required, Permission: episode:edit
Request body (all fields optional)
{
"episodeNumber": 2,
"title": "Episode 2",
"description": "Second episode",
"icon": "π₯",
"targetDuration": 420,
"status": "active",
"isLocked": false,
"changedBy": "editor@example.com"
}
status values: draft | active | completed | paused
Response β 200 β updated episode object
Delete episodeβ
DELETE /api/episodes/:id β Auth required, Permission: episode:delete
Response β 204
Upload episode preview videoβ
POST /api/episodes/preview/upload β Auth required, multipart/form-data, Permission: episode:preview:upload
Form fields:
| Field | Type | Required |
|---|---|---|
file | video file | yes |
projectId | string (UUID) | yes |
episodeId | string (UUID) | yes |
Response β 201
{ "url": "/api/episodes/preview/file/proj-uuid/ep-uuid/preview/preview.mp4", "filename": "preview.mp4" }
Get episode preview fileβ
GET /api/episodes/preview/file/:projectId/:episodeId/preview/:filename β Auth required
Returns the preview video binary stream.
Delete episode previewβ
DELETE /api/episodes/preview/:projectId/:episodeId β Auth required, Permission: episode:preview:delete
Response β 204
Prepare episode importβ
POST /api/episodes/import/prepare β Auth required, Permission: episode:import
Reserves a job ID for tracking progress via SSE.
Response β 200
{ "jobId": "job-abc123" }
Import episode from videoβ
POST /api/episodes/import β Auth required, multipart/form-data, Permission: episode:import
Transcribes the uploaded video with ElevenLabs, then uses the LLM to generate scenes and blocks. Response is streamed via SSE.
Form fields:
| Field | Type | Required |
|---|---|---|
file | video file | yes |
projectId | string (UUID) | yes |
userPrompt | string | no |
jobId | string | no β use one from /import/prepare |
Response β SSE stream of progress events
{ "progress": 50, "stage": "transcribing", "jobId": "job-abc123" }
{ "progress": 100, "stage": "finalizing", "done": true, "episodeId": "ep-uuid" }
Get import job progressβ
GET /api/episodes/import/:jobId/progress β Auth required
Reconnects to a running SSE stream for the given job.
Response β SSE stream (same event shape as /import)