HiAPI
Blogue

Tutorial

Como chamar gpt-image-2/image-to-image na HiAPI: curl, Python e uma requisição que funciona

Guia prático de requisições de imagem para imagem para desenvolvedores: enviar imagem de referência, consultar a tarefa e baixar o resultado

Oct 31, 2026
扁平流体形态交叠的封面图,墨黑底色上浮现青瓷绿与石板灰的克制波纹,呼应教程文章。

O que o endpoint image-to-image espera

O modelo gpt-image-2/image-to-image na HiAPI é um endpoint de geração de imagem assíncrono. Diferente de chamadas síncronas que bloqueiam até a imagem retornar, este endpoint recebe sua requisição, coloca na fila e retorna um identificador de tarefa. Depois você precisa acompanhar a tarefa até que ela seja concluída.

No nível da requisição, você precisa fornecer três coisas:

  • ID do modelo: gpt-image-2/image-to-image.
  • Uma imagem de referência: a imagem de origem com base na qual o modelo deve transformar ou construir. Este é o input decisivo do modo imagem para imagem — sem ela, você está fazendo texto para imagem.
  • Prompt e opções: uma instrução de texto descrevendo a saída desejada, além dos campos opcionais listados na documentação do modelo (por exemplo, tamanho ou formato de saída). Envie apenas os parâmetros listados na documentação do modelo.

A resposta não é a imagem em si, mas um objeto de tarefa contendo um identificador e um status. Trate esse status como a única fonte de verdade: pending ou processing significa continuar aguardando, succeeded significa que o resultado está pronto, failed significa que algo deu errado e você deve parar de consultar.

Projete seu cliente em torno desse ciclo de vida desde o início. Todo o resto neste tutorial — curl, Python, consulta, download — baseia-se no fato de que "envio e conclusão são dois momentos separados".

Prepare sua chave da HiAPI e a imagem de referência

Antes de escrever qualquer código, prepare duas coisas.

Uma chave de API. Crie uma no console da HiAPI e armazene-a em uma variável de ambiente, em vez de colá-la diretamente no script:

export HIAPI_API_KEY="your-key-here"

Trate a chave como confidencial. Não faça commit no repositório e não a registre em logs de requisição.

Uma imagem de referência. Escolha um arquivo de imagem local que você deseja transformar. Mantenha um tamanho razoável — imagens de origem muito grandes e de alta resolução são a causa mais comum de requisições lentas ou rejeitadas. Coloque o PNG ou JPEG no mesmo diretório do script para a primeira execução ser mais simples:

ls -lh ./reference.png

Anote o caminho do arquivo; você vai referenciá-lo tanto no exemplo curl quanto no Python. Se pretender chamar o modelo a partir de um servidor, confirme que o processo tem permissão de leitura para esse caminho e que o arquivo é uma imagem válida (não um arquivo renomeado com extensão errada).

Com a chave exportada e a imagem em disco, tudo o que você precisa para a primeira requisição está pronto.

Uma requisição curl que funciona

A maneira mais rápida de validar credenciais e a estrutura do corpo da requisição é fazer uma chamada curl. Ela envia a tarefa e imprime o objeto de tarefa:

curl -sS https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/image-to-image",
    "input": {
      "image": "https://example.com/reference.png",
      "prompt": "Turn this photo into a watercolor illustration"
    }
  }'

Duas observações sobre este exemplo. Primeiro, a imagem de referência é passada como URL pelo campo input.image; se a documentação do endpoint suportar base64 inline ou upload multipart para o seu caso, use esse formato, mas mantenha os nomes dos campos consistentes. Segundo, o prompt é onde você descreve a transformação — seja específico sobre estilo, composição e o que deve permanecer inalterado.

Execute e leia a resposta. Um envio bem-sucedido retorna um ID de tarefa e um status não terminal. Se receber 401, sua chave está ausente ou incorreta. Se receber 422 ou um erro de validação semelhante, verifique o corpo da requisição — geralmente é o ID do modelo ou o formato do campo image que está errado.

Salve o ID da tarefa. As etapas seguintes dependem dele.

Faça o mesmo com Python

A versão Python deve corresponder exatamente à chamada curl, mantendo autenticação e construção do corpo explícitas, para que nada fique oculto por uma camada de abstração. Use requests:

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = "https://api.hiapi.ai/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

payload = {
    "model": "gpt-image-2/image-to-image",
    "input": {
        "image": "https://example.com/reference.png",
        "prompt": "Turn this photo into a watercolor illustration",
    },
}

response = requests.post(f"{BASE_URL}/tasks", json=payload, headers=headers, timeout=30)
response.raise_for_status()
task = response.json()
print(task["id"], task["status"])

Se sua integração enviar um arquivo local em vez de uma URL, codifique e anexe a imagem conforme a documentação do endpoint, em vez de inventar campos. A disciplina é a mesma do curl: construa o corpo da requisição como um dicionário simples, envie, e verifique o status HTTP antes de fazer o parsing.

Encapsule a lógica de envio em uma função que retorna o ID da tarefa. Assim, o código de consulta da próxima seção fica independente de como a tarefa foi criada.

Consulte a tarefa assíncrona até a conclusão

A chamada de envio retorna enquanto a imagem ainda está sendo gerada. Para obter o resultado, consulte o endpoint de status da tarefa até que ela atinja um estado terminal. Um loop robusto tem três características: intervalo entre consultas, tempo máximo de espera e tratamento explícito de estados de falha.

import time

def wait_for_task(task_id, headers, base_url, timeout=300, interval=3):
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.get(f"{base_url}/tasks/{task_id}", headers=headers, timeout=30)
        r.raise_for_status()
        task = r.json()
        status = task["status"]
        if status == "succeeded":
            return task
        if status == "failed":
            raise RuntimeError(f"Task failed: {task}")
        time.sleep(interval)
    raise TimeoutError(f"Task {task_id} did not finish within {timeout}s")

Algumas melhorias práticas:

  • Backoff: comece com um intervalo curto e aumente gradualmente, ou mantenha um intervalo fixo suficientemente largo para não sobrecarregar a API. A geração de imagens não é instantânea.
  • Timeout: sempre limite o tempo total de espera. Caso contrário, uma tarefa travada deixará seu worker pendurado indefinidamente.
  • Estados terminais: considere apenas succeeded e failed como terminais. Qualquer outro status significa continuar consultando. Se a API adicionar novos estados intermediários no futuro, seu loop continuará funcionando corretamente.

Se você executar muitos trabalhos, faça a consulta em um worker em segundo plano ou fila, em vez de bloquear uma requisição web. O ciclo de vida é o mesmo, apenas o modelo de concorrência muda.

Baixe e valide o resultado

Quando a tarefa reportar sucesso, o objeto de tarefa conterá a localização da imagem gerada — normalmente uma URL em um campo de saída. Baixe-a e grave em disco:

task = wait_for_task(task_id, headers, BASE_URL)
image_url = task["output"]["image"]

img = requests.get(image_url, timeout=60)
img.raise_for_status()

with open("result.png", "wb") as f:
    f.write(img.content)

Se a URL assinada tiver validade, baixe imediatamente após a conclusão ou persista o arquivo diretamente, em vez de guardar a URL para usar depois. Se o endpoint retornar base64 em vez de URL, decodifique antes de gravar.

Uma verificação rápida de integridade evita falhas confusas em etapas posteriores:

from PIL import Image

with Image.open("result.png") as im:
    im.verify()
print("valid image, bytes:", os.path.getsize("result.png"))

Se o arquivo não for uma imagem decodificável, verify() lançará uma exceção, o que detecta downloads truncados e páginas de erro salvas como imagem. Verificar o tamanho em bytes também informa se a resposta faz sentido. Com isso, o ciclo está completo: enviar, consultar, baixar, validar.

Solução de problemas comuns

A maioria das primeiras integrações falha de algumas maneiras previsíveis. Diagnostique na seguinte ordem.

Erros de autenticação (401/403). Chave ausente, formato incorreto ou permissão insuficiente. Confirme que a variável de ambiente foi exportada no shell ou processo que executa a requisição e que o cabeçalho Authorization usa o prefixo exato esperado pela API.

Imagem de referência inválida ou muito grande (400/422). A URL da imagem pode estar inacessível do lado da API, o arquivo pode estar corrompido, ou as dimensões e o tamanho do arquivo podem exceder os limites. Teste primeiro com um PNG pequeno e comprovadamente válido. Se enviar uma URL, garanta que ela seja publicamente acessível; se enviar dados inline, confirme que a codificação está correta.

Timeout na consulta. Se a tarefa continuar atingindo seu timeout, aumente o limite, amplie o intervalo ou verifique se a tarefa já falhou e você está apenas sem exibir o motivo. Registre o último objeto de tarefa antes de lançar a exceção, para poder inspecionar o status.

Limite de taxa (429). Faça backoff com jitter e tente novamente, em vez de repetir imediatamente. Se você enviar muitos trabalhos em paralelo, limite a concorrência para evitar que picos de tráfego disparem o limite, e registre o ID da tarefa para tornar as tentativas idempotentes.

Para qualquer categoria de erro, registre o status HTTP, o corpo da resposta truncado e o ID da tarefa — esses três geralmente bastam para determinar se o problema está na autenticação, no corpo da requisição ou no timing. Use o exemplo curl primeiro para isolar se o problema está no seu código ou no input, e depois leve a correção de volta ao Python.

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