APIUploadWebDAV

Envio de vídeos via API: curl, Python, Node.js, WebDAV e FTP

Envie e importe vídeos com a REST API da UFOLOAD usando curl, Python e Node.js, aguarde a codificação e use WebDAV ou FTP para arquivos grandes.

Você pode colocar um vídeo na UFOLOAD sem nunca abrir o painel. A REST API aceita envios por HTTPS, o servidor pode baixar um arquivo a partir de um link para você, e a mesma conta é acessível via WebDAV e FTP para ferramentas que já falam esses protocolos. Este guia percorre os cinco caminhos com comandos que funcionam, explica o que o servidor responde e mostra como esperar o fim da codificação. Os endpoints abaixo foram conferidos com a especificação OpenAPI pública; a documentação da API traz a referência completa.

Crie uma chave de API

Crie uma chave na seção Desenvolvedores do painel. Toda requisição a envia como bearer token no cabeçalho Authorization. A chave é exibida uma única vez, ao ser criada, então guarde-a numa variável de ambiente ou num gerenciador de segredos e revogue-a pelo painel se vazar. A mesma chave funciona como senha para WebDAV e FTP, com o e-mail da conta como login. Se você ainda não tem conta, crie uma gratuita; a página de preços lista o limite de tamanho de arquivo e as cotas de armazenamento e tráfego do seu plano.

bash
export UFOLOAD_API_KEY="ufo_..."

Envio com curl

O envio mais simples manda o arquivo como corpo bruto da requisição e coloca o nome no cabeçalho X-File-Name. Envie o nome com percent-encoding (UTF-8) se ele tiver espaços ou caracteres não ASCII. Por padrão o arquivo vai para a pasta raiz; adicione ?folder_id= ou um cabeçalho X-Folder-Id para escolher outra.

Corpo bruto · 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

Um formulário multipart também funciona. O arquivo vai no campo file, e a pasta pode ser informada como campo de formulário folder_id:

Formulário multipart · bash
curl -X POST "https://ufoload.com/api/v1/files" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -F "file=@holiday-2026.mp4"

Um envio bem-sucedido responde 201 com um corpo JSON que contém o objeto do arquivo. Os campos que você vai usar com mais frequência são id, public_id (o código curto que vai nos endereços do player), status, duration_ms e max_quality. O servidor não gasta espaço extra com conteúdo que já tem: se você enviar os mesmos bytes de novo, ele responde 200 com o arquivo existente e "duplicate": true, identificando os arquivos pelo hash SHA-256.

StatusSignificado
201O arquivo foi aceito e entrou na fila de processamento
200O mesmo conteúdo já está na sua biblioteca; duplicate é true
401A chave está ausente ou é inválida
404A pasta de destino não existe
409Armazenamento insuficiente
413O arquivo é maior do que o seu plano permite
429Requisições demais; espere e tente de novo
Dica

Envios grandes não estão sujeitos aos timeouts curtos que valem para chamadas comuns da API. O servidor aceita o corpo enquanto ele continuar chegando, então uma conexão lenta não interrompe um envio de vários gigabytes, embora uma pausa longa demais entre blocos ainda possa ser cortada pelo proxy reverso.

Espere o vídeo ficar pronto

O envio é só a primeira metade. Depois dele, o arquivo entra na fila e é codificado numa escada HLS adaptativa (veja como a escada é montada). O status passa por uploading, queued e processing e termina em ready ou failed; um arquivo com falha traz uma mensagem em error. Consulte o arquivo a cada poucos segundos, nunca num loop apertado: a API tem limite de requisições e responde 429.

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

A resposta tem duas partes: file, com os metadados, e links, com endereços assinados para a playlist master (playback), a capa (poster), o sprite de prévia ao passar o mouse (sprite), cada versão e expires_at. Se você precisa de outra validade, POST /files/{id}/links emite links válidos de 60 segundos a 30 dias, opcionalmente vinculados a um endereço IP ou a um cookie.

Python

Com a biblioteca requests, passar o objeto de arquivo aberto faz o streaming a partir do disco, então o uso de memória fica estável mesmo com vídeos grandes. A função abaixo envia o arquivo e depois espera o resultado.

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

O Node.js 18 e versões mais novas têm fetch embutido, então não é preciso nenhuma dependência. Esta versão lê o arquivo para a memória, o que serve para clipes e vídeos curtos; para arquivos de vários gigabytes, prefira curl, WebDAV ou FTP, que fazem streaming a partir do disco.

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)

Importação por URL

Se o vídeo já está online num link direto, deixe o servidor baixá-lo em vez de trazê-lo para a sua máquina e enviá-lo de novo. A chamada retorna 202 na hora, com uma tarefa de importação; o servidor baixa o arquivo e depois o coloca na fila de codificação. Links para redes internas, loopback e faixas de endereços de serviço são recusados, você pode ter até dez importações ativas, e GET /files/import mostra o progresso.

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 e FTP

Para transferências em massa e para ferramentas que não conseguem chamar uma API, a mesma biblioteca está disponível via WebDAV e FTP. O login é o e-mail da sua conta e a senha é uma chave de API. Os dois fazem streaming a partir do disco e são a opção mais robusta para arquivos muito grandes.

WebDAV sobre HTTPS, porta 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 com TLS explícito, porta 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/

Use as variantes criptografadas sempre que o seu cliente suportar, já que a chave de API é a senha. Qualquer cliente que fale WebDAV ou FTPS, de gerenciadores de arquivos a ferramentas de sincronização, pode usar os mesmos dados. Os arquivos copiados dessa forma aparecem na sua biblioteca e são codificados como qualquer outro envio.

Qual caminho escolher

CaminhoIdeal paraAtenção a
Envio pela APIAplicações e backends que enviam em nome dos usuáriosUso de memória se o cliente ler o arquivo inteiro antes
Importação por URLArquivos que já têm um link direto públicoApenas links http(s) diretos; limite de dez importações ativas
WebDAVArquivos grandes, montar a biblioteca como unidade de discoUse o seu e-mail e a chave de API como credenciais
FTP / FTPSFerramentas e scripts existentes, transferência em massaUse a opção de TLS explícito

Use o vídeo

Quando o status for ready, o endereço do player é https://iframe.andromedans.live/e/ seguido de public_id, que é exatamente o que você coloca num iframe (o id longo também funciona e é redirecionado para o endereço curto); o guia de incorporação mostra a marcação e a alternativa com hls.js. Você pode restringir onde o vídeo toca com regras de domínio e país e, quando há anúncios disponíveis, ativá-los para ganhar com as visualizações. Mantenha a chave fora do código do navegador, troque-a quando alguém sair da sua equipe e lembre que a API está disponível em todos os planos, então você pode começar a construir hoje.

Experimente com uma conta gratuita

Envie um vídeo e receba um player HLS e uma chave de API em minutos. Os limites dos planos estão na página de preços.