/v2/workspaces is the endpoint, “folder” is the word in the UI.
Two things make folders useful beyond tidiness:
- Generated output files itself. Send a folder on a generation request and every output lands in that folder — no follow-up call.
- Every file filter works inside a folder.
?workspace=composes with search, kind, tool and favorites, so the same query means the same thing whether you scope it to a folder or not.
Create a folder
slug it is derived from the name and given a short random suffix, so two folders called “Campaign assets” do not collide. Pass slug yourself to choose it.
Every /v2/workspaces/{id} route accepts a uuid or a slug, so you can keep using the readable one:
GET /v2/workspaces returns {"data": [...], "nextCursor": ...} without file_count — it would cost one count per row. Fetch a single folder when you need it.
File generated output into a folder
SendX-Workspace-Id on any job-creating request. The output is linked to the folder when the job completes:
/v2/image, /v2/video, /v2/speech, /v2/music, /v2/ffmpeg), POST /v2/tools/{tool_key}/call, /v2/render and /v2/pipeline.
An unknown folder answers 404 and no job is created. That is deliberate: silently filing your output somewhere else is harder to notice than an error.
workspace_id as a top-level body field instead. Multipart uploads accept a workspace_id form field for the same reason.
The folder is not part of the generation input, so it never affects the cache key — the same prompt filed into two folders is still one billable generation.
Renders put their assets in the folder too
POST /v2/render fans out into sub-generations, and those inherit the render’s folder. So a render started in a folder puts both its final output and the assets it produced along the way there — the folder shows the whole render, not just the result.
To tell them apart, ask POST /v2/lineage for a file: an asset produced inside a render carries a parent_job_id, and root_job_id points at the render you started. /v2/pipeline behaves the same way.
List a folder’s files
Filter files by folder
GET /v2/files takes ?workspace= and composes it with every other filter:
unfiled is a reserved value meaning “files in no folder” — useful for finding what still needs sorting.
Filtering happens in the database, not on the returned page, so kind=video inside a folder means every video in that folder rather than the videos among the most recent 50.
Move files in and out
Endpoints
{id} is a uuid or a slug on all of them.
There is no
DELETE /v2/workspaces/{id}. Folders are shared with the dashboard, where deleting one also affects the projects and members attached to it, so folder deletion lives there until those semantics are settled. Empty a folder with the per-file DELETE above.