Skip to main content
Use this flow before sending reference images, reference videos, or first/end-frame images to generation:
  1. Call POST /files for each file to receive an upload grant and file_id.
  2. Send the file bytes to upload_url with every returned upload_fields entry as multipart form data.
  3. After the upload succeeds, pass file_id in referenceImageKeys, referenceVideoKeys, firstFrameKey, or endFrameKey.
Receiving a file_id does not mean the file has been uploaded. Complete step 2 before submitting generation. Use file_id directly; you do not need to construct a storage path or download URL. upload_fields.key is also accepted.
POST /files creates a signed upload grant. Send JSON with the MIME type, file size in bytes, and filename. This endpoint does not receive the file bytes.
All three fields are required. size must be a positive integer. filename must contain 1–255 characters after trimming and no control characters. Send a MIME type without parameters, such as image/jpeg. Unknown fields are rejected. The HTTP 200 response contains file_id, upload_url, upload_fields, and expires_at. Upload with a multipart POST, not PUT. Include every returned form field unchanged and append the file field last. Do not send your API key to the upload URL.
Node.js
The signed grant expires after six hours. Image uploads are limited to 10 MiB; other uploads to 100 MiB. The storage service rejects uploads exceeding the signed limit. Model-specific restrictions can be stricter; see Video models. Wait for a successful upload before submitting generation. Use the returned file_id or upload_fields.key; both refer to the same uploaded object and are scoped to your workspace. Video references go in referenceVideoKeys. Reference audio is not currently accepted by the generation request schema. Uploaded inputs are temporary. Submit promptly, and keep your originals in your own storage. An expired grant requires a new grant and upload. An accepted job retains its own copy of reference inputs.