HiAPI
Blogue

Tutorial

Como usar seedream-4.5/image-to-image através da API hiapi: curl, Python e requisições disponíveis

Jul 10, 2026
Como usar seedream-4.5/image-to-image através da API hiapi: curl, Python e requisições disponíveis

Para editar imagens com o seedream-4.5, basta enviar um POST para a API de tarefas unificada da hiapi, fazer uma breve consulta de status (polling) e então baixar o resultado. Este guia traz requisições curl funcionais e um script Python completo para o seedream-4.5/image-to-image, além de uma descrição precisa dos campos de entrada (verificada contra a API em produção), uso com múltiplas imagens de referência e os erros que você realmente vai encontrar.

O que você vai construir e o que precisa

Objetivo: enviar uma ou mais imagens de origem junto com uma instrução de edição para seedream-4.5/image-to-image e obter de volta a URL da imagem finalizada.

Pré-requisitos:

  • Uma chave de API hiapi — obtenha no seu console. Todas as requisições abaixo a utilizam como token Bearer.
  • As imagens de origem hospedadas em URLs acessíveis publicamente. A API as busca no lado do servidor; caminhos de arquivo locais ou URLs privadas não funcionam.

O modelo roda em um endpoint de tarefas assíncronas: POST /v1/tasks cria a tarefa, GET /v1/tasks/<taskId> informa o status, e a imagem finalizada aparece em data.output[0].url.

Descrição dos campos de entrada (verificada)

seedream-4.5/image-to-image tem quatro campos de entrada obrigatórios e não aceita nenhum outro — a especificação é estrita e campos desconhecidos são rejeitados com 400:

Campo Tipo Restrição
prompt string Instrução de edição
image_urls array de strings URLs públicas, até 14 imagens
aspect_ratio string Um de 1:1, 4:3, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9
resolution string Apenas 2K ou 4K

Dois pontos merecem atenção: não existe parâmetro n (uma saída por tarefa — para múltiplas variantes, crie várias tarefas em paralelo); e, ao contrário do image-to-image do seedream-5.0-pro (que aceita 1K/2K), o 4.5 exige 2K ou 4K. Enviar 1K aqui retorna erro de validação.

Requisição mínima funcional: curl

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-4.5/image-to-image",
    "input": {
      "prompt": "Turn this product shot into a clean studio photo on a seamless white background with soft shadows",
      "image_urls": ["https://your-cdn.example.com/source.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2K"
    }
  }'

Uma criação bem-sucedida retorna o ID da tarefa em data.taskId. Consulte-a:

curl -s https://api.hiapi.ai/v1/tasks/<taskId> \
  -H "Authorization: Bearer sk-<your-key>"

Quando data.status chega a success, a URL da imagem está em data.output[0].url. Se for fail, o motivo está em data.error.

Script Python completo

Não é necessário SDK — apenas requests e um loop de polling:

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def edit_image(prompt: str, image_urls: list[str],
               aspect_ratio: str = "1:1", resolution: str = "2K") -> bytes:
    # 1. Create the task
    resp = requests.post(API_BASE, headers=HEADERS, json={
        "model": "seedream-4.5/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # public URLs, max 14
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,   # "2K" or "4K"
        },
    }, timeout=60)
    resp.raise_for_status()
    task_id = resp.json()["data"]["taskId"]

    # 2. Poll until terminal state
    deadline = time.time() + 600
    while time.time() < deadline:
        task = requests.get(f"{API_BASE}/{task_id}",
                            headers=HEADERS, timeout=30).json()["data"]
        if task["status"] == "success":
            url = task["output"][0]["url"]
            # 3. Output URLs expire -- download immediately
            return requests.get(url, timeout=120).content
        if task["status"] == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(5)
    raise TimeoutError(f"task {task_id} did not finish in 600s")

png = edit_image(
    "Turn this product shot into a clean studio photo on a seamless white background",
    ["https://your-cdn.example.com/source.jpg"],
)
with open("edited.png", "wb") as f:
    f.write(png)

Observe o comentário do passo 3: a URL de saída carrega um timestamp de expiração. Assim que a tarefa for concluída, persista os bytes no seu próprio armazenamento imediatamente — não guarde apenas a URL retornada e conte com ela ainda funcionando amanhã.

Edição com múltiplas imagens de referência

image_urls aceita até 14 imagens em uma única tarefa. Isso é ótimo para tarefas de transferência de estilo e composição: passe a imagem que você quer editar junto com as imagens de referência e descreva no prompt como combiná-las.

{
  "model": "seedream-4.5/image-to-image",
  "input": {
    "prompt": "Apply the color grading and lighting style of the second image to the first image, keep the subject unchanged",
    "image_urls": [
      "https://your-cdn.example.com/subject.jpg",
      "https://your-cdn.example.com/style-reference.jpg"
    ],
    "aspect_ratio": "3:2",
    "resolution": "2K"
  }
}

A ordem importa para o prompt, não para a API — refira-se às imagens por posição ("a primeira imagem", "a segunda imagem") para que o modelo saiba qual é qual.

Considerações para produção

Use callback em vez de polling. Para qualquer cenário além de scripts, adicione um objeto callback de nível raiz ao criar a tarefa e pule completamente o loop de polling:

{
  "model": "seedream-4.5/image-to-image",
  "input": { "...": "..." },
  "callback": { "url": "https://yourapp.com/hooks/hiapi", "when": "final" }
}

Quando a tarefa terminar, a hiapi enviará o estado final da tarefa por POST para a sua URL. O polling é adequado para ferramentas CLI e notebooks; para backends Web, o callback é a escolha correta, caso contrário você manterá um worker ocupado pelas dezenas de segundos necessárias para uma edição em 2K.

Idempotência. A criação de tarefas não é idempotente — repetir a criação após um timeout de rede pode gerar (e cobrar) duas tarefas. Armazene o taskId no momento em que o receber e, ao repetir, verifique primeiro se já existe uma tarefa ativa antes de criar uma nova.

Tratamento de erros. Os dois primeiros tipos de falha que você vai encontrar:

  • 401 permission_denied — chave incorreta, ou a chave não tem acesso a este modelo. O corpo da resposta é parecido com {"error": {"code": "permission_denied", "message": "This API key cannot use the selected model...", "request_id": "..."}}. Inclua o request_id ao contatar o suporte.
  • 400 INVALID_REQUEST — violação da especificação de campos, com mensagem precisa: valor incorreto de resolution, mais de 14 itens em image_urls, campo desconhecido ou image_urls que não é um array. Esses são capturados antes da execução da tarefa, portanto não geram custo.

Tarefas com falha reportam status: "fail" na própria tarefa, junto com um objeto error — trate isso como um caso diferente dos erros HTTP, como faz o script Python acima.

Preços

O custo por imagem depende da resolução. Consulte as tarifas atuais na página de preços. Requisições rejeitadas na fase de validação (400) nunca iniciam uma tarefa, então erros de especificação de campos durante a integração não têm custo.

Leitura relacionada

Perguntas frequentes

Posso enviar um arquivo local ou uma imagem base64 em vez de uma URL? Não. image_urls deve ser um array de URLs acessíveis publicamente — a plataforma as busca e normaliza no lado do servidor. Faça upload para o seu próprio armazenamento (S3, R2, qualquer CDN) primeiro e então passe a URL.

Quantas imagens de referência o seedream-4.5 image-to-image suporta? Até 14 por tarefa. Exceder retorna 400 com uma mensagem contendo image_urls: maxItems.

Por que recebo 400 quando defino resolution como 1K? O endpoint 4.5 image-to-image aceita apenas 2K ou 4K. A opção 1K pertence ao image-to-image do seedream-5.0-pro — famílias de camadas diferentes têm enums diferentes.

Posso gerar múltiplas variantes em uma única requisição? Não — a especificação de campos não tem parâmetro n e rejeita campos desconhecidos. Crie uma tarefa para cada variante e execute-as em paralelo; cada tarefa retorna apenas uma saída.

Quanto tempo a URL do resultado fica válida? As URLs de saída têm assinatura e tempo de expiração. Baixe a imagem e armazene-a você mesmo logo após a conclusão da tarefa, em vez de fazer hotlink da saída da tarefa.

Qual é a diferença entre um erro HTTP e uma tarefa com falha? Erros HTTP (400/401) significam que a requisição nunca se tornou uma tarefa — corrija o payload ou a chave e reenvie. Uma tarefa que termina com status: "fail" foi aceita mas não pôde ser concluída; o motivo está no objeto error da tarefa e, para falhas transitórias, repetir com as mesmas entradas geralmente é a atitude correta.

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