A documentação também existe em formato para IAs e LLMs. Cole o link de contexto na sua IA, ou copie o prompt pronto e peça a integração.
__BASE__/llms.txtDocumentação da API de vídeo
A API é assíncrona: você envia o pedido, recebe um id e consulta pelo id até o vídeo ficar pronto. Aceita as proporções 16:9 (horizontal), 9:16 (vertical), 1:1, 4:3, 3:4 e 21:9, com imagens de referência opcionais.
__BASE__JSON (Content-Type: application/json) · UTF-8ISO 8601 · UTC1. Autenticação
A API key da sua conta fica em Minha conta. Todo request (exceto /health e os links /preview e /download) precisa do header:
Authorization: Bearer <API_KEY>
Sem header ou com uma key inválida, o servidor responde 401 {"error":"unauthorized"}.
2. Fluxo de processamento
O tempo de geração depende do modelo. Se o vídeo não chegar em 4 minutos (padrão do servidor), o job passa para failed e o valor é reembolsado.
POST /v1/videos → 202 {"id": "...", "status": "queued"}
│
▼ (consulte a cada ~5 segundos)
GET /v1/videos/{id} → status: queued → generating → done | failed
│
▼
done: use o campo "url" para tocar ou baixar o vídeo (.mp4)
3. Criar vídeo
POST__BASE__/v1/videosCampos do body (JSON)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
prompt | string | Obrigatório | O que o vídeo mostra e como se move. Até 5000 caracteres. |
aspect_ratio | Opcional. "16:9" (padrão, 1280×720), "9:16" (720×1280), "1:1" (960×960), "4:3", "3:4" ou "21:9" (1344×576). | ||
duration_seconds | Opcional. Duração desejada do vídeo: 5, 10, 20, 30, 40, 50 ou 60 segundos. Até 10 s é um clipe único (~1 min); acima disso o vídeo é montado em partes de 10 s (30 s ≈ 3–4 min, 60 s ≈ 7 min). Continue consultando o status a cada 5 s. A resposta devolve requested_seconds (o pedido) e duration_seconds (o real, lido do MP4). | ||
video | Opcional. Vídeo de referência já enviado: {"path": "refs/…/….mp4"}, onde path vem de POST /v1/uploads (reserva um endereço assinado; faça PUT do arquivo nele; MP4, WEBM ou MOV até 50 MB). A IA usa o vídeo como base da cena. Não combine com images. | ||
video_url | Opcional. Alternativa ao video: URL https pública de um MP4/WEBM/MOV (até 50 MB) que o servidor baixa para você. | ||
conversation_id | string | Opcional | Nome de uma conversa da sua key (letras, números, ., _, -, até 64). Pedidos com o mesmo nome rodam na mesma conversa, um após o outro, e o modelo lembra os anteriores: ideal para continuações de história e para manter o mesmo personagem. Sem ele, cada pedido é isolado numa conversa nova (nada de outro pedido entra no contexto). |
images | array | Opcional | Até 3 imagens de referência. Estrutura de cada item abaixo. |
Cada item de images
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
mime_type | string | Obrigatório | image/png, image/jpeg ou image/webp. |
data_base64 | string | Obrigatório | Imagem em base64, sem o prefixo data:...;base64,. Até 8 MB por imagem (antes da codificação). |
filename | string | Opcional | Somente letras, números, ., _ e - (até 80 caracteres). |
Com 1 imagem, ela é usada como primeiro quadro e referência principal. Com várias, todas viram referência de uma única cena contínua; descreva no prompt o papel de cada uma (ex.: "a pessoa da imagem 1 segura o produto da imagem 2").
Com imagem de referência, o vídeo pode manter a proporção da imagem em vez do aspect_ratio. Para garantir o formato, envie a imagem já recortada na mesma proporção do aspect_ratio pedido.
Resposta de sucesso — 202 Accepted
{ "id": "5f3e9c2f-4ac4-455f-ab73-03c07e8f8079", "status": "queued", "balance": 900 }
Erros na criação
| HTTP | error | Motivo |
|---|---|---|
400 | prompt must be a non-empty string (max 5000 chars) | Prompt ausente, vazio ou longo demais. |
400 | aspect_ratio must be one of: 16:9, 9:16, 1:1, 4:3, 3:4, 21:9 | Proporção inválida. |
400 | images must contain at most 3 items | Mais de 3 imagens. |
400 | images[0].mime_type must be one of ... | Formato de imagem não suportado. |
400 | images[0].data_base64 must be a base64 string | Base64 inválido ou ainda com o prefixo data:. |
400 | images[0] is larger than 8MB | Imagem acima de 8 MB. |
400 | invalid JSON | O body não é um JSON válido. |
401 | unauthorized | Key ausente, errada ou bloqueada. |
402 | insufficient balance | Saldo menor que o preço de 1 vídeo. A resposta traz balance e price_per_video. Nada é cobrado. |
413 | body too large | O request inteiro passou de 40 MB. |
429 | queue is full (max 8 pending jobs per key) | A key já tem o máximo de jobs em queued + generating. |
503 | Serviço de vídeo indisponível no momento. Por favor, aguarde. | O serviço (service: video, image ou chat) está em instabilidade. Nada é cobrado. Tente de novo depois de retry_after segundos; GET /v1/status mostra o estado de cada serviço. |
3b. Criar imagem
POST__BASE__/v1/imagesA API também gera imagens. Mesma key, mesma fila e mesmo fluxo assíncrono dos vídeos; o resultado é um PNG, fica pronto em cerca de 1 minuto e custa price_per_image créditos (padrão 20, bem menos que um vídeo). GET /v1/key mostra price_per_image e remaining_images.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
prompt | string | Obrigatório | O que a imagem mostra: assunto, cenário, estilo, luz, composição. Até 5000 caracteres. |
aspect_ratio | string | Opcional | "16:9" (padrão), "9:16", "1:1", "4:3", "3:4" ou "21:9". |
images | array | Opcional | Até 3 imagens de referência (mesma estrutura de images): a IA edita, varia ou reestiliza a partir delas conforme o prompt. |
duration_seconds, video e video_url não se aplicam a imagens e devolvem 400.
{ "id": "9b1c5e30-2d4f-4a0e-9c1d-3f2e8a7b6c5d", "kind": "image", "status": "queued", "balance": 980 }
Acompanhe em __BASE__/v1/images/{id} (ou em /v1/videos/{id}: o id é o mesmo). A resposta tem o formato de 4. Ver o resultado, com "kind": "image", "media_type": "image", duration_seconds nulo e url/download_url em /v1/images/{id}/preview e /download. GET /v1/images lista só as imagens; GET /v1/videos?kind=all lista vídeos e imagens juntos. Sem saldo: 402 com price_per_image.
curl -X POST "__BASE__/v1/images" -H "Authorization: Bearer $VIDEOAPI_KEY" -H "Content-Type: application/json" \
-d '{"prompt":"pôster minimalista de um farol numa tempestade","aspect_ratio":"9:16"}'
curl "__BASE__/v1/images/<id>" -H "Authorization: Bearer $VIDEOAPI_KEY"
4. Ver o resultado
GET__BASE__/v1/videos/{id}Resposta — 200 OK
{
"id": "5f3e9c2f-4ac4-455f-ab73-03c07e8f8079",
"kind": "video",
"status": "done",
"prompt": "a dog running on the beach",
"aspect_ratio": "9:16",
"requested_seconds": 10,
"duration_seconds": 8,
"url": "__BASE__/v1/videos/5f3e9c2f-4ac4-455f-ab73-03c07e8f8079/preview",
"source": "local",
"download_url": "__BASE__/v1/videos/5f3e9c2f-4ac4-455f-ab73-03c07e8f8079/download",
"preview_url": "__BASE__/v1/videos/5f3e9c2f-4ac4-455f-ab73-03c07e8f8079/preview",
"media_type": "video",
"expires_at": "2026-10-21T14:54:12.301Z",
"error": null,
"created_at": "2026-10-20T14:52:54.877Z",
"finished_at": "2026-10-20T14:54:12.301Z"
}
Campos da resposta
| Campo | Descrição |
|---|---|
id | Identificador do job. Só a key que criou o job consegue vê-lo; id inexistente ou de outra key → 404 {"error":"not found"}. |
kind | video ou image (pedidos de POST /v1/images). media_type repete o valor quando o job conclui. |
status | queued (na fila), generating (gerando), done (pronto), failed (falhou). |
prompt, aspect_ratio | O que foi enviado. |
duration_seconds | Duração total do vídeo, em segundos inteiros, lida do arquivo MP4 quando o job conclui. null enquanto não terminou ou quando só há link externo. |
url | Link do .mp4. Só existe com status = done; senão é null. |
source | cdn = link original do provedor. local = cópia guardada por este servidor; aí url aponta para /v1/videos/{id}/preview. |
download_url, preview_url | Download (anexo) e visualização (inline, aceita Range para avançar). Com source = cdn, os dois são iguais a url. Esses links não pedem API key. |
media_type | video quando concluído. |
expires_at | Quando o link expira (ISO 8601). Cópias locais: 24 h após terminar. CDN: lido do próprio link quando disponível, senão null. |
error | Motivo da falha quando status = failed; senão null. |
created_at, finished_at | Criação e término (finished_at é null enquanto roda). |
Motivos comuns de failed
| error | Significado | O que fazer |
|---|---|---|
Timed out after 240s waiting for the video ... | O vídeo não chegou no prazo. Pode vir junto a explicação do modelo. | Envie de novo; tente reescrever o prompt. |
the model produced an image instead of a video | O modelo gerou uma imagem parada em vez de vídeo. | Envie de novo descrevendo melhor a ação e o movimento de câmera. |
Could not download the generated video: ... | O vídeo foi gerado, mas o servidor não conseguiu buscá-lo. | Envie de novo. |
server restarted | O servidor reiniciou com o job em andamento. | Envie de novo. |
Erros de conexão com o provedor também aparecem em error. Em todos os casos de failed o valor volta 100% para o saldo.
5. Exemplos completos
# Criar vídeo curl -X POST "__BASE__/v1/videos" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt":"a dog running on the beach","aspect_ratio":"9:16"}' # Ver resultado curl "__BASE__/v1/videos/<id>" \ -H "Authorization: Bearer $API_KEY"
// Node.js 18+ (ES module) ou navegador import fs from 'node:fs'; const BASE = '__BASE__'; const headers = { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }; // Imagem de referência (opcional): lida do disco e codificada em base64 const image = { mime_type: 'image/png', data_base64: fs.readFileSync('input.png').toString('base64'), filename: 'input.png', }; const { id } = await (await fetch(`${BASE}/v1/videos`, { method: 'POST', headers, body: JSON.stringify({ prompt: 'make the picture come alive', aspect_ratio: '16:9', images: [image] }), })).json(); let job; do { await new Promise(r => setTimeout(r, 5000)); job = await (await fetch(`${BASE}/v1/videos/${id}`, { headers })).json(); } while (job.status === 'queued' || job.status === 'generating'); if (job.status === 'done') console.log('Vídeo:', job.url); else console.error('Erro:', job.error);
import base64, time, requests
BASE = "__BASE__"
H = {"Authorization": f"Bearer {API_KEY}"}
with open("input.png", "rb") as f:
image = {"mime_type": "image/png", "data_base64": base64.b64encode(f.read()).decode()}
r = requests.post(f"{BASE}/v1/videos", headers=H, json={
"prompt": "make the picture come alive",
"aspect_ratio": "9:16",
"images": [image], # remova esta linha se não tiver imagem
})
job_id = r.json()["id"]
while True:
time.sleep(5)
job = requests.get(f"{BASE}/v1/videos/{job_id}", headers=H).json()
if job["status"] in ("done", "failed"):
break
print(job["url"] if job["status"] == "done" else job["error"])
5b. MCP: use a VIDEOAPI de dentro do seu agente
A API também fala Model Context Protocol (transporte Streamable HTTP) em __BASE__/mcp. Autentique com a sua API key no header Authorization: Bearer <API_KEY> ou, para clientes que não enviam headers, na própria URL: __BASE__/mcp/<API_KEY> (trate essa URL como segredo).
Ferramentas expostas: create_video, create_image, wait_for_video, get_video, list_videos e get_balance. Em Minha conta → MCP há o passo a passo para Claude, Claude Code, ChatGPT, Cursor, Codex, VS Code, Gemini e Hermes.
claude mcp add --transport http videoapi __BASE__/mcp --header "Authorization: Bearer $VIDEOAPI_KEY"
6. Notas de operação
- Links expiram: veja
expires_at. A cópia local fica 24 h; depois disso/previewe/downloadrespondem410 {"error":"video expired"}e o link não é reemitido. Guarde o.mp4no seu armazenamento antes. - Link direto para .mp4: pode ir direto em
<video src="...">ou ser baixado. - Polling: a cada 5 segundos é o ideal; não precisa ser mais rápido.
- Fila: os jobs são processados em ordem de chegada. Cada key pode ter até 8 jobs aguardando (padrão do servidor) (
queued+generating); acima disso a criação responde 429. - Privacidade: as imagens de referência ficam só em memória e são descartadas quando o job termina.
- Sem webhook: o resultado é obtido por polling em
GET /v1/videos/{id}, sem precisar abrir uma porta pública para callbacks. - CORS: os endpoints
/v1aceitam chamadas de qualquer origem, então dá para usar direto do navegador.
7. Saúde do servidor
Verificação rápida de que a API está no ar (não pede API key):
GET__BASE__/health{"ok": true}
8. Saldo e histórico
Endpoints só de leitura, sempre limitados à key enviada no header. São os mesmos dados da página Minha conta.
Saldo rápido
GET__BASE__/v1/balance{ "balance": 900, "tier": 1, "tier_name": "Padrão", "plan_type": "prepaid" }
Informações da key e totais
GET__BASE__/v1/key{
"api_key_masked": "sk-7047…b0ed70",
"status": "active",
"tier": 1,
"tier_name": "Padrão",
"plan_type": "prepaid",
"balance": 900,
"price_per_video": 100,
"remaining_videos": 9,
"expires_at": null,
"created_at": "2026-10-01T09:00:00.000Z",
"last_used_at": "2026-10-15T20:39:12.000Z",
"totals": {
"deposited": 1000, "spent": 100, "holding": 0, "refunded": 100,
"jobs": 3, "done": 1, "failed": 1, "pending": 1
}
}
deposited, spent, holding (reservado por jobs em andamento) e refunded estão em créditos; jobs, done, failed e pending são contagens.
Jobs da key
GET__BASE__/v1/videos?status=done&limit=100status (opcional): done, failed, queued, generating ou pending (= queued + generating). limit: 1–500, padrão 100. Mais recentes primeiro; cada item tem a estrutura da seção 4 mais cost e refunded.
{ "data": [ { "id": "5f3e9c2f-…", "status": "done", "cost": 100, "refunded": false, "url": "…", … } ] }