Tutorial
Como chamar seedream-5.0-lite/text-to-image pela API HiAPI: guia com curl e Python
Exercício prático de requisição para desenvolvedores: integração de texto para imagem via HiAPI
O que essa integração realmente faz
Fazer uma chamada de texto para imagem na HiAPI é uma breve conversa entre o seu código e uma fila de tarefas assíncrona. Você envia uma requisição descrevendo a imagem que deseja; a plataforma valida a requisição, aceita a tarefa e devolve um identificador. A imagem não vem na primeira resposta — ela é gerada depois. Em seguida, seu código monitora a tarefa até que ela informe conclusão e, por fim, baixa a imagem da URL exposta pela tarefa.
Esse formato importa porque determina como você escreve a integração. Há três momentos distintos: submissão, polling e obtenção. Cada um tem seus próprios modos de falha. A submissão falha quando o payload está malformado ou o caminho do modelo é inválido. O polling falha quando o loop está mal escrito — rápido demais, curto demais, ou incapaz de distinguir "ainda em execução" de "concluído". A obtenção falha quando você trata a URL de saída como um endereço permanente ou esquece de gravar os bytes em disco.
Por baixo, seedream-5.0-lite/text-to-image é um modelo genérico de texto para imagem na plataforma HiAPI. Você o chama pelo identificador exato do modelo. Os parâmetros que você envia são os comuns desse tipo de chamada: nome do modelo, prompt e quaisquer parâmetros de controle de tamanho ou quantidade de saída indicados na documentação do endpoint. Você não precisa de nenhum SDK especial; um cliente HTTPS comum é suficiente.
Ao final deste exercício, você terá uma requisição reproduzível com curl, uma função Python em torno dela, dicas de como formular prompts para que o texto renderizado fique legível, e um loop de polling que realmente termina. Tudo roda pelo mesmo endpoint HiAPI, portanto, assim que uma chamada funcionar, o resto é ajuste de parâmetros.
Construindo a requisição com curl
Comece pela linha de comando. Uma chamada curl funcional é a base do payload — quando ela funciona, qualquer outra linguagem é apenas exercício de tradução.
Você precisa de duas coisas antes da primeira chamada: sua chave de API HiAPI e a URL base da API. A chave vai no cabeçalho Authorization como token bearer. Mantenha-a fora do histórico do shell sempre que possível; variáveis de ambiente são o hábito mais simples.
export HIAPI_API_KEY="your_api_key_here"
A requisição em si é um POST com corpo JSON. O identificador do modelo é o segmento de caminho a chamar, e o prompt descreve a imagem:
curl -sS -X POST "$HIAPI_BASE_URL" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5.0-lite/text-to-image",
"prompt": "A minimalist poster for a coffee shop called North Roast, warm cream background, bold dark lettering"
}'
Defina HIAPI_BASE_URL com o endpoint de submissão de texto para imagem mostrado na documentação da plataforma; o caminho varia conforme a interface do produto, então copie em vez de adivinhar.
Antes de escrever mais código, leia a resposta. Uma submissão bem-sucedida retorna um objeto JSON com o identificador da tarefa e um campo de status. O status geralmente indica que a tarefa está na fila ou em processamento — ainda não concluída. Isso é esperado. Anote os nomes exatos dos campos retornados; você os usará nas próximas duas seções.
Dois erros no nível do curl causam a maioria das primeiras falhas. O primeiro é chave ausente ou com escopo errado: a resposta é um erro de autenticação, não de modelo. O segundo é corpo malformado — aspas não escapadas dentro do prompt, vírgula final, aspas simples onde o JSON exige aspas duplas. Se a plataforma rejeitar o payload, formate-o com jq e valide-o isoladamente antes de culpar o modelo.
Quando a submissão retorna um identificador, você tem uma requisição válida. Tudo depois disso é esperar e obter.
Portando para Python
A versão Python deve ser uma função pequena e reutilizável — não um script com um único prompt fixo. Use requests (ou httpx, se preferir); a chamada em si não exige cliente especial.
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
def submit_image(prompt: str, **params) -> dict:
payload = {
"model": "seedream-5.0-lite/text-to-image",
"prompt": prompt,
**params,
}
response = requests.post(BASE_URL, headers=HEADERS, json=payload, timeout=30)
response.raise_for_status()
return response.json()
Há três escolhas intencionais aqui. A chave e a URL base vêm do ambiente, então a função pode ser commitada com segurança. O parâmetro coringa **params permite passar tamanho de saída ou outras opções documentadas sem editar a função. E raise_for_status() converte erros HTTP em exceções imediatamente, que é o que você quer — um 4xx na submissão nunca vira uma tarefa válida, então falhar rápido é melhor do que inspecionar um corpo de resposta confuso.
O dicionário retornado é o registro da sua tarefa. Imprima-o uma vez durante o desenvolvimento para conhecer as chaves exatas do identificador e do status. Não indexe às cegas; um pequeno acessor mantém o restante do código legível:
job = submit_image("A flat illustration of a paper plane over a city map")
print(job)
Se ele imprimir uma tarefa enfileirada, a portabilidade a partir do curl está correta. Se lançar exceção, a mensagem de raise_for_status() dirá se foi problema de autenticação ou de payload — os mesmos dois tipos de problema que você teria no shell.
Escrevendo prompts para conhecimento de mundo e texto renderizado
Modelos de texto para imagem são mais fortes quando o prompt descreve o que deve estar visível, e mais fracos quando sugere conhecimento que o modelo precisa inferir. seedream-5.0-lite/text-to-image aproveita contexto geral de mundo — objetos reconhecíveis, convenções comuns de design, estilos tipográficos — mas você ainda precisa fornecer conteúdo suficiente para ancorar esse contexto.
Para prompts de cena, descreva o sujeito, a composição e o estilo visual. 'A cozy reading nook by a window, soft afternoon light, three-quarter view, muted earth tones' diz ao modelo tanto o que desenhar quanto como estilizar. Prompts vagos geram imagens genéricas; prompts específicos geram imagens utilizáveis.
Texto renderizado é onde os prompts costumam falhar. Se você precisa de texto dentro da imagem, siga algumas regras:
- Cite a string exata. Escreva o texto desejado entre aspas, para deixar claro que é literal, não descritivo.
- Mantenha curto. Títulos curtos ou nomes de marca renderizam de forma confiável; parágrafos não.
- Indique posição e estilo. 'The word "North" centered at the top in a bold sans-serif' é melhor que 'some text at the top'.
- Evite textos concorrentes. Vários elementos de texto distintos na mesma imagem tendem a virar caracteres embaralhados. Se precisar de vários, mantenha-os curtos e bem separados.
- Itere uma variável por vez. Mude a formulação, não a formulação, o layout e o estilo ao mesmo tempo, senão você não saberá o que resolveu o problema.
Para qualquer coisa que envolva contexto reconhecível — categoria de produto, tipo de pôster, tipo de placa — nomeie explicitamente. O conhecimento prévio do modelo é mais útil quando o prompt oferece uma âncora. 'A vintage travel poster for a coastal town' carrega mais contexto aproveitável do que 'a poster'.
Não invente parâmetros. Se o prompt não produziu a posição de texto desejada, ajuste primeiro a formulação do próprio prompt antes de tentar opções que você não viu documentadas.
Tratando tarefas assíncronas e baixando a saída
O polling é onde a integração falha silenciosamente. A tarefa é assíncrona, então você precisa de um loop que verifique o status, espere entre verificações, desista em algum momento e saiba exatamente quais valores de status significam "concluído".
import time
def wait_for_job(job_id: str, poll_interval: float = 3.0, timeout: float = 180.0) -> dict:
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
response = requests.get(
f"{BASE_URL}/{job_id}", headers=HEADERS, timeout=30
)
response.raise_for_status()
job = response.json()
status = job.get("status")
if status in {"succeeded", "completed"}:
return job
if status in {"failed", "error", "cancelled"}:
raise RuntimeError(f"Job {job_id} ended with status {status}")
time.sleep(poll_interval)
raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")
Ajuste o caminho de polling e as strings de status conforme a documentação da plataforma — esses dois detalhes são os mais propensos a divergir do esboço acima. O essencial é a estrutura: um prazo monotônico, espera entre verificações, conjuntos explícitos de sucesso e falha, e um timeout que lança exceção em vez de retornar uma tarefa pela metade.
Quando a tarefa reporta sucesso, a resposta contém a URL da saída. Trate essa URL como temporária. Baixe os bytes imediatamente, em vez de guardar o link:
def download_image(url: str, path: str) -> None:
response = requests.get(url, timeout=60)
response.raise_for_status()
with open(path, "wb") as f:
f.write(response.content)
job = wait_for_job(job_id)
download_image(job["output"]["url"], "out.png")
Antes de seguir, confirme que o arquivo é uma imagem real — abra-o, confira as dimensões ou ao menos verifique se o tamanho em bytes não é anormalmente pequeno. Se o servidor fechar a conexão normalmente, um download truncado pode parecer sucesso para o requests.
Erros comuns e como corrigi-los
A maioria das falhas nas primeiras integrações se divide em quatro categorias. Trate-as em ordem.
Submissão rejeitada
Se a primeira chamada retornar 4xx, imprima o corpo da resposta. Erro de autenticação significa chave ausente, expirada ou não enviada como token bearer. Erro de esquema significa payload malformado — campo de modelo errado, prompt ausente ou parâmetro documentado com erro de digitação. Valide o JSON isoladamente e compare com o exemplo funcional de curl.
A tarefa nunca conclui
O loop gira para sempre ou atinge o timeout. Verifique primeiro o intervalo de polling: martelar o endpoint sem esperar pode disparar limites de taxa, fazendo uma tarefa saudável parecer travada. Em seguida, verifique a comparação de status — se a plataforma retorna success e você compara com succeeded, toda tarefa parecerá não concluída. Registre o valor bruto de status uma vez, em vez de adivinhar.
A URL de saída retorna 404 ou 403
A URL de saída é assinada e tem prazo de validade. Se você fez polling por muito tempo antes de obter, o link pode ter expirado. Obtenha imediatamente após a conclusão e, se precisar guardar o resultado, salve o arquivo em vez do link.
A imagem renderiza, mas o texto fica embaralhado
Isso é problema de prompt, não de código. Encurte o texto, cite com exatidão, reduza a quantidade de elementos de texto e torne as instruções de estilo mais explícitas. Execute novamente alterando apenas uma coisa por vez, para saber qual ajuste ajudou.
A requisição trava ou dá timeout
Sempre defina timeouts explícitos nas chamadas de submissão e de polling. Uma requisição sem timeout pode bloquear indefinidamente um worker, e um loop de polling sem prazo transforma uma interrupção transitória em um processo travado.
Quando ocorrer comportamento inesperado, reduza ao menor chamado curl que ainda falha. Se a requisição HTTP bruta se comporta mal, a camada Python não é o problema — assim que o curl voltar a funcionar, portar de volta para Python é mecânico. A página do modelo seedream-5.0-lite/text-to-image lista os parâmetros e o formato de resposta atuais, então consulte-a antes de presumir nomes de campos.
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