Início rápido

Rode sua primeira tarefa FFmpeg no FFHub em 3 minutos.

Este guia te leva pela primeira chamada à API: pegar a chave, enviar uma tarefa de transcodificação e ler o resultado.

1. Pegue uma API Key

Cadastre-se em ffhub.io e crie uma chave em dashboard/api-keys. A chave tem o formato sk_xxxxx — guarde em segredo.

Você ganha créditos grátis ao se cadastrar, então o passo a passo abaixo sai de graça.

Valide sua chave de API com GET /v1/me e o cabeçalho Authorization: Bearer YOUR_API_KEY. Uma chave válida retorna HTTP 200 com os dados da conta; uma chave inválida retorna HTTP 401. Use esse endpoint para verificar a conexão, em vez da consulta de tarefas.

2. Envie uma tarefa

Mande qualquer comando FFmpeg para POST /v1/tasks. As entradas precisam ser URLs públicas — caminhos locais são rejeitados pelo worker.

curl -X POST https://api.ffhub.io/v1/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "command": "ffmpeg -i https://storage.ffhub.io/Sample_Video_File_100MB.mp4 -c:v libx264 -preset fast output.mp4"
  }'
const res = await fetch("https://api.ffhub.io/v1/tasks", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FFHUB_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    command:
      "ffmpeg -i https://storage.ffhub.io/Sample_Video_File_100MB.mp4 -c:v libx264 -preset fast output.mp4",
  }),
});
const { task_id } = await res.json();
import os, requests

res = requests.post(
    "https://api.ffhub.io/v1/tasks",
    headers={"Authorization": f"Bearer {os.environ['FFHUB_API_KEY']}"},
    json={
        "command": "ffmpeg -i https://storage.ffhub.io/Sample_Video_File_100MB.mp4 -c:v libx264 -preset fast output.mp4",
    },
)
task_id = res.json()["task_id"]

A resposta traz um task_id que você usa pra consultar o status:

{
  "task_id": "01abcd…"
}

3. Consulte até concluir

curl https://api.ffhub.io/v1/tasks/TASK_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

Consulte a cada 2–5 segundos enquanto status for pending ou running. Pare quando virar succeeded ou failed. Baixe os arquivos de outputs somente após succeeded; em caso de failed, leia error e informe a falha, sem tentar baixar o resultado. Uma resposta HTTP de sucesso na consulta não significa que o processamento teve sucesso. Abaixo está um trecho de uma resposta bem-sucedida:

{
  "task_id": "01abcd…",
  "status": "succeeded",
  "progress": 100,
  "outputs": [
    {
      "filename": "output.mp4",
      "url": "https://storage.ffhub.io/outputs/01abcd…/output.mp4",
      "size": 10485760
    }
  ]
}

A resposta da consulta também inclui created_at e, após o término da tarefa, finished_at. São timestamps ISO 8601 com fuso horário e podem incluir frações de segundo. Por exemplo, 2026-05-10T12:00:00Z e 2026-05-10T12:00:00.123Z são válidos. Antes do término, finished_at pode estar ausente; não tente interpretar um valor ausente como data de conclusão.

Os arquivos de saída são excluídos 7 dias após a conclusão da tarefa — baixe o que quiser guardar.

Subir arquivos locais

Se sua entrada ainda não é uma URL pública, faz upload antes pra pegar uma. Dois passos:

# 1. Peça uma URL PUT assinada de uso único
SIGNED=$(curl -s -X POST https://api.ffhub.io/v1/uploads/sign \
  -H "Authorization: Bearer $FFHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename":"input.mp4","size":12345678,"content_type":"video/mp4"}')

# 2. PUT o arquivo direto no R2 — seu servidor nunca vê os bytes
curl -fsS -X PUT "$(echo "$SIGNED" | jq -r '.upload_url')" \
  -H "Content-Type: video/mp4" \
  --data-binary "@./input.mp4" || { echo "Falha no upload"; exit 1; }

# O campo .public_url é o que você passa em `-i` no comando da tarefa.

Passo a passo completo em Upload de arquivos.

Próximos passos