# Files & uploads

Many generations take file inputs — reference images, inpainting masks, poses, depth maps, or audio. You upload a file once, then pass its `file_id` into generation requests.

## Upload flow

Uploads go **directly to storage** with a resumable upload. You request a signed URL, then upload the bytes yourself.

1. **Request an upload URL**  
```bash  
curl -X POST https://api.app.layer.ai/api/v1/workspaces/$WORKSPACE_ID/files/upload-url \
  -H "Authorization: Bearer $LAYER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content_type": "image/png" }'  
# → { "file_id": "…", "upload_url": "https://storage.googleapis.com/…", "content_type": "image/png", "source_type": "asset" }  
```
2. **Start a resumable session** by POSTing to `upload_url` with the `x-goog-resumable: start` header; the response’s `Location` is your session URI.
3. **Upload the bytes** with a `PUT` to the session URI.

Caution

The `upload_url` **expires in 15 minutes** — request it right before uploading.

## Supported types & sizes

| Type    | Content types                     | Max size |
| ------- | --------------------------------- | -------- |
| Image   | image/png, image/jpeg, image/webp | 64 MB    |
| Video   | video/mp4                         | 64 MB    |
| Audio   | audio/wav, audio/mpeg             | 64 MB    |
| Archive | application/zip                   | 100 MB   |

## Using files in a generation

Pass the returned `file_id` into a generation request. Reference images and other guidance go in `guidance_files`; an inpainting mask goes in `mask` (request it with `source_type: "mask"`, and it must be an image):

```jsonc
{
  "model_id": "MODEL_ID",
  "parameters": {
    "prompt": "replace the sky with aurora",
    "guidance_files": [{ "file_id": "FILE_ID" }],
    "mask": { "file_id": "MASK_FILE_ID" }
  }
}
```

Layer resolves each `file_id` to the stored object internally — you don’t pass URLs.

## Downloads

There is **no download endpoint**. Generated outputs are returned as URLs in the run result (see [Async jobs](/docs/async-jobs)); fetch those directly.
