> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blon.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# File uploads

> Give a job an image, video or audio file.

A media input takes one of two values:

| Value | Use it for |
| - | - |
| `{ "url": "https://…" }` | A file already on a public URL. Blon imports it before estimating the job. |
| `{ "asset_id": "…" }` | A file already in Blon: an upload, or an artifact of an earlier job. |

## Import from a URL

Put the URL in the input. Blon fetches it (within 60 seconds) when you submit or estimate. If the file cannot be fetched, is over the size limit, or cannot be read, the request fails with `422 input_media_unreadable`.

```json theme={null}
{
  "model": "seedance-2.0",
  "input": {
    "prompt": "Slow push-in",
    "firstFrame": { "url": "https://example.com/frame.png" }
  }
}
```

## Upload a local file

Uploading takes three requests. Your Blon key is only sent to Blon, never to the upload URL.

**1. Declare the file**

```bash theme={null}
curl https://api.blon.ai/v1/uploads \
  -H "Authorization: Bearer $BLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content_type":"image/png","size_bytes":1482113,"file_name":"frame.png"}'
```

The `201` response holds `upload_url`, `upload_headers`, a `ticket` and its `expires_at` (10 minutes).

**2. Upload the bytes**

`PUT` the file to `upload_url` with the headers from `upload_headers`. Do not add an `Authorization` header.

```bash theme={null}
curl -X PUT "$UPLOAD_URL" -H "content-type: image/png" --data-binary @frame.png
```

**3. Complete the upload**

```bash theme={null}
curl https://api.blon.ai/v1/uploads/complete \
  -H "Authorization: Bearer $BLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ticket":"…"}'
```

The response holds the `asset_id`, `content_type`, `size_bytes`, `media` (`duration_seconds`, `width`, `height`) and `expires_at`. Completing the same ticket twice returns the same asset.

Then use it in a job: `"firstFrame": { "asset_id": "…" }`.

## Limits

| | Limit |
| - | - |
| Images | 20,000,000 bytes |
| Video, audio and other files | 52,428,800 bytes |
| `file_name` | 200 characters |

| Error | When |
| - | - |
| `413 payload_too_large` | The declared `size_bytes` is over the limit |
| `415 unsupported_media_type` | The `content_type` is not accepted |
| `401 unauthorized` | The ticket is invalid or expired |
| `422 input_media_unreadable` | The file was not uploaded, does not match the ticket, or cannot be read |

## Retention

Files uploaded or imported through the API, and the artifacts the API creates, expire after 7 days (`expires_at`). A file someone adds to the asset library in Blon is kept.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.