Skip to main content

Uploading files via the Layer API

How to upload reference images, masks, and other files via the Layer API before using them in a generation — including the full three-step signed URL flow.

The Layer API does not accept raw image bytes directly in generation requests. Instead, you upload a file first and receive a file_id to reference in your inference or workflow call. This article walks through the complete upload flow.

When you need to upload a file

File uploads are required any time you want to use an image, video, or audio as an input to a generation — for example:

  • Reference images — guide the style or composition of a generation

  • Inpainting masks — define the area to edit in an image

  • Pose or depth maps — control character pose or scene depth

  • Image-to-video — use an existing image as the starting frame

Supported file types and limits

  • Images: image/jpeg, image/png, image/webp — up to 64 MB

  • Video: video/mp4 — up to 64 MB

  • Audio: audio/mpeg, audio/wav — up to 64 MB

The signed upload URL expires 15 minutes after it is issued. Complete the upload within that window.

The upload flow

Uploading a file takes three steps.

Step 1: Request a signed upload URL

Call the POST /v1/workspaces/{workspace_id}/files/upload-url endpoint with the file's MIME type and size in bytes:

Request body:

  • content_type — MIME type of the file (e.g. image/png)

  • file_size_bytes — exact size of the file in bytes

  • file_name — optional file name

Response:

  • file_id — the UUID you'll pass to your generation request

  • upload_url — a signed Google Cloud Storage URL

  • content_type — confirmed MIME type to use during upload

Step 2: Initiate the resumable upload

Send a POST request to the upload_url from Step 1, with the header:

x-goog-resumable: start

The response will contain a Location header with a session URI. Copy that URI — you'll use it in Step 3.

Step 3: Upload the file content

Send a PUT request to the session URI from Step 2 with the raw file bytes as the body and the correct Content-Type header. This supports chunked uploads for large files.

Once the PUT completes successfully, the file is stored and your file_id is ready to use.

Using the file_id in a generation

Pass the file_id as a guidance_files input when calling the inference or workflow endpoint. The specific parameter name varies by model — check the model's detail page via the Get model endpoint for the exact input field names it accepts.

Common errors

  • 400 UPLOAD_FAILED — the file could not be stored. Check that the content_type matches the actual file format and the upload completed before the 15-minute URL expiry.

  • 422 Invalid input — file_size_bytes was not provided or doesn't match the actual file size.

  • 403 Forbidden — your token doesn't have permission to upload to this workspace.

What's next

Did this answer your question?