Tutorial
Como usar veo-3.1-lite/text-to-video via API hiapi: curl, Python e uma requisição executável
veo-3.1-lite/text-to-video gera clipes de vídeo curtos apenas com um prompt de texto — sem necessidade de imagem inicial. Este guia traz exemplos de curl e Python prontos para copiar e colar contra a API real de tarefas da hiapi, o schema de entrada exato (confirmado contra o endpoint em produção) e os formatos de erro que você realmente encontrará em produção.
1. Pré-requisitos
- Uma conta hiapi e uma chave de API (
sk-...) obtida no painel de API Keys. - curl, ou Python 3 com
requestsinstalado (pip install requests). - Nada mais —
text-to-videosó precisa de uma string de prompt.
Cada modelo de geração na hiapi funciona pela mesma API de tarefas assíncronas unificada: POST /v1/tasks cria a tarefa, e então você faz polling ou aguarda um callback para obter o resultado. A chamada de veo-3.1-lite/text-to-video é exatamente igual à de qualquer outro modelo de vídeo — mesmos cabeçalhos de autenticação, mesmo ciclo de vida de tarefa — apenas model e input mudam. O id do modelo é veo-3.1-lite/text-to-video, com o sufixo /text-to-video; a mesma família também oferece veo-3.1-lite/image-to-video, um id de modelo separado para animar uma imagem de origem.
2. Exemplo mínimo executável
2.1 Criar a tarefa (curl)
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3.1-lite/text-to-video",
"input": {
"prompt": "a paper boat drifting down a rain-slicked city street at night, neon signs reflecting on wet asphalt",
"duration": 6,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true
}
}'
Uma chamada bem-sucedida retorna imediatamente um id de tarefa — a geração é assíncrona:
{"code":200,"data":{"taskId":"tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX"},"message":"success"}
2.2 Consultar o resultado
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX \
-H "Authorization: Bearer sk-<your-api-key>"
Enquanto o clipe está sendo renderizado, status é "handling". Quando concluído:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX",
"model": "veo-3.1-lite/text-to-video",
"status": "success",
"storage": "temp",
"output": [
{"artifactId": "...", "type": "video", "url": "https://temp.hiapi.ai/.../result.mp4", "expireAt": 1786932195}
]
},
"message": "success"
}
output[0].url é um link temporário e expirável — baixe o arquivo antes de expireAt expirar (ou mova a saída para um armazenamento permanente).
2.3 Exemplo completo em Python
import time
import requests
API_KEY = "sk-<your-api-key>"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task(prompt: str) -> str:
resp = requests.post(BASE, headers=HEADERS, json={
"model": "veo-3.1-lite/text-to-video",
"input": {
"prompt": prompt,
"duration": 6,
"resolution": "720p",
"aspect_ratio": "16:9",
},
}, timeout=30)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_for_result(task_id: str, poll_seconds: int = 5, timeout_seconds: int = 600) -> str:
deadline = time.time() + timeout_seconds
while time.time() < deadline:
resp = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
data = resp.json()["data"]
if data["status"] == "success":
return data["output"][0]["url"]
if data["status"] == "failed":
raise RuntimeError(f"task {task_id} failed: {data}")
time.sleep(poll_seconds)
raise TimeoutError(f"task {task_id} did not finish in {timeout_seconds}s")
if __name__ == "__main__":
tid = create_task("a paper boat drifting down a rain-slicked city street at night")
video_url = wait_for_result(tid)
print(video_url)
3. Schema de entrada
Todos os campos abaixo ficam sob input. O schema é rígido — enviar um campo inexistente retorna 400 (additional properties '<field>' not allowed), o que é uma ótima forma de validar rapidamente uma requisição antes da renderização.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
prompt |
string | Sim | Descrição da cena; especifique sujeito, movimento e comportamento de câmera. |
duration |
integer | Não | Um de 4, 6, 8 (segundos). |
resolution |
string | Não | "720p" ou "1080p". |
aspect_ratio |
string | Não | "16:9" ou "9:16". |
generate_audio |
boolean | Não | Inclui áudio ambiente/efeitos sonoros sincronizados na renderização. |
negative_prompt |
string | Não | Elementos de conteúdo que a renderização deve evitar. |
seed |
integer | Não | Valor fixo para reproduzir a mesma composição/movimento entre tentativas. |
Durações mais longas e resoluções mais altas aumentam o custo de renderização — antes de escalar lotes grandes de tarefas, consulte os preços atuais por modelo na página de preços.
4. Padrões para produção
Prefira callback a polling em escala
Para qualquer coisa além de um script pontual, registre um callback em vez de fazer polling em loop:
{
"model": "veo-3.1-lite/text-to-video",
"input": {"prompt": "..."},
"callback": {"url": "https://your-app.example.com/webhooks/hiapi", "when": "final"}
}
callback.url deve ser uma URL http(s) acessível, e when aceita apenas "final" — a hiapi fará um único POST quando a tarefa atingir um estado terminal (success ou failed). Isso evita desperdiçar cota de requisições em loops de polling e entrega o resultado no instante em que ele fica pronto, o que importa ainda mais para vídeo (tempo de renderização maior que o de geração de imagem).
Idempotência e retentativas
Se seu executor de tarefas pode retentar o envio (crash, timeout, novo deploy), registre sua própria chave de idempotência junto com o taskId retornado antes de fazer a requisição, para que ao retentar você possa verificar “já enviei isto?” em vez de criar uma renderização duplicada e pagar duas vezes por ela.
Tratamento de erros
Na prática surgem dois formatos de erro diferentes:
- Entrada inválida (
400) — erro de validação no corpo da requisição:{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: prompt: missing required field \"prompt\""} - Falha de autenticação/permissão (
401) — chave ausente, inválida ou sem permissão suficiente:{"error":{"code":"permission_denied","message":"This API key cannot use the selected model...","request_id":"...","type":"hiapi_error"}}
Ramifique primeiro pelo código de status HTTP e depois examine o corpo da resposta — 400 quase sempre significa nome de campo ou valor incorreto (corrija a requisição), enquanto 401 significa que a própria chave precisa de atenção (permissão no painel ou uma nova chave).
5. Páginas relacionadas
- Página do modelo veo-3.1-lite/text-to-video — preços em tempo real e um playground no navegador para testar prompts antes de integrar o código.
- Página do modelo veo-3.1-lite/image-to-video — o modelo irmão condicionado por imagem, para animar uma cena existente em vez de partir de texto.
- Introdução à API assíncrona unificada — o ciclo de vida de tarefa compartilhado por todos os modelos da hiapi (imagem, vídeo, áudio).
- Documentação de autenticação — formato da chave de API e detalhes dos cabeçalhos.
- Guia da API seedance-2.5/text-to-video — um segundo modelo de texto para vídeo na mesma API de tarefas, útil para comparar schema e preços.
Perguntas frequentes
O veo-3.1-lite/text-to-video precisa de uma imagem inicial?
Não. Ele gera inteiramente a partir da string prompt. Se você tem uma imagem de origem para animar, use o id de modelo separado veo-3.1-lite/image-to-video.
Quais resoluções e durações são suportadas?
resolution é "720p" ou "1080p"; duration é 4, 6 ou 8 segundos. Enviar qualquer outro valor retorna 400, listando o conjunto de valores permitidos.
O clipe gerado pode ter áudio?
Sim — defina "generate_audio": true em input para incluir áudio ambiente/efeitos sonoros sincronizados.
Como evitar fazer polling em loop?
Passe um objeto callback com a url do seu webhook e "when": "final". Quando a tarefa terminar, a hiapi fará um POST para essa URL, sem que você precise reconsultar periodicamente GET /v1/tasks/<id>.
Por que minha requisição retorna 401 em vez de 400?
401 com error_code/code igual a "permission_denied" indica que a própria chave de API é inválida ou não tem acesso ao modelo — verifique o painel de API Keys. 400 indica corpo de requisição mal formatado para uma chave que é válida.
A URL do vídeo retornada é permanente?
Não — output[0].url é um link temporário com um timestamp expireAt. Baixe-o antes de expirar ou mova-o para armazenamento permanente.
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