Разместить видео в UFOLOAD можно, ни разу не открыв кабинет. REST API принимает загрузки по HTTPS, сервер может сам скачать файл по ссылке, а тот же аккаунт доступен по WebDAV и FTP для инструментов, которые уже работают с этими протоколами. В этом руководстве разобраны все пять способов с рабочими командами, объяснено, что отвечает сервер, и показано, как дождаться окончания кодирования. Эндпоинты ниже сверены с публичной спецификацией OpenAPI; полный справочник — в документации API.
Создайте API-ключ
Создайте ключ в разделе «Разработчикам» в кабинете. Каждый запрос передаёт его как bearer-токен в заголовке Authorization. Ключ показывается только один раз при создании, поэтому сохраните его в переменной окружения или менеджере секретов и отзовите в кабинете, если он утёк. Тот же ключ служит паролем для WebDAV и FTP, а логином — email вашего аккаунта. Если аккаунта ещё нет, создайте бесплатный; на странице тарифов указаны лимит размера файла и квоты хранилища и трафика для вашего тарифа.
export UFOLOAD_API_KEY="ufo_..."Загрузка через curl
Самый простой способ загрузки — отправить файл как тело запроса и указать его имя в заголовке X-File-Name. Если в имени есть пробелы или символы не из ASCII, передавайте его в percent-кодировке (UTF-8). По умолчанию файл попадает в корневую папку; чтобы выбрать другую, добавьте ?folder_id= или заголовок X-Folder-Id.
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:
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.
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 открытый файловый объект передаётся потоком с диска, поэтому расход памяти не растёт даже для больших видео. Функция ниже загружает файл, а затем ждёт результата.
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, которые передают данные потоком с диска.
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 показывает прогресс.
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-ключ. Оба протокола передают данные потоком с диска и надёжнее всего подходят для очень больших файлов.
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.mp4curl -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-ключ за несколько минут. Лимиты тарифов указаны на странице тарифов.