Tutorial
Como chamar gpt-image-2/text-to-image@ext via API HiAPI: curl e Python
Exercício prático de requisições para desenvolvedores que integram geração de imagem a partir de texto
O que gpt-image-2/text-to-image@ext oferece
gpt-image-2/text-to-image@ext é um modelo de geração de imagem a partir de texto disponibilizado externamente pela interface unificada da HiAPI. Você só precisa enviar o prompt e parâmetros de geração opcionais ao mesmo endpoint para obter os dados da imagem gerada. Não é necessário instalar nenhum componente específico do modelo, nem integrar SDKs por fornecedor, nem gerenciar contas separadas — a mesma API key e a mesma estrutura de requisição cobrem o restante das capacidades da plataforma.
Escolha este modelo quando seu produto precisar transformar descrições textuais em imagens inéditas: copy de marketing em visual principal, prompt do usuário em miniatura, ferramentas de design que renderizam concept art sob demanda. Como a chamada é uma requisição HTTP comum, ela se integra facilmente a serviços de backend, workers de fila ou scripts, sem qualquer biblioteca cliente.
É a escolha certa quando a entrada é texto e a saída é um bitmap que você pretende armazenar e distribuir por conta própria. Se no futuro você precisar alternar para outra rota de imagem na plataforma, a lógica de integração — autenticação, envelope da requisição, tratamento da saída — permanece igual; basta alterar o identificador do modelo e o bloco de parâmetros.
Como ler este guia
Este exercício avança em camadas. Primeiro, uma requisição mínima que retorna uma imagem; depois, a versão em Python; em seguida, a decisão estrutural entre chamada única e polling assíncrono; por fim, o tratamento da saída. Cada camada pode ser testada isoladamente, de modo que, quando algo falhar, você saiba exatamente qual alteração introduziu o problema.
Pré-requisitos e autenticação
Antes de enviar a primeira requisição, você precisa de duas coisas: uma conta HiAPI e uma API key vinculada a ela. Crie a key no painel da conta e armazene-a como qualquer segredo — variável de ambiente localmente, secrets manager em produção. Não faça commit no repositório nem cole em código cliente que seja enviado ao navegador.
A autenticação é feita por bearer token no cabeçalho. O formato é sempre o mesmo:
Authorization: Bearer $HIAPI_API_KEY
Defina essa variável uma vez no shell e os exemplos abaixo poderão referenciá-la sem exibir a chave:
export HIAPI_API_KEY="your-key-here"
O que confirmar antes de começar
- A key está ativa e possui permissão de acesso à geração de imagens.
- Seu ambiente consegue fazer requisições HTTPS de saída para o endpoint HiAPI.
- Você sabe onde os arquivos gerados serão gravados — diretório local para testes, object storage em produção.
Se a key estiver ausente ou mal formatada, o problema se manifesta imediatamente na primeira chamada como erro de autenticação, que é o momento mais cedo e mais claro para detectá-lo.
Uma requisição curl mínima e executável
Comece pela menor requisição capaz de produzir uma imagem. Tudo além do prompt é opcional, e manter a primeira chamada enxuta significa que qualquer erro quase certamente estará relacionado à autenticação ou à estrutura da requisição, e não a conflitos de parâmetros.
curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/text-to-image@ext",
"prompt": "Uma bússola de latão desgastada sobre um mapa de papel dobrado, luz suave de janela, profundidade de campo rasa",
"size": "1024x1024",
"n": 1
}'
Explicação campo a campo
model— identificador do modelo. É o único valor que vincula a requisição agpt-image-2/text-to-image@ext; deve ser exato.prompt— descrição do conteúdo. Seja específico quanto a sujeito, estilo e iluminação; prompts vagos produzem imagens vagas e são mais difíceis de depurar do que erros de parâmetro.size— dimensões da saída. Pode ser omitido durante a validação do pipeline, aceitando o valor padrão.n— quantidade de imagens geradas por chamada. Mantenha em 1 durante a integração, para que uma falha corresponda exatamente a uma saída.
Grave a resposta em arquivo para inspecioná-la sem poluir o terminal com dados binários:
curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @payload.json -o response.json
Assim que ela retornar uma imagem, você terá uma linha de base comprovadamente funcional. Toda alteração posterior deve ser uma edição única e reversível em relação a ela.
Portar a requisição para Python
A versão em Python é a mesma requisição, apenas com outro meio de transporte. Use requests — é a escolha menos sujeita a surpresas e corresponde campo a campo ao curl que você já validou.
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
payload = {
"model": "gpt-image-2/text-to-image@ext",
"prompt": "Uma bússola de latão desgastada sobre um mapa de papel dobrado, luz suave de janela",
"size": "1024x1024",
"n": 1,
}
response = requests.post(
f"{BASE_URL}/v1/images/generations",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=120,
)
response.raise_for_status()
data = response.json()
Interpretação dos pontos-chave
json=payloaddefine o content type e serializa o corpo em uma única etapa — sem concatenação manual de strings, sem bugs de escape.timeoutnão é opcional na prática. A geração de imagens é mais lenta que uma chamada típica de API JSON; sem timeout, o worker fica travado quando o upstream desacelera.raise_for_status()transforma falhas HTTP em exceções que você pode capturar e classificar, em vez de deixar um corpo de resposta malformado seguir para o downstream.
Mantenha o payload como dict, e não como string inline. Quando adicionar parâmetros no futuro, você só acrescenta chaves — a estrutura da requisição não muda e você nunca precisa depurar novamente a camada de transporte.
Se você preferir um cliente no estilo SDK, o mesmo endpoint e os mesmos cabeçalhos continuam válidos; apenas a sintaxe da chamada muda. Valide primeiro com curl e depois adote o cliente já padronizado na sua aplicação.
Escolher entre chamada única e polling assíncrono
Esta é uma decisão de design, não de sintaxe, e afeta o tratamento de retentativas e o armazenamento mais do que qualquer outra escolha da integração.
Chamada única
Use um ciclo único de requisição-resposta quando:
- Você gera sob demanda e há um usuário aguardando.
- Sua camada HTTP tolera conexões longas.
- Você gera uma imagem por vez, e não em lote.
Defina o timeout com folga em relação ao tempo de geração mais lento que você observou e trate o timeout como falha retentável, não como erro definitivo.
Polling assíncrono
Escolha assíncrono em processamento em lote, quando a requisição vem de um worker de fila ou quando o chamador não pode bloquear. O padrão é: enviar, obter um handle e então consultar o status de conclusão.
import time
def poll_until_done(fetch_status, handle, interval=2, max_wait=300):
deadline = time.monotonic() + max_wait
while time.monotonic() < deadline:
status = fetch_status(handle)
if status["state"] == "succeeded":
return status
if status["state"] == "failed":
raise RuntimeError(status.get("error", "generation failed"))
time.sleep(interval)
raise TimeoutError("generation did not finish in time")
Regras para um loop de polling confiável
- Backoff. Comece com intervalo curto e aumente gradualmente; polling constante e apertado desperdiça cota e orçamento de rate limit.
- Limite a espera. Um prazo
max_waitevita que tarefas órfãs ocupem um worker indefinidamente. - Persista o handle. Se o worker reiniciar, você precisa poder retomar o polling em vez de reenviar e pagar por uma geração duplicada.
- Trate a falha como estado terminal por tarefa. O estado
faileddeve ser registrado, e não silenciosamente retentado em um loop apertado.
Decida cedo. Adaptar semântica assíncrona a um caminho de código síncrono depois significa reescrever ao mesmo tempo o chamador, o armazenamento e o tratamento de erros.
Tratar a saída da imagem
A resposta contém a imagem gerada, mas ela é um dado dentro de um envelope JSON — não uma URL pronta para hotlink. Trate-a como saída binária de sua propriedade.
Decodificar e persistir
import base64
item = data["data"][0]
image_bytes = base64.b64decode(item["b64_json"])
with open("out.png", "wb") as f:
f.write(image_bytes)
Se a resposta trouxer uma URL em vez de dados inline, busque-a imediatamente e grave os bytes no seu próprio armazenamento. As URLs geradas são temporárias; tudo o que você entrega ao usuário deve estar por trás da sua própria infraestrutura.
Valide antes de distribuir
- Verifique os magic bytes. PNG começa com
\x89PNG; uma página de erro HTML não. A checagem de alguns bytes detecta problemas de proxy que retornam HTTP 200 com corpo errado. - Registre o tamanho. Anote o comprimento em bytes para que downloads truncados apareçam no monitoramento.
- Armazenamento determinístico. Nomeie arquivos pelo ID de geração, não pelo texto do prompt, e guarde prompt, parâmetros e metadados da resposta junto com a imagem. Essa combinação permite reproduzir ou auditar qualquer saída no futuro.
- Defina o content type corretamente — derive-o do arquivo real, não de suposições.
Mantenha os metadados junto ao artefato
Crie um pequeno registro companheiro: identificador do modelo, prompt completo, dimensões e quantidade, timestamp e qualquer request ID presente na resposta. Seis meses depois, quando alguém perguntar por que esta imagem ficou assim, esse registro será sua única resposta.
Depurar falhas comuns
A maioria das falhas de primeira integração se enquadra em três categorias. Verifique nesta ordem — o custo de diagnóstico cresce aproximadamente do menor para o maior.
Erros de autenticação
401 ou 403 significa key errada, revogada ou não enviada. Exiba a construção do cabeçalho sem a chave para confirmar que o prefixo Bearer e o espaço estão intactos, e confirme que a variável de ambiente está realmente preenchida no processo que faz a requisição — a armadilha comum é tê-la definido no shell, mas não no worker ou container.
Corpo da requisição malformado
400 geralmente aponta para o corpo da requisição. Volte à requisição mínima da seção curl e acrescente os campos um a um. Suspeitos frequentes:
- A string de
modelnão corresponde exatamente agpt-image-2/text-to-image@ext. - O corpo não é JSON válido — vírgula sobrando ou aspas não escapadas.
- Tipo de parâmetro errado;
né número, não string. - Falta de
Content-Type: application/json, impedindo o servidor de interpretar o corpo.
Timeouts e respostas lentas
Se a conexão cai antes de a imagem retornar, provavelmente você excedeu o timeout do cliente, e não encontrou uma falha do modelo. Para o design de chamada única, aumente o timeout; para qualquer formato em lote, migre para polling assíncrono. Ao retentar, garanta que não haja geração duplicada: se a requisição pode ter tido sucesso, verifique se já existe um resultado antes de reenviar.
Quando nenhuma das anteriores se aplica
Capture a resposta completa da requisição que falhou — código de status, cabeçalhos e corpo — e reproduza com o comando curl mínimo. Uma falha que persiste com a requisição mínima é um problema de integração do seu ambiente; uma falha que desaparece aponta para os parâmetros que você adicionou.
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