Episodes
An episode is a numbered partition inside a collection — “Season 1 · Episode 3”, “Podcast #12”, “Chapter 5”. Each episode groups its own set of assets (videos, audio, docs, images) and tracks its own status. Episodes are optional: flat collections (like a plain knowledge base) don’t need them, while series-style types (tv_series, movie, audio_drama, comic_drama) are built around them.
The episode model
| Field | Meaning |
|---|---|
sequenceNo | The episode number. Unique within a collection. Numbering can be dense (1, 2, 3) or sparse (1, 3, 5). |
title / description | Episode metadata. |
status | draft → generating → ready → published → archived. |
coverImageId | Optional cover image. |
assetCount / sizeBytes | Cached totals for the episode’s assets. |
Creating two episodes with the same sequenceNo in one collection is rejected with EPISODE_SEQUENCE_CONFLICT (409) — each number is unique.
Managing episodes
In the dashboard, open a collection and use the Episodes panel to create, reorder (by sequenceNo), edit, and delete episodes, and to filter by status (e.g. show only ready).
For developers, episodes are standard CRUD under a collection (see the API playground):
| Method | Path | Purpose |
|---|---|---|
POST | /v1/collections/{id}/episodes | Create an episode |
GET | /v1/collections/{id}/episodes | List episodes (filter by status, cursor-paginated) |
GET | /v1/collections/{id}/episodes/{epId} | Episode detail |
PATCH | /v1/collections/{id}/episodes/{epId} | Update |
DELETE | /v1/collections/{id}/episodes/{epId} | Soft delete |
Attaching assets — the sync flow
To attach already-uploaded resources to an episode in bulk, use episode sync:
POST /v1/collections/{id}/episodes/{epId}/sync{ "idempotencyKey": "batch-2026-07-04-001", "assets": [ { "resourceType": "video", "resourceId": "vid_xxx", "sourceHash": "…" }, { "resourceType": "doc", "resourceId": "doc_yyy" } ]}The response reports each asset’s outcome plus totals:
{ "episodeId": "…", "collectionId": "…", "applied": [ { "resourceType": "video", "resourceId": "vid_xxx", "status": "applied" }, { "resourceType": "doc", "resourceId": "doc_yyy", "status": "skipped_duplicate", "reason": "natural_key_matched" } ], "appliedCount": 1, "skippedCount": 1, "failedCount": 0, "totalCount": 2, "syncedAt": "…"}Two safety properties make this reliable for automated pipelines:
- Idempotent — pass an
Idempotency-Key(header or body). A repeat of the same batch within 24h replays the original result (X-Idempotent-Replay: true) instead of double-attaching. - Double dedup — an asset is skipped if its
sourceHashwas already seen (source_hash_matched) or if the same(episode, resourceType, resourceId)is already attached (natural_key_matched). - Error isolation — one bad asset (e.g.
resource_not_found,forbidden) is reported inapplied[].reason; it never aborts the rest of the batch. The call returns200even on partial failure.
Up to 100 assets per sync request.
Third-party AI pipelines
If you generate media with AI tools (ComfyUI, Replicate, OpenAI Sora, Diffusers…) and want each batch to land as an episode with a full audit trail, the sync flow above is the integration point — but the end-to-end guide, including the SDK calls, OAuth Device Flow for headless CLIs, and the admin audit view, lives in:
Next
- Collections overview — the container model and quotas.
- Collection types — which types are episode-oriented.