APIUploadWebDAV

Загрузка видео через API: curl, Python, Node.js, WebDAV и FTP

Загрузка и импорт видео через REST API UFOLOAD на curl, Python и Node.js, ожидание окончания кодирования, а также WebDAV и FTP для больших файлов.

Разместить видео в UFOLOAD можно, ни разу не открыв кабинет. REST API принимает загрузки по HTTPS, сервер может сам скачать файл по ссылке, а тот же аккаунт доступен по WebDAV и FTP для инструментов, которые уже работают с этими протоколами. В этом руководстве разобраны все пять способов с рабочими командами, объяснено, что отвечает сервер, и показано, как дождаться окончания кодирования. Эндпоинты ниже сверены с публичной спецификацией OpenAPI; полный справочник — в документации API.

Создайте API-ключ

Создайте ключ в разделе «Разработчикам» в кабинете. Каждый запрос передаёт его как bearer-токен в заголовке Authorization. Ключ показывается только один раз при создании, поэтому сохраните его в переменной окружения или менеджере секретов и отзовите в кабинете, если он утёк. Тот же ключ служит паролем для WebDAV и FTP, а логином — email вашего аккаунта. Если аккаунта ещё нет, создайте бесплатный; на странице тарифов указаны лимит размера файла и квоты хранилища и трафика для вашего тарифа.

bash
export UFOLOAD_API_KEY="ufo_..."

Загрузка через curl

Самый простой способ загрузки — отправить файл как тело запроса и указать его имя в заголовке X-File-Name. Если в имени есть пробелы или символы не из ASCII, передавайте его в percent-кодировке (UTF-8). По умолчанию файл попадает в корневую папку; чтобы выбрать другую, добавьте ?folder_id= или заголовок X-Folder-Id.

Файл в теле запроса · bash
curl -X POST "https://ufoload.com/api/v1/files?folder_id=root" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -H "X-File-Name: holiday-2026.mp4" \
  -H "Content-Type: video/mp4" \
  --data-binary @holiday-2026.mp4

Подойдёт и multipart-форма. Файл передаётся в поле file, а папку можно указать в поле формы folder_id:

Multipart-форма · bash
curl -X POST "https://ufoload.com/api/v1/files" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -F "file=@holiday-2026.mp4"

При успешной загрузке сервер отвечает 201 с JSON, в котором лежит объект файла. Чаще всего вам понадобятся поля id, public_id (короткий код для адресов плеера), status, duration_ms и max_quality. Сервер не тратит лишнее место на уже имеющийся контент: если загрузить те же байты повторно, он ответит 200 с существующим файлом и "duplicate": true — файлы сопоставляются по хешу SHA-256.

СтатусЗначение
201Файл принят и поставлен в очередь на обработку
200Такой же контент уже есть в вашей библиотеке; duplicate равно true
401Ключ отсутствует или недействителен
404Папка назначения не существует
409Недостаточно места в хранилище
413Файл больше, чем позволяет ваш тариф
429Слишком много запросов; подождите и повторите
Совет

На большие загрузки не распространяются короткие таймауты, действующие для обычных вызовов API. Сервер принимает тело запроса, пока оно продолжает поступать, поэтому медленное соединение не прервёт загрузку на несколько гигабайт, хотя слишком долгую паузу между блоками всё же может оборвать обратный прокси.

Дождитесь готовности видео

Загрузка — только первая половина дела. После неё файл ставится в очередь и кодируется в адаптивную HLS-лестницу (см. как строится лестница). Его status проходит через uploading, queued и processing и завершается значением ready или failed; у неудавшегося файла есть сообщение error. Опрашивайте файл раз в несколько секунд и никогда не делайте это в плотном цикле: у API есть ограничение частоты запросов, и он ответит 429.

bash
curl "https://ufoload.com/api/v1/files/FILE_ID" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY"

Ответ состоит из двух частей: file с метаданными и links с подписанными адресами мастер-плейлиста (playback), обложки (poster), спрайта превью при наведении (sprite), каждой версии и expires_at. Если нужен другой срок действия, POST /files/{id}/links выдаёт ссылки, действующие от 60 секунд до 30 дней, с необязательной привязкой к IP-адресу или cookie.

Python

С библиотекой requests открытый файловый объект передаётся потоком с диска, поэтому расход памяти не растёт даже для больших видео. Функция ниже загружает файл, а затем ждёт результата.

python
import os
import time
import urllib.parse

import requests

BASE = "https://ufoload.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['UFOLOAD_API_KEY']}"}


def upload(path, folder_id="root"):
    name = urllib.parse.quote(os.path.basename(path))
    with open(path, "rb") as f:
        r = requests.post(
            f"{BASE}/files",
            params={"folder_id": folder_id},
            data=f,
            headers={**HEADERS, "X-File-Name": name, "Content-Type": "application/octet-stream"},
        )
    r.raise_for_status()
    return r.json()["file"]


def wait_ready(file_id, timeout=3600):
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.get(f"{BASE}/files/{file_id}", headers=HEADERS)
        r.raise_for_status()
        data = r.json()
        status = data["file"]["status"]
        if status == "ready":
            return data
        if status == "failed":
            raise RuntimeError(data["file"].get("error") or "encoding failed")
        time.sleep(5)
    raise TimeoutError("video is still processing")


file = upload("holiday-2026.mp4")
data = wait_ready(file["id"])
print("embed:", f"https://iframe.andromedans.live/e/{file['public_id']}")
print("playlist:", data["links"]["playback"])

Node.js

В Node.js 18 и новее fetch встроен, так что зависимости не нужны. Эта версия читает файл в память, что нормально для клипов и коротких видео; для файлов на несколько гигабайт лучше подходят curl, WebDAV или FTP, которые передают данные потоком с диска.

js
import { readFile } from 'node:fs/promises'
import { basename } from 'node:path'
import { setTimeout as sleep } from 'node:timers/promises'

const BASE = 'https://ufoload.com/api/v1'
const headers = { Authorization: `Bearer ${process.env.UFOLOAD_API_KEY}` }

async function upload(path) {
  const res = await fetch(`${BASE}/files?folder_id=root`, {
    method: 'POST',
    headers: { ...headers, 'X-File-Name': encodeURIComponent(basename(path)), 'Content-Type': 'application/octet-stream' },
    body: await readFile(path),
  })
  if (!res.ok) throw new Error(`upload failed: ${res.status}`)
  return (await res.json()).file
}

async function waitReady(id) {
  for (;;) {
    const res = await fetch(`${BASE}/files/${id}`, { headers })
    if (!res.ok) throw new Error(`status check failed: ${res.status}`)
    const data = await res.json()
    if (data.file.status === 'ready') return data
    if (data.file.status === 'failed') throw new Error(data.file.error || 'encoding failed')
    await sleep(5000)
  }
}

const file = await upload('holiday-2026.mp4')
const data = await waitReady(file.id)
console.log('embed:', `https://iframe.andromedans.live/e/${file.public_id}`)
console.log('playlist:', data.links.playback)

Импорт по ссылке

Если видео уже доступно онлайн по прямой ссылке, пусть сервер скачает его сам, а не вы будете скачивать его к себе и загружать заново. Вызов сразу возвращает 202 с задачей импорта; сервер скачивает файл и ставит его в очередь на кодирование. Ссылки на внутренние сети, loopback и служебные диапазоны адресов отклоняются, одновременно может быть до десяти активных импортов, а GET /files/import показывает прогресс.

bash
curl -X POST "https://ufoload.com/api/v1/files/import" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/video.mp4", "name": "video.mp4"}'

WebDAV и FTP

Для массовой передачи и для инструментов, которые не умеют вызывать API, та же библиотека доступна по WebDAV и FTP. Логин — email вашего аккаунта, пароль — API-ключ. Оба протокола передают данные потоком с диска и надёжнее всего подходят для очень больших файлов.

WebDAV по HTTPS, порт 443 · bash
curl -u "you@example.com:$UFOLOAD_API_KEY" https://ufoload.com/dav/
curl -u "you@example.com:$UFOLOAD_API_KEY" -T holiday-2026.mp4 https://ufoload.com/dav/holiday-2026.mp4
FTP с явным TLS, порт 21 · bash
curl -u "you@example.com:$UFOLOAD_API_KEY" ftp://ftp.ufoload.com/
curl -u "you@example.com:$UFOLOAD_API_KEY" --ftp-ssl -T holiday-2026.mp4 ftp://ftp.ufoload.com/

Используйте шифрованные варианты везде, где их поддерживает клиент, ведь паролем служит API-ключ. Те же данные подходят для любого клиента с поддержкой WebDAV или FTPS, от файловых менеджеров до программ синхронизации. Файлы, скопированные таким способом, появляются в вашей библиотеке и кодируются так же, как любая другая загрузка.

Какой способ выбрать

СпособЛучше всего подходит дляНа что обратить внимание
Загрузка через APIПриложений и бэкендов, которые загружают файлы от имени пользователейРасход памяти, если клиент сначала читает весь файл
Импорт по ссылкеФайлов, у которых уже есть публичная прямая ссылкаТолько прямые ссылки http(s); не больше десяти активных импортов
WebDAVБольших файлов, подключения библиотеки как дискаВ качестве учётных данных используйте email и API-ключ
FTP / FTPSСуществующих инструментов и скриптов, массовой передачиИспользуйте вариант с явным TLS

Использование видео

Когда статус станет ready, адрес плеера — это https://iframe.andromedans.live/e/ и следом public_id; именно его вы вставляете в iframe (длинный id тоже работает и перенаправляет на короткий адрес). Руководство по встраиванию показывает вёрстку и альтернативу на hls.js. Ограничить, где воспроизводится видео, можно правилами по доменам и странам, а когда реклама доступна, включите её, чтобы зарабатывать на просмотрах. Не допускайте попадания ключа в код браузера, меняйте его, когда люди уходят из команды, и помните, что API доступен на любом тарифе, так что начать можно уже сегодня.

Попробуйте с бесплатным аккаунтом

Загрузите видео и получите HLS-плеер и API-ключ за несколько минут. Лимиты тарифов указаны на странице тарифов.