# VIDEOAPI — guia de integração para IAs e desenvolvedores > API REST assíncrona de geração de vídeo e imagem por IA (texto e referências → MP4; texto → PNG). Servida em https://www.videoapi.com.br (o mesmo servidor desta página). Este arquivo é a referência completa: siga-o à risca ao integrar. ## Conceitos - Fluxo: `POST /v1/videos` cria um pedido e responde `202` com um `id`; depois `GET /v1/videos/{id}` até `status` ser `done` (vídeo pronto) ou `failed` (créditos devolvidos). - Cada vídeo custa `price_per_video` créditos (padrão 100) e cada imagem `price_per_image` (padrão 20), reservados na criação, cobrados só quando conclui; falha = reembolso automático de 100%. - Tempo típico: vídeos de 5–10 s ficam prontos em ~1 minuto; 20 s em ~2,5 min; 30 s em ~3,5 min; 60 s em ~7 min (acima de 10 s o vídeo é montado em partes). Continue consultando a cada 5 s até concluir. - Proporção: `16:9` (1280×720), `9:16` (720×1280), `1:1` (960×960), `4:3`, `3:4`, `21:9` (1344×576). Formato de saída: MP4 (H.264/AAC). ## Autenticação Todo request (exceto `GET /health`, `/preview` e `/download`) leva o header `Authorization: Bearer `. A key tem o formato `sk-…` e fica em "Minha conta" no painel. Guarde-a em variável de ambiente (ex.: `VIDEOAPI_KEY`); nunca a coloque no código nem no front-end. Sem header ou key inválida/bloqueada: `401 {"error":"unauthorized"}`. ## Base URL e formato - Base: `https://www.videoapi.com.br` - Corpo e respostas em JSON (`Content-Type: application/json`), UTF-8. Datas em ISO 8601 (UTC). - Tamanho máximo do corpo: 4,5 MB na hospedagem atual (imagens grandes dão 413). ## POST /v1/videos — criar vídeo Body: ```json { "prompt": "um farol numa tempestade, câmera lenta", "aspect_ratio": "16:9", "duration_seconds": 10, "images": [{ "mime_type": "image/png", "data_base64": "", "filename": "ref-1.png" }] } ``` - `prompt` (obrigatório): string não vazia, até 5000 caracteres. Descreva cena, estilo, movimento de câmera. - `aspect_ratio` (opcional): `"16:9"` (padrão), `"9:16"`, `"1:1"`, `"4:3"`, `"3:4"` ou `"21:9"`. - `duration_seconds` (opcional): `5`, `10`, `20`, `30`, `40`, `50` ou `60`. Omitido = o modelo decide (~8–10 s). - `video` (opcional): vídeo de referência enviado antes por `POST /v1/uploads` → `{ "path": "refs/.../….mp4" }`; ou `video_url` (https, mp4/webm/mov, até 50 MB) que o servidor baixa. Não combine com `images`. - `conversation_id` (opcional): nome (letras, números, `.`, `_`, `-`, até 64) de uma conversa da sua key. Pedidos com o mesmo nome rodam **na mesma conversa, um após o outro**, e o modelo lembra os anteriores (continuações de história, mesmo personagem). Sem ele, cada pedido é isolado numa conversa nova. - `images` (opcional): até 3 imagens de referência; `mime_type` em `image/png`, `image/jpeg` ou `image/webp`; `data_base64` é base64 puro (sem `data:…;base64,`), até 8 MB cada; `filename` opcional (letras, números, `.`, `_`, `-`, até 80 chars). Uma imagem = primeiro quadro/referência principal; várias = referências de uma mesma cena. Respostas: - `202 {"id":"","status":"queued","balance":}` - `400 {"error":""}` — validação (ex.: `prompt must be a non-empty string (max 5000 chars)`, `aspect_ratio must be one of: 16:9, 9:16, 1:1, 4:3, 3:4, 21:9`, `duration_seconds must be one of: 5, 10, 20, 30, 40, 50, 60`, `images must contain at most 3 items`). - `401` key inválida · `402 {"error":"insufficient balance","balance":N,"price_per_video":P}` sem créditos · `413` corpo grande demais · `429` fila cheia (máx. 8 pedidos pendentes por key: espere concluir e reenvie). ## POST /v1/uploads — reservar o envio de um vídeo de referência Body `{"filename":"clip.mp4","mime_type":"video/mp4","size":}` (mp4, webm ou mov; até 50 MB). Resposta `{"path":"refs//.mp4","upload":{"method":"PUT","url":"...","headers":{...}}}`. Faça `PUT` do arquivo bruto em `upload.url` com os `upload.headers` (é um endereço assinado do storage; sem a sua key). Depois crie o vídeo com `"video":{"path":""}`. O vídeo de referência é apagado quando o pedido termina. ## POST /v1/images — criar imagem Body `{"prompt":"pôster de um farol numa tempestade","aspect_ratio":"9:16","images":[...opcional, até 3 referências no mesmo formato...],"conversation_id":"opcional, como nos vídeos"}`. Não aceita `duration_seconds` nem `video`/`video_url` (400). Resposta `202 {"id":"","kind":"image","status":"queued","balance":N}`. Pronta em ~1 min. Acompanhe em `GET /v1/images/{id}` (mesmo formato abaixo, com `"kind":"image"`, `"media_type":"image"`, `duration_seconds` nulo e `url`/`download_url` em `/v1/images/{id}/preview|download`, PNG). `GET /v1/images` lista só imagens; `GET /v1/videos?kind=all` lista vídeos e imagens. Sem saldo: `402` com `price_per_image`. ## GET /v1/videos/{id} — acompanhar Consulte a cada 5 s (não menos). Resposta: ```json { "id": "", "kind": "video | image", "conversation_id": null, "status": "queued | generating | done | failed", "prompt": "...", "aspect_ratio": "16:9", "requested_seconds": 10, "duration_seconds": 8, "url": "https://www.videoapi.com.br/v1/videos//preview", "download_url": "https://www.videoapi.com.br/v1/videos//download", "preview_url": "...", "source": "local", "media_type": "video", "expires_at": "2026-01-01T12:00:00.000Z", "error": null, "created_at": "...", "finished_at": "..." } ``` - `done`: use `url`/`preview_url` para exibir (`