Tutorial
Como usar seedream-5.0-lite de imagem para imagem via API hiapi
Este tutorial mostrará como chamar o modo de imagem para imagem do seedream-5.0-lite pela API de tarefas unificada da hiapi: a estrutura exata da requisição, comandos curl prontos para executar, um script Python que pode ser colocado no backend e as armadilhas de validação que este modelo impõe e que outros modelos não impõem.
Ao terminar de ler este artigo, você terá um script que recebe uma ou mais URLs de imagens de referência e um prompt de edição, e retorna uma URL de imagem gerada pronta para download imediato.
O que você precisa preparar
- Uma conta hiapi e uma API key. Você pode obtê-las no console hiapi.
- Uma ou mais imagens de referência hospedadas em URLs HTTPS públicas. O modelo aceita no máximo 14 imagens de referência por requisição, e é justamente isso que o torna útil para fluxos com múltiplas referências: combinar o sujeito de uma imagem com o estilo ou a cena de outra.
- Um prompt de texto descrevendo a edição ou transformação (mínimo de 3 caracteres — sim, a API valida isso).
Todas as requisições vão para o endpoint unificado de tarefas, com a chave no cabeçalho Authorization:
POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json
Estrutura da requisição (e os requisitos deste modelo)
O id do modelo é seedream-5.0-lite/image-to-image — passe exatamente como está, idêntico ao listado em /v1/models. O schema do seu input é rígido: os quatro campos são todos obrigatórios:
| Campo | Tipo | Descrição |
|---|---|---|
prompt |
string | Instrução de edição. Comprimento mínimo 3. |
image_urls |
string[] | 1–14 URLs de imagens de referência. |
aspect_ratio |
string | Valor entre 1:1, 4:3, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9. |
resolution |
string | Apenas 2K ou 4K. Este modelo não possui opção 1K. |
Quem migra de outros modelos da plataforma costuma cair em duas armadilhas:
resolutionaceita apenas2Kou4K. Se o seu código de envio de tarefas compartilhado envia"1K"por padrão (o que funciona em muitos outros modelos de imagem), este modelo rejeita com 400.- Campos extras são rejeitados, não ignorados. Enviar
size,nou qualquer coisa fora do schema retorna400 INVALID_REQUESTcomadditional properties '<field>' not allowed. A API de tarefas valida oinputpor modelo — não reutilize cegamente o payload de outro modelo.
Exemplo mínimo executável: curl
Criar uma tarefa:
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5.0-lite/image-to-image",
"input": {
"prompt": "Replace the background with a sunlit Tokyo street at golden hour, keep the subject unchanged",
"image_urls": ["https://your-cdn.example.com/subject.png"],
"aspect_ratio": "3:2",
"resolution": "2K"
}
}'
Após o envio bem-sucedido, um id de tarefa é retornado em data:
{"code": 200, "data": {"taskId": "task_abc123..."}}
Consultar o resultado:
curl https://api.hiapi.ai/v1/tasks/task_abc123 \
-H "Authorization: Bearer sk-<your-key>"
Durante a execução, data.status fica pending/processing. Ao concluir, passa para "success" e a imagem aparece em data.output:
{
"code": 200,
"data": {
"status": "success",
"output": [{"url": "https://.../result.png", "expireAt": "..."}]
}
}
A URL de saída tem validade curta (observe o expireAt). Baixe os bytes imediatamente e armazene por conta própria — não faça hotlink nem persista a URL original.
Múltiplas referências: passar várias imagens
Para combinar várias imagens de referência — por exemplo, uma imagem de produto mais uma imagem de referência de estilo — basta adicionar mais URLs em image_urls e explicar no prompt o que cada imagem contribui:
{
"model": "seedream-5.0-lite/image-to-image",
"input": {
"prompt": "Place the product from the first image into the scene from the second image, matching its lighting and color grade",
"image_urls": [
"https://your-cdn.example.com/product.png",
"https://your-cdn.example.com/scene-reference.jpg"
],
"aspect_ratio": "1:1",
"resolution": "2K"
}
}
O limite rígido é de 14 URLs; a 15ª retorna 400 INVALID_REQUEST: image_urls: maxItems: got 15, want 14. Na prática, 2–4 imagens de referência bem escolhidas, com um prompt que atribui explicitamente um papel a cada imagem ("mantenha o sujeito da imagem 1, use a paleta de cores da imagem 2"), resultam em edições muito mais controláveis do que um monte de imagens vagamente relacionadas.
Para edições precisas e pontuais em uma única imagem — trocar o fundo, alterar a roupa, remover um objeto — use uma única URL de referência e especifique ao mesmo tempo o que deve ser alterado e o que deve ser preservado ("mantenha o rosto e a pose inalterados"). Os modelos Seedream seguem bem instruções de preservação, e ser explícito é justamente o que separa uma edição precisa de uma reinterpretação completa.
Python pronto para produção: enviar, consultar, baixar
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-5.0-lite/image-to-image",
"input": {
"prompt": prompt,
"image_urls": image_urls,
"aspect_ratio": aspect_ratio,
"resolution": resolution, # this model: "2K" or "4K" only
},
}, timeout=60)
body = resp.json()
if resp.status_code != 200 or not (body.get("data") or {}).get("taskId"):
raise RuntimeError(f"create failed [{resp.status_code}]: {body}")
task_id = body["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().get("data") or {}
if task.get("status") == "success":
outputs = task.get("output") or []
if not outputs or not outputs[0].get("url"):
raise RuntimeError(f"task {task_id} succeeded but returned no output URL")
# 3. Download immediately — the URL expires
img = requests.get(outputs[0]["url"], timeout=120)
img.raise_for_status()
return img.content
if task.get("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} still running after 600s")
if __name__ == "__main__":
png = edit_image(
"Replace the background with a minimalist studio backdrop, keep the subject unchanged",
["https://your-cdn.example.com/subject.png"],
aspect_ratio="3:2",
)
with open("edited.png", "wb") as f:
f.write(png)
print(f"saved edited.png ({len(png)} bytes)")
Usar callback em vez de polling
O polling funciona bem para scripts e filas de workers. Para um backend web, registre um callback ao criar a tarefa e deixe a hiapi enviar o estado final para você — o objeto callback fica no nível superior da requisição, ao lado de model:
{
"model": "seedream-5.0-lite/image-to-image",
"input": { "...": "..." },
"callback": {
"url": "https://your-app.example.com/hooks/hiapi",
"when": "final"
}
}
Com "when": "final", você recebe um único POST quando a tarefa entra em success ou fail. Duas regras para o handler:
- Torne-o idempotente. Use o id da tarefa como chave de processamento, para que webhooks entregues em duplicidade não causem processamento duplicado. Armazene o id da tarefa no momento do envio e trate o callback como uma notificação de "vá buscar e conclua", não como fonte única da verdade.
- Mantenha um caminho de reconciliação. Se o seu endpoint estiver fora do ar quando o callback disparar, varrer periodicamente os ids não concluídos e fazer GET em
/v1/tasks/<id>captura as perdas.
Se o seu callback parecer nunca chegar, verifique os modos de falha comuns em ordem de probabilidade no artigo por que o callback da sua tarefa hiapi não está disparando.
Tratamento de erros: três falhas que realmente importam
401 permission_denied na criação — sua chave não pode usar este modelo. O corpo da resposta é semelhante a:
{"error": {"code": "permission_denied", "message": "This API key cannot use the selected model...", "type": "hiapi_error"}}
Verifique as permissões de modelo da chave no console, ou use uma chave com modelos de imagem habilitados.
400 INVALID_REQUEST na criação — seu input não corresponde ao schema do modelo. A mensagem lista todos os campos infratores de uma vez (por exemplo, resolution: value must be one of '2K', '4K'; <root>: additional properties 'size' not allowed), então leia tudo e corrija todos os campos de uma vez. São erros permanentes — repetir o mesmo payload falhará para sempre.
status: "fail" na tarefa — a criação foi bem-sucedida, mas a geração falhou (URL de referência inacessível pelo backend, política de conteúdo, capacidade do upstream). O error.code e o error.message da tarefa explicam o motivo. Diferentemente do 400, algumas destas falhas são temporárias e merecem uma nova tentativa com backoff.
Também vale saber: um GET em um id de tarefa inexistente ou expirado retorna 404 task not found — em varreduras de reconciliação, trate isso como estado final, e não como "ainda em espera".
Para onde ir agora
- Página do modelo seedream-5.0-lite/image-to-image — playground e cobrança por imagem.
- Preços da hiapi — tarifas atuais de todos os modelos de imagem.
- Melhores APIs de imagem para imagem de 2026 — comparação entre seedream e gpt-image-2 etc. na mesma tarefa de edição.
- Tutorial de imagem para imagem do gpt-image-2 — mesma API de tarefas, schema de input diferente; uma boa demonstração de por que payloads não são intercambiáveis entre modelos.
- Documentação da hiapi — referência completa da API de tarefas.
FAQ
Quantas imagens de referência posso enviar para o seedream-5.0-lite de imagem para imagem?
O array image_urls aceita no máximo 14. No mínimo uma — o campo é obrigatório, então chamadas puras de texto para imagem devem usar seedream-5.0-lite/text-to-image.
Por que outros modelos aceitam 1K, mas eu recebo "value must be one of '2K', '4K'"? O schema de input da API de tarefas é definido por modelo. O modo de imagem para imagem do seedream-5.0-lite oferece apenas saídas 2K e 4K; outros modelos oferecem a opção 1K. Não reutilize o payload de outro modelo sem verificar.
Posso enviar imagens de referência em base64 em vez de URL?
O schema deste modelo aceita image_urls — um array de URLs. Hospede as imagens em URLs HTTPS acessíveis (qualquer CDN, bucket de object storage ou URL pré-assinada serve) e passe essa URL.
Quanto tempo leva uma geração e por quanto tempo a URL de saída é válida?
Normalmente bem menos que o orçamento de polling de 600 segundos do exemplo Python acima. A URL de saída traz um timestamp expireAt — baixe os bytes imediatamente após o sucesso da tarefa e armazene no seu próprio storage.
O mesmo código serve para o seedream-5.0-lite de texto para imagem?
O endpoint e o fluxo são os mesmos, mas texto para imagem tem seu próprio schema de input (sem image_urls). Troque o id do modelo para seedream-5.0-lite/text-to-image e remova as imagens de referência — depois valide com uma chamada de teste, porque os campos obrigatórios variam entre os modos.
Quanto custa cada imagem? A cobrança é por uso a cada geração e varia conforme a resolução. Consulte as tarifas em tempo real na página de preços.
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