Skip to main content

The problem

Most AI endpoints take your media as a URL (image_url, video_url, audio_url, reference_images, …). That’s easy when your file already lives on the public internet — but if it’s a local file, or something you generated on the fly, you have nowhere to point those endpoints to. The Upload Files API solves this: you upload the file once and get back a readable URL (asset_url) that you can drop into any endpoint that accepts a URL — images, video or audio alike.
asset_url is a plain, publicly-fetchable URL. Anywhere an endpoint asks for an image_url / video_url / audio_url (or a reference image), pass the asset_url of your upload.

How it works

1

Request an upload URL

Call POST /v1/ai/uploads/request-url with the content_type of each file. You get back, per file, a short-lived upload_url (to send the bytes to) and a readable asset_url (to use later).
2

Upload the bytes

PUT the raw file bytes to upload_url, including the returned headers. The upload happens directly against storage — the upload_url is short-lived (see expires_in).
3

Use the asset_url

Pass the asset_url as the input URL of any AI endpoint that accepts one. Re-fetch it any time from GET /v1/ai/uploads.

Supported file types

Pass one of these as content_type: Maximum size: 1 GiB per file.

1. Request an upload URL

You can request up to 14 files in a single call (files array).
string
Identifier of the uploaded file (upl_…).
string
Pre-signed URL to PUT the raw file bytes to. Short-lived — see expires_in.
object
Headers you must include in the PUT request (they are part of the URL signature).
integer
Seconds until upload_url expires (do the PUT right after requesting it).
string
Readable URL of the uploaded file. Valid once the PUT completes. Use it as the input URL in any endpoint that accepts one. Expires in ~24h — don’t persist it.
integer
Seconds until asset_url expires (counted from this response).

2. Upload the bytes

PUT the file to the upload_url, echoing the headers from step 1. Do not send your API key here — the request goes straight to storage and is authorized by the signed URL.
The Content-Type you send here must match the content_type you requested in step 1, and the x-goog-content-length-range header is required — both are covered by the URL signature.

3. Use the asset_url

Once the upload completes, pass the asset_url wherever an endpoint expects a URL:
The same asset_url works for video and audio inputs on endpoints that accept them (video_url, audio_url, …).

List your uploads

Lost the response from step 1, or your asset_url expired? List your files — each item comes with a freshly-signed asset_url:

Expiration

Two independent clocks:
  • asset_url_expires_in — how long the URL itself stays valid (~1 day). An expired URL returns 403 — just call GET /v1/ai/uploads again to get a fresh one (a new URL is signed on every listing). Don’t persist the asset_url.
  • ttl_seconds — how long until the file becomes eligible for auto-deletion (~7 days). Deletion is eventual, so a file may linger a little past this — but once it is deleted, its asset_url stops working. Treat uploads as a staging area, not storage.