Skip to main content

Files you get back

Capabilities that make a file (audio.speech, image.generate, video.generate) return it as a link on this API’s own host, with an id and an expiry:
  • The link works without an API key, for anyone who has it, until expiresAt (7 days after the call). Download the file if you need it for longer.
  • GET /v1/files/{id} returns a fresh link. DELETE /v1/files/{id} removes the file at once.
  • A link can be downloaded about 20 times. After that it answers 429; get the file once and serve it from your own storage if many people will fetch it.
  • If the file cannot be stored, the call fails with 502 upstream_unavailable and you are not charged. Retry it.

Upload a file

Send the file as the request body, with its media type in Content-Type and its kind in the query:
  • Uploading is free. You need a credit balance above zero.
  • An upload is kept for 7 days. You can hold up to 1 GB of uploads at a time; over that the upload is refused with 402 spend_cap_reached until you delete files or they expire.
  • The media type must match the file’s own bytes, or the upload is refused with 400.

Upload directly (required above 90 MB)

The request-body endpoint above accepts at most 90 MB. The per-kind limits in the table still apply. Larger files go directly to storage, without passing through the API. The SDK chooses the flow for you (a browser File is also a Blob):
For HTTP clients:
  1. POST /v1/files/uploads with API authorization, Content-Type: application/json, and { "kind": "video", "contentType": "video/mp4", "sizeBytes": 120000000 }. It returns 201 with { "fileId": "file_...", "uploadUrl": "...", "headers": { ... }, "expiresAt": "..." }. Size, type, credit and available storage are checked before the link is issued; pending uploads count toward storage quota, and a failed or deleted direct upload keeps counting for one hour after it was started.
  2. Send one PUT to uploadUrl with the file as the body and all returned headers. Do not send your API key to this URL. The link expires in 15 minutes and accepts exactly the declared size and type. It only creates the object once, so repeating a successful PUT is refused. In browsers, omit the returned content-length header: fetch sets it from the Blob automatically. Browser uploads require the bucket owner to allow the app’s origin.
  3. POST /v1/files/{fileId}/finish with API authorization. It returns the usual file facts after checking the stored size and file contents. Until then the file cannot be used. If the bytes are not there yet, or storage does not answer, the upload stays pending and you can call finish again. A failed check deletes the object and returns an error explaining how to start again.
Treat the upload URL as a temporary secret. Keep it out of logs. If a PUT fails or the link expires, start a new upload. Unfinished uploads are eligible for the hourly pending-file sweep after one hour. Retention deletion must be enabled for the sweep to remove bytes.

Upload a large object in parts

For an object larger than one storage.object.put takes (25 MB), or of a type the list above does not accept, use a multipart upload to your own bucket. Each chunk is uploaded as a part file: raw bytes, sent as application/octet-stream with kind=part.
  • A part file can only be passed to storage.upload.part.put. It has no link, cannot be downloaded, and every other capability refuses it with 400 invalid_request.
  • One part is at most 8 MiB. The parts of one upload may total 1 GiB. Part files count toward your 1 GB of uploads until they are deleted.
  • Part files are deleted when the upload completes or is aborted, and after 7 days otherwise. An upload near 1 GB does not fit in your 1 GB of uploads all at once: delete each part file (DELETE /v1/files/{id}) once its storage.upload.part.put has succeeded.
  • The finished object is assembled in your bucket exactly as you sent it. Its content is not checked.
  • Without kind=part, an application/octet-stream upload is refused as before.

Use an uploaded file

Pass the fileId where a capability accepts one, in place of a public link:
Send exactly one of them. The audio capabilities take audio files; the document capabilities take document and image files (a scan or a photo of a page). A fileId returned by a capability (a generated audio file, say) can be passed on the same way.

Errors

See errors for the full list.