---
title: Input media
description: Pass images, video and audio to a model by HTTPS URL.
---
Models that take media (an image to edit, a first frame, a clip to restyle, speech to lip-sync) take it as a **public HTTPS URL** in the request body.

| Field | Used by |
|---|---|
| `image_urls` | [Generate an image](/docs/reference/images/generate): reference or edit images, up to 16 |
| `image_url`, `end_image_url` | [Generate a video](/docs/reference/video/generate): first and last frame |
| `video_url` | Video-to-video models: the clip to edit |
| `audio_url` | Lip-sync models: the speech to say |
| `reference_image_urls`, `reference_video_urls`, `reference_audio_urls` | Video models that take references |

Each URL must be downloadable without cookies or custom headers, and must stay valid until the job finishes. A signed URL from your own storage (S3, GCS, R2) works if it lasts longer than the job.

A model that does not take a field rejects it with `400 invalid_request`. The model's row in its list says what it accepts (`capabilities`).

## Direct upload

If the file is not online yet, upload it into Sume storage with your key, in three calls:

1. `POST /v1/assets/upload-url` with `content_type` and `size_bytes` (and optionally `filename`). The `201` returns `data.asset.id` and `data.upload`: a presigned `url`, its `method` (`PUT`), the `headers` to send with it, and `expires_at`.
2. Send the bytes to `data.upload.url` with that method and exactly those headers. Do not send your API key there.
3. `POST /v1/assets/{id}/complete` with the same `size_bytes`. The `200` returns the asset with `status: "ready"` and its `url` on `media.sume.com`.

Pass that `url` as `image_url`, `video_url` or `audio_url` like any other HTTPS URL. Uploading and completing are free. An upload URL that expires before you complete it must be created again.
