Uploads
Upload an image, video or audio file as an asset you can pass to a generation job.
POST /v1/generation/uploads
Stores a file as an asset in the current project and returns it. Use the asset’s id (or url) in a job’s inputs, for example as the start_frame of a wan-2.2-i2v clip. Uploads are free.
Scope: generation:write
Body
Send multipart/form-data with a single file part.
The file. The part’s Content-Type decides the asset kind; when it’s missing, the type is guessed from the filename. The filename is kept as the asset’s filename.
The project to upload into, by id or slug. Defaults to your organization’s default project. A multipart body has no project_id field, so the header is the only way to pick a project here.
Accepted types, up to 50 MiB:
| Content type | Asset kind |
|---|---|
image/png | image |
image/jpeg (image/jpg is accepted as an alias) | image |
image/webp | image |
video/mp4 | video |
audio/mpeg (MP3) | audio |
audio/wav | audio |
Images must decode; their width and height are read from the file. Video and audio uploads are stored as-is, with width, height and duration_s left null.
Response
201 Created with {"data": Asset}. See the Asset object for every field. Uploaded assets have source: "upload" and job_id: null.
Errors
| Status | Message | Cause |
|---|---|---|
422 | Unsupported content type '<type>'. | Not one of the types above. details.allowed lists them. |
422 | Empty file. | The part has no bytes. |
422 | File exceeds 50 MiB. | The file is larger than 50 MiB. |
422 | File is not a readable image. | An image type whose bytes don’t decode. |
409 | The project is archived. | |
413 | Request Entity Too Large | The request body is over 51 MiB (the 50 MiB file limit plus room for multipart framing). |
408 | Request took longer than 120 seconds to process | The upload didn’t finish streaming within 120 seconds. Uses the timeout body, not the error envelope. |