---
title: "Download a file from a URL into a media directory."
method: POST
path: "/api/media/download"
tags: ["Media"]
---

# Download a file from a URL into a media directory.

`POST /api/media/download`

## Request

- The document declares no server URL.
- Auth: none declared

Checks the URL and waits for the remote server's response headers, then
answers 202 with the job while the body downloads in the background.
Progress and the outcome arrive as `MediaDownloadProgress` WebSocket events.

## Request body

- MediaDownloadRequest: Request to download a file from a URL into the media library.
  - `filename` string, nullable: File name to save as. When absent, the name comes from the response's `Content-Disposition` header, then from the URL's last path segment. At most 200 bytes.
  - `overwrite` boolean: Replace an existing file of the same name. Without it, an existing file makes the request fail with 409 Conflict.
  - `path` string: Directory to save into, relative to the media root. Empty means the root.
  - `url` string, required: The http or https URL to fetch.

## Response `202`

Download started

- MediaDownloadJob: One URL download into the media library. Carried by `POST /api/media/download`, `GET /api/media/downloads` and the `MediaDownloadProgress` WebSocket event.
  - `bytes` integer, required: Bytes received so far.
  - `directory` string, required: Directory the file is saved into, relative to the media root.
  - `error` string, nullable: Why the download failed, when it did.
  - `filename` string, required: File name the download is saved as.
  - `job_id` string, required: Job identifier, used to cancel the download.
  - `path` string, required: Path of the finished file, relative to the media root.
  - `state` 'downloading' | 'done' | 'failed' | 'cancelled', required: Where a URL download is in its life.
  - `total` integer, nullable: Total size, when the server announced one.
  - `url` string, required: The requested URL without user info, query or fragment, for display.

## Other responses

- `400`: Invalid URL, path or file name
- `403`: The URL leads to an address downloads may not connect to
- `404`: Target directory not found
- `409`: The file exists and overwrite is not set, or another download is writing it
- `413`: The file is larger than the configured limit
- `422`: The request failed validation (URL or file name too long)
- `502`: The remote server failed or answered with an error
- `504`: The remote server did not answer in time

## Changes

- **2026-10-08** `4ab7568b68c9`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/eyevinn/apis/strom-api/changes/api/media/download/post.md)

---

[API](https://skmtc.dev/eyevinn/apis/strom-api.md) - [All operations](https://skmtc.dev/eyevinn/apis/strom-api/llms.txt) - [OpenAPI document](https://skmtc.dev/eyevinn/apis/strom-api/revisions/8cd4dbc44175?raw)
