Tutorial
Como usar a API de texto para vídeo grok-imagine-1.5-lite (curl + Python)
Se você quer gerar um vídeo curto com áudio a partir de uma única frase, grok-imagine-1.5-lite/text-to-video é a opção mais barata da hiapi capaz de chegar a 1080P. Ele recebe um prompt e retorna um MP4 de 1 a 15 segundos, já com o áudio mixado, e roda na mesma API de tarefas unificada de todos os outros modelos da plataforma. Esta página traz requisições prontas para copiar e executar, o schema exato (verificado contra o endpoint ao vivo, não copiado da especificação), como é uma resposta real e as pegadinhas que encontrei durante os testes.
Todo o conteúdo abaixo foi verificado contra a API ao vivo em 2026-10-21. Os preços são os que medi; se mudarem, vale a página de preços.
1. O que você vai construir e o que precisa preparar
Objetivo: enviar um prompt de texto e receber de volta um clipe MP4 com áudio, pronto para download.
Você só precisa de uma coisa: uma API key da hiapi. Crie uma no console e guarde no servidor — ela tem o formato sk-... e vai no cabeçalho Authorization: Bearer. Não existe caminho sem key; toda requisição abaixo precisa ser autenticada.
O modelo é assíncrono. Você não recebe o vídeo diretamente na resposta do POST. Primeiro cria uma tarefa, obtém o taskId e depois faz polling (ou usa callback) até a tarefa concluir e entregar a URL de saída.
2. Exemplo mínimo funcional
Dois passos: criar a tarefa e depois fazer polling do resultado.
Criar a tarefa (curl)
curl -s -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-1.5-lite/text-to-video",
"input": {
"prompt": "Ao amanhecer, uma raposa-vermelha atravessa a neve recém-caída, o hálito virando névoa branca, luz suave da manhã, leve som ambiente de vento. Cinematográfico, cores naturais. Sem texto.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9"
}
}'
Repare na estrutura: model fica no nível superior e todo o resto é aninhado em input. Se você enviar os campos achatados (sem o invólucro input), a API rejeita o corpo inteiro com invalid input: must be a JSON object — é o erro mais comum.
Uma criação bem-sucedida retorna um id de tarefa imediatamente:
{ "code": 200, "data": { "taskId": "tk-hiapi-01M5E3QKSB2TAJRDHR5Y8EQNEB" }, "message": "success" }
Polling do resultado (Python)
import time, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEAD = {"Authorization": "Bearer sk-YOUR_KEY", "Content-Type": "application/json"}
def generate(prompt, duration=5, resolution="720p", aspect_ratio="16:9"):
r = requests.post(BASE, headers=HEAD, json={
"model": "grok-imagine-1.5-lite/text-to-video",
"input": {
"prompt": prompt,
"duration": duration, # integer, 1–15
"resolution": resolution, # "480p" | "720p" | "1080p"
"aspect_ratio": aspect_ratio, # veja o schema abaixo
},
})
r.raise_for_status()
task_id = r.json()["data"]["taskId"]
# Poll the SAVED task_id. A single transient network error is not a failure —
# keep polling the same id rather than re-creating (re-creating bills again).
deadline = time.time() + 300
while time.time() < deadline:
try:
d = requests.get(f"{BASE}/{task_id}", headers=HEAD, timeout=30).json()
except requests.RequestException:
time.sleep(5); continue
task = d.get("data") or {}
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
raise RuntimeError(task.get("error"))
time.sleep(5)
raise TimeoutError(task_id)
print(generate("Ao amanhecer, uma raposa-vermelha atravessa a neve recém-caída, leve som ambiente de vento. Cinematográfico."))
Schema (verificado ao vivo)
Os campos ficam dentro de input. O schema é fechado — qualquer chave que ele não conheça retorna 400, então não envie seed, negative_prompt ou motion_mode (nenhum deles existe aqui; todos os movimentos de câmera e direções de movimento são expressos pela redação do prompt).
| Campo | Tipo | Obrigatório | Valores aceitos |
|---|---|---|---|
prompt |
string | Sim | Texto livre |
duration |
integer | Sim | 1–15 (segundos inteiros; 5.5 é rejeitado) |
resolution |
string | — | 480p, 720p, 1080p |
aspect_ratio |
string | — | 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16 |
Este modelo não tem proporção de aspecto auto (o equivalente dele de imagem para vídeo tem; este endpoint de texto para vídeo não). Especifique a proporção explicitamente, senão você recebe a proporção padrão do modelo.
Abaixo está o retorno real de uma tarefa concluída:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01M5E3QKSB2TAJRDHR5Y8EQNEB",
"model": "grok-imagine-1.5-lite/text-to-video",
"status": "success",
"storage": "temp",
"output": [
{ "type": "video", "url": "https://temp.hiapi.ai/.../...-0.mp4", "expireAt": 1793153637 }
]
},
"message": "success"
}
Este é um clipe gerado por esse modelo (saída de referência que a hiapi oferece para grok-imagine-1.5-lite/text-to-video, gerada a partir do prompt de exemplo da documentação — "Ao nascer do sol, um balão de ar quente de vidro flutua sobre terraços cultivados"):
3. Colocando em produção
Use callback em vez de polling. Polling funciona bem para scripts; para servidores, adicione callback para não precisar manter a requisição aberta. Quando a tarefa atinge um estado terminal, a plataforma envia os detalhes da tarefa via POST para a sua URL:
{
"model": "grok-imagine-1.5-lite/text-to-video",
"input": { "prompt": "...", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9" },
"callback": { "url": "https://your.app/hooks/hiapi", "when": "final" }
}
Nesse tipo de tarefa, when aceita apenas "final". Deduplique por taskId no seu handler — callbacks podem ser reenviados, então trate o handler como idempotente.
As URLs de saída expiram. Observe o storage: "temp" e o timestamp unix expireAt — as saídas temporárias ficam em temp.hiapi.ai por cerca de 7 dias e depois retornam 404. Não salve hotlinks. Baixe os bytes no momento em que a tarefa conclui ou chame o endpoint de promoção de armazenamento para mover o artefato para armazenamento permanente antes que o TTL expire.
A cobrança é por segundo de saída. O custo depende apenas de duration e da resolução solicitada. Nos testes: 480P $0.029/s, 720P $0.043/s, 1080P $0.20/s. Assim, um clipe de 5 s em 720P custa cerca de $0.215, um de 5 s em 1080P cerca de $1.00 e um de 1 s em 480P cerca de $0.029. A tarifa de 1080P é aproximadamente 5 vezes a de 720P — use só quando realmente precisar dessa resolução. Veja os números mais recentes na página de preços.
Tratamento de erros. Requisições rejeitadas retornam HTTP 400 com uma mensagem precisa que pode ser registrada e tratada. A validação ocorre antes de criar qualquer tarefa, então um 400 aqui não gera cobrança. Respostas reais que disparei:
invalid input: duration: maximum: got 999, want 15
invalid input: duration: minimum: got 0, want 1
invalid input: duration: got number, want integer
invalid input: resolution: value must be one of '480p', '720p', '1080p'
invalid input: aspect_ratio: value must be one of '16:9', '4:3', '3:2', '1:1', '2:3', '3:4', '9:16'
invalid input: prompt: missing required field "prompt"
invalid input: <root>: additional properties 'bogus_field' not allowed
Tarefas aceitas que falham depois aparecem como data.status: "fail" com um objeto data.error no endpoint de detalhes — não como erro HTTP — então verifique o status e não confie no código de status HTTP do polling.
4. O que observei na prática
Executei uma geração real para confirmar o fluxo de ponta a ponta (não apenas o schema): duration: 1, resolution: "480p", aspect_ratio: "16:9".
- Funciona de verdade e cobra de verdade — o POST retornou um
taskIde a tarefa concluiu com uma URL de saída real. A renderização do clipe de 1 segundo levou cerca de 51 segundos no servidor; mesmo clipes minúsculos não são instantâneos, então defina um prazo de polling generoso (usei 300 segundos). - As tarefas passam por estados intermediários. O campo
statuspassa porhandling→archiving→success. Apenassuccessefailsão estados terminais; não tratearchivingcomo concluído. - 480P em 16:9 renderiza como 848×480 H.264. Execute
ffprobeno arquivo baixado: um stream de vídeo H.264 (848×480) mais um stream de miniatura MJPEG incorporado. O arquivo de 495 KB é um MP4 válido. - O áudio sempre vem embutido. Mesmo que meu prompt mencionasse apenas "leve som ambiente de vento", a saída tinha uma faixa de áudio AAC — o modelo sintetiza o áudio correspondente e o mixa no mesmo MP4. Não há URL de áudio separada nem opção para desabilitá-lo; se você precisa de um clipe sem som, remova a faixa por conta própria (
ffmpeg -an).
Nota de escopo: validei o contrato da API, os três tipos de erro acima e uma renderização em 480P. Não fiz benchmarks da qualidade das saídas em 720P/1080P nem de durações longas (15 s), então não faço afirmações de qualidade sobre elas — apenas digo que o schema as aceita e cobra por segundo.
5. Lite vs. API de vídeo Grok Imagine padrão
Escolha o endpoint certo antes de construir:
grok-imagine-1.5-lite/text-to-video(esta página): 480P/720P/1080P, 1–15 segundos (portanto gera clipes de 1 ou 2 segundos), preço de$0.029–$0.20/s. É o único endpoint de texto para vídeo de 1.5ª geração hospedado na hiapi e a única faixa t2v do Grok que chega a 1080P.grok-imagine/text-to-video(a faixa padrão mais antiga, veja este guia): mais barato por segundo ($0.0114–$0.0214/s) e oferece Motion Modes, mas chega no máximo a 720p e exige duração de 6–30 segundos — não gera clipes com menos de 6 segundos.
Então o "lite" aqui não é a opção mais barata por segundo; é a faixa que desbloqueia 1080P e clipes muito curtos. Se você quer usar uma única imagem estática como entrada em vez de texto, use o endpoint grok-imagine-1.5-lite/image-to-video da mesma faixa (mesmo preço, entrada como image_urls).
6. Links relacionados
- Página do modelo / playground do grok-imagine-1.5-lite texto para vídeo
- Criar tarefa — referência da API
- Obter detalhes da tarefa — referência da API
- Preços
Perguntas frequentes
Preciso fazer polling ou existe callback? Os dois funcionam. Scripts usam polling em GET /v1/tasks/{taskId}; servidores adicionam callback.url e definem when como "final". Deduplique por taskId.
Por que minha requisição retorna 400 com "must be a JSON object"? Seus campos não estão dentro de input. O corpo deve ser {"model": "...", "input": { ... }}.
Dá para desligar o áudio? Na requisição, não — toda saída inclui uma faixa AAC mixada. Se precisar de silêncio, remova depois com ffmpeg -an.
Quanto tempo dura a URL de saída? É uma URL temporária com expireAt (cerca de 7 dias). Baixe imediatamente ou promova para armazenamento permanente; não faça hotlink.
Qual é a requisição válida mais barata? 1 segundo em 480P custa cerca de $0.029. Antes de processar em lote, é uma boa forma de fazer uma requisição canário para confirmar que sua key tem saldo.
Artigos relacionados
Ver todos os artigos →-
Tutorial
Como chamar hailuo-2.3-fast/image-to-video pela API HiAPI: curl e Python na prática
A primeira requisição executável do nível rápido e econômico de geração de vídeo a partir de imagem — do ID do modelo ao download do MP4
-
Tutorial
Como chamar hailuo-2.3/text-to-video pela API HiAPI: curl, Python e exemplos de requisição executáveis
-
Tutorial
Usar Kandinsky 6.0 Pro text-to-video na HiAPI: tutorial de curl e Python
Demonstração prática com foco na requisição: montar a chamada de prompt para clipe de vídeo, enviar a requisição, consultar o status de conclusão e baixar o resultado