# Media Hosting Upload an audio file once, get a stable file id, and re-resolve it to a short-lived signed playback URL — the audio backend for annotation and evaluation tools. Media hosting is a durable, transcription-decoupled storage layer. You upload a file once, receive a stable `file_id`, and can resolve that id to a fresh short-lived signed URL whenever you need to stream the audio back — for example to play a clip in a browser while a reviewer reads its transcript. The audio never expires from your control, but each playback URL is short-lived and self-authenticating. > **💡 Tip** > > Building an annotation or evaluation UI (like [eval.lesan.ai](https://eval.lesan.ai))? This is the endpoint you want. Store the `file_id` next to your transcript/annotation records; call `GET /v1/media/{file_id}` to get a fresh URL each time you render the player. No need to keep the audio bytes or manage GCS yourself. ## How it differs from transcription uploads A normal transcription job stores its audio only for as long as the job lives. A media asset is a first-class, standalone record: it is keyed on your **account** (so it survives API-key rotation), it is never garbage-collected with a job, and you can re-resolve it to a playback URL without ever running ASR on it. | | `GET /v1/transcriptions/{id}/audio` | `GET /v1/media/{file_id}` | | ----------- | ----------------------------------- | --------------------------------------- | | Tied to | A transcription job | Nothing — standalone asset | | Lifetime | The job | Durable until you delete it | | Primary use | Fetch the audio of a job you ran | Play back any uploaded file, ASR or not | | Ownership | Job owner | Account (survives key rotation) | ## The two-step model Every integration is the same two moves: **upload once** to get a `file_id`, then **resolve on demand** to get a playback URL. - **1. Upload** — either proxy the bytes through the API (`POST /v1/uploads`) or upload straight to storage with a presigned PUT (`GET /v1/uploads/signed-url` then `POST /v1/uploads/{file_id}/finalize`). Both return a `file_id` and register a durable media asset. - **2. Resolve** — call `GET /v1/media/{file_id}` to get a signed URL, valid for one hour by default (tune with `expires_in`, up to 7 days). Signed URLs support HTTP Range requests, so browser `