Download the finished video
/v1/videos/{job_id}/contentServes the clip's actual bytes — MP4 streamed through the gateway, not a redirect.
Request
job_idstringpathrequiredvid_…iintegerquery= 00Responses
200
HTTP/1.1 200 OK
content-type: video/mp4
<байты MP4 — тело файла, не JSON>Details
Needs a key in Authorization: Bearer or x-api-key.
These are exactly the links a finished job returns in data, and any key of the same account can open them. The answer is a 200 with Content-Type: video/mp4 and the file as its body: the gateway fetches the clip from the provider and pipes it to you. There is deliberately no redirect — the host we take the video from is never shown outside, so nobody gets a link to it. By the same principle the result host is checked against an allowlist before the fetch, and the upstream's status is checked BEFORE streaming starts: otherwise the client would get a 200 that dies mid-body.
One request, one clip. When a job returned several (storyboard, multi-output), data holds links with ?i=0, ?i=1, … — take them from there instead of assembling them by hand.
On lifetime. A video job's row holds the provider's link, not our bytes, so retention never clears it — there is nothing of ours to move, and it only stamps the row's archived_at so the row leaves the candidate queue. For video that stamp means precisely "retention is done with this row", not "the bytes have moved out". That does not make the clip available forever: it lives on the provider's side, and its lifetime is neither checked in our code nor guaranteed by us. Download it as soon as you have it.
One and the same 404 covers every case — no such job, someone else's, not finished yet, the result no longer stored, an i outside the set, a result host outside the allowlist — and that is deliberate: distinct answers would leak facts about other people's jobs. The 502 is checked before streaming starts, so it is an honest error rather than a truncated file; money is not involved — the job is already paid for.