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
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
succeededefailedcomo 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 →-
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