Tutorial
Como usar o veo-3.1-lite/image-to-video através da API hiapi
- Modelo
- veo-3.1-lite
O Veo 3.1 Lite transforma uma única imagem de referência mais um prompt de texto em um vídeo curto e, no hiapi, ele é disponibilizado através da mesma API de tarefas assíncronas compartilhada por todos os modelos da plataforma. Este guia percorre o fluxo de requisição que você realmente usa: obter a chave, chamar POST /v1/tasks, recuperar o resultado e os detalhes que importam quando você leva esse fluxo de um script único para a produção (callbacks, idempotência, tratamento de erros).
O que você vai construir e o que preparar antes
Você envia uma URL de imagem e um prompt para o modelo veo-3.1-lite/image-to-video e recebe de volta uma URL .mp4 hospedada externamente. Tudo é executado através do endpoint de tarefas unificado do hiapi, portanto a mesma estrutura de requisição se aplica a todos os modelos de vídeo e imagem da plataforma — apenas o id do model e os campos de input mudam.
Antes de começar:
- Crie uma conta hiapi e obtenha uma chave de API no console. A chave tem o formato
sk-.... - Prepare uma URL de imagem acessível publicamente — a API a busca no servidor, então caminhos
localhostou buckets privados não funcionam. - Antes de fazer requisições reais (não de teste), consulte a página de preços para ver o preço atual de
veo-3.1-lite/image-to-video, pois o custo depende da duração e da resolução.
Não há camada gratuita nem modo sem chave — cada chamada exige Authorization: Bearer sk-<your-key>.
Exemplo mínimo funcional
A API de tarefas do hiapi consiste em duas chamadas: criar a tarefa e depois ou consultá-la periodicamente (polling) ou deixar um callback informar quando ela terminar. Abaixo está a versão em Python com polling, usando apenas requests e time:
import time
import requests
API_KEY = "sk-your-key-here"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
payload = {
"model": "veo-3.1-lite/image-to-video",
"input": {
"prompt": "the camera slowly pushes in as steam rises from the cup",
"image_url": "https://example.com/your-reference-image.jpg",
"duration": 6,
"aspect_ratio": "16:9",
},
}
# 1. Create the task
resp = requests.post(BASE, headers=HEADERS, json=payload, timeout=60)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print("task created:", task_id)
# 2. Poll until it's done
while True:
task = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
status = task["status"]
if status == "success":
video_url = task["output"][0]["url"]
print("done:", video_url)
break
if status == "fail":
raise RuntimeError(task.get("error"))
time.sleep(5)
Se você quiser apenas ver o formato trafegado na rede, abaixo está a mesma coisa em curl puro:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3.1-lite/image-to-video",
"input": {
"prompt": "the camera slowly pushes in as steam rises from the cup",
"image_url": "https://example.com/your-reference-image.jpg",
"duration": 6,
"aspect_ratio": "16:9"
}
}'
# then poll:
curl -s https://api.hiapi.ai/v1/tasks/<taskId> \
-H "Authorization: Bearer sk-your-key-here"
Há alguns pontos no esquema de input que vale conhecer especificamente, porque ele é mais rigoroso do que aquele endpoint genérico de "envie qualquer coisa" — campos extras são rejeitados diretamente, em vez de ignorados silenciosamente:
prompteimage_urlsão os únicos dois campos obrigatórios.image_urlestá no singular — este modelo aceita exatamente uma imagem de referência, não um array.durationaceita apenas4,6ou8(segundos) — nenhum outro inteiro é aceito.aspect_ratioaceitaauto,16:9ou9:16.resolutionaceita720pou1080p.- Itens opcionais adicionais:
seed(inteiro, para reprodução),generate_audio(booleano),negative_prompt(string).
Observe que o id do modelo é um id puro, ou seja, veo-3.1-lite/image-to-video — não adicione prefixo ou namespace extra a ele.
Assim que status se torna "success", o vídeo de saída fica em data.output[0].url. Essa URL é temporária (possui expireAt), portanto baixe-a imediatamente ou re-hospede-a, em vez de guardar esse hotlink.
Considerações para produção: callbacks, idempotência e erros
Consultar a cada 5 segundos é aceitável em um script, mas é desperdício em um servidor que lida com muitas tarefas ao mesmo tempo. Para tráfego de produção, recomenda-se usar callbacks: passe um objeto callback na mesma requisição de criação de tarefa e o hiapi fará um POST do resultado final para o seu endpoint, em vez de você precisar perguntar.
payload = {
"model": "veo-3.1-lite/image-to-video",
"input": {
"prompt": "the camera slowly pushes in as steam rises from the cup",
"image_url": "https://example.com/your-reference-image.jpg",
},
"callback": {
"url": "https://yourapp.example.com/hooks/hiapi",
"when": "final",
},
}
A configuração-chave aqui é when: "final" — significa que você será notificado apenas uma vez, quando a tarefa atingir um estado terminal (success ou fail), em vez de a cada mudança de estado intermediário. Seu handler de webhook deve validar o id da tarefa e então buscar o registro local da tarefa que você criou ao chamar POST /v1/tasks originalmente.
Idempotência. Se o seu serviço pode repetir a chamada de criação de tarefa (timeout, entrega pelo menos uma vez etc.), anexe um cabeçalho Idempotency-Key, com no máximo 255 bytes:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-your-key-here" \
-H "Idempotency-Key: order-42-veo-submit" \
-H "Content-Type: application/json" \
-d '{...}'
Repetir a chamada na mesma conta com a mesma chave retorna o taskId original, em vez de criar uma segunda tarefa (cobrável) — você pode disparar com segurança a partir de um loop de retentativa sem cobrar o cliente duas vezes.
Polling vs. callbacks, em resumo: para scripts, notebooks ou ferramentas internas de baixo tráfego, use polling se você já está bloqueando à espera do resultado. Para qualquer cenário no lado do servidor e concorrente, use callbacks — eles evitam manter conexões abertas e escalam para muitos trabalhos em andamento sem executar um loop de polling para cada tarefa.
Tratamento de erros. Uma chave inválida ou revogada retorna HTTP 401 com error.code: "permission_denied" — verifique isso especificamente, em vez de presumir que qualquer resposta fora da faixa 2xx significa que a geração do vídeo em si falhou. Um input malformado (prompt ausente, duration fora do intervalo do enum, campos não reconhecidos) retorna HTTP 400 com error_code: "INVALID_REQUEST" e uma mensagem que aponta o campo específico com problema — vale exibir isso diretamente nos seus logs, em vez de engolir, porque a mensagem indica exatamente o que corrigir. Uma vez que a tarefa é aceita, uma falha do lado da geração aparece como status: "fail" e um objeto error no payload de polling/callback — só trate como repetível se a mensagem indicar um problema transitório do upstream, e não um problema de esquema.
Recursos relacionados
- Documentação do modelo veo-3.1-lite/image-to-video — referência completa de parâmetros deste modelo específico
- Criar tarefa e Obter detalhes da tarefa — os dois endpoints sobre os quais este guia é construído
- Documentação de autenticação — formato da chave e requisitos de cabeçalho
- Veo 3.1 Image-to-Video: guia para vídeos curtos — se você quiser a saída de maior fidelidade do modelo não-lite, esta é a explicação de casos de uso
- Preços — taxas atuais por segundo, divididas por duração e resolução
Perguntas frequentes
Preciso passar image_url como data URI ou base64?
Não — image_url deve ser uma URL HTTP(S) pública que os servidores do hiapi possam buscar. Este modelo não aceita imagens codificadas em base64.
Posso gerar vídeo sem uma imagem de referência?
Com veo-3.1-lite/image-to-video, não — é um modelo de imagem para vídeo, e image_url é obrigatório. Se você quer geração puramente a partir de texto, use um modelo de texto para vídeo; a página do modelo Veo 3.1 não-lite lista os modos disponíveis.
Por que minha requisição retorna 400 mesmo eu passando todos os campos obrigatórios?
Verifique se há campos extras — o esquema de entrada deste modelo rejeita qualquer coisa que não esteja na lista permitida (prompt, image_url, duration, aspect_ratio, resolution, seed, generate_audio, negative_prompt). A mensagem de erro indica o campo exato que não foi reconhecido.
Quanto tempo a geração realmente leva? Varia com a duração e a profundidade atual da fila, e é exatamente por isso que consultar em intervalos curtos ou usar callback é a abordagem correta, em vez de presumir um tempo de espera fixo.
O resultado pode ter áudio?
Sim, através do booleano generate_audio — consulte a documentação do modelo para saber os padrões atuais e como isso afeta o custo.
E se meu endpoint de callback estiver fora do ar quando a tarefa terminar?
Nunca dependa apenas da chegada do callback — guarde o taskId retornado na chamada de criação e, se não receber o callback dentro de uma janela de tempo razoável, recorra ao polling via GET /v1/tasks/<id>.
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