HiAPI
Blogue

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

Oct 31, 2026
黑绿底上,黄铜色与深绿色扁平缎带以经纬交织方式构成开放式网格,这是教程文章的封面图。

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 a gpt-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=payload define o content type e serializa o corpo em uma única etapa — sem concatenação manual de strings, sem bugs de escape.
  • timeout nã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_wait evita 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 failed deve 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 model não corresponde exatamente a gpt-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 →

Comece a criar com artefactos de IA persistentes

Obtenha a sua chave de API e chame modelos de imagem, vídeo e áudio através de uma única API baseada em tasks.

Ler a documentação da API