HiAPI
Blogue

Tutorial

Como melhorar a resolução de imagens com a API da hiapi: um fluxo de trabalho de upscale para 4K

Uma solução imagem-para-imagem executável para upscale generativo em 2K/4K, com Python, callbacks e tratamento de erros.

Sep 8, 2026
Como melhorar a resolução de imagens com a API da hiapi: um fluxo de trabalho de upscale para 4K

Se você tem uma foto de produto em baixa resolução, uma pequena miniatura gerada por IA ou um documento antigo digitalizado e precisa de uma versão nítida em 2K/4K, não é necessário contratar um serviço dedicado de super-resolução. O endpoint unificado /v1/tasks da hiapi permite enviar a mesma requisição para vários modelos de imagem — modelos que aceitam uma imagem existente e a redesenham em uma faixa de resolução superior. Esta solução mostra o fluxo completo e executável: enviar a tarefa, fazer polling (ou receber um callback) para obter o resultado e, em seguida, baixar o arquivo ampliado.

Antes de tudo, uma verdade: a hiapi atualmente (ainda) não oferece um modelo dedicado de super-resolução que preserve os pixels. O que você tem aqui é upscale generativo — o modelo redesenha sua imagem de origem na resolução de destino mais alta, seguindo um prompt que exige manter a composição e adicionar detalhes. Para fotos e ilustrações, é geralmente isso que as pessoas querem dizer com "melhorar a resolução da imagem", mas não é interpolação sem perdas, então, se você precisa de escala de pixels exata, bit a bit, por exemplo em uma captura de tela com letras pequenas, não use isto.

O que você vai construir e o que precisa preparar antes

Você vai construir um pequeno script que:

  1. Envia uma referência para sua imagem existente (qualquer URL pública serve — seu próprio CDN, R2, S3 etc.)
  2. Envia uma tarefa imagem-para-imagem solicitando um redesenho em 4K
  3. Faz polling até a tarefa ser concluída e baixa o resultado em resolução mais alta

Antes de começar:

  • Uma conta hiapi e uma chave de API, criada na página API Keys do painel. Toda requisição abaixo exige Authorization: Bearer sk-<your-key> — sem a chave não é possível chamar esses endpoints.
  • Uma URL acessível publicamente apontando para a imagem que você quer ampliar. Os workers de tarefa da hiapi buscam a imagem no lado do servidor, então caminhos localhost ou buckets privados não funcionam — envie primeiro para qualquer host público.
  • Python 3.8+ com requests instalado (pip install requests), ou, se preferir testar no shell, basta usar curl.

Exemplo mínimo executável

A escolha mais limpa é seedream-5.0-lite/image-to-image. O schema de entrada dele exige exatamente quatro campos — prompt, image_urls, aspect_ratio e resolution — e resolution aceita apenas 2K ou 4K (não há faixa 1K nessa rota, o que justamente significa que você não vai reduzir sua imagem sem querer).

import time
import requests

API_KEY = "sk-your-hiapi-key"  # from https://www.hiapi.ai/en/dashboard/api-keys
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

def create_upscale_task(source_image_url: str) -> str:
    payload = {
        "model": "seedream-5.0-lite/image-to-image",
        "input": {
            "prompt": "Same image, preserved composition and colors, sharp fine detail, no artifacts",
            "image_urls": [source_image_url],
            "aspect_ratio": "1:1",   # match your source image's ratio
            "resolution": "4K",
        },
    }
    resp = requests.post(BASE, headers=HEADERS, json=payload, timeout=60)
    resp.raise_for_status()
    body = resp.json()
    task_id = body["data"]["taskId"]
    return task_id

def wait_for_result(task_id: str, timeout_s: int = 300, poll_every: int = 5) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        resp = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        task = resp.json()["data"]
        if task["status"] == "success":
            return task["output"][0]["url"]
        if task["status"] == "fail":
            err = task.get("error", {})
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(poll_every)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")

if __name__ == "__main__":
    task_id = create_upscale_task("https://your-cdn.example.com/product-photo-small.jpg")
    result_url = wait_for_result(task_id)
    print("4K result:", result_url)

Se você só quer ver como é a requisição, aqui está a chamada equivalente de criação de tarefa com curl:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-your-hiapi-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-lite/image-to-image",
    "input": {
      "prompt": "Same image, preserved composition and colors, sharp fine detail, no artifacts",
      "image_urls": ["https://your-cdn.example.com/product-photo-small.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "4K"
    }
  }'

Sobre essa requisição, alguns pontos merecem destaque:

  • image_urls é um array, mesmo que este modelo leia apenas o primeiro elemento. Passar uma string simples em vez de uma lista é uma causa comum de erro 400.
  • A URL de saída expira. Assim que wait_for_result() retornar, baixe os bytes imediatamente e armazene por conta própria — não trate o link hospedado pela hiapi como a URL permanente do seu recurso.
  • Se a imagem de origem não for quadrada, defina aspect_ratio para corresponder a ela (4:3, 16:9, 9:16, 3:2, 2:3 ou 21:9), para que o modelo não corte nem preencha o seu objeto principal.

Como fazer em produção

Em escala, prefira callbacks a polling. Se você tem mais do que algumas imagens para ampliar, não faça um loop martelando GET /v1/tasks/<id> para cada tarefa — envie um objeto callback e deixe a hiapi enviar o resultado para você:

payload = {
    "model": "seedream-5.0-lite/image-to-image",
    "input": {...},
    "callback": {
        "url": "https://your-service.example.com/hooks/hiapi-task",
        "when": "final",
    },
}

Seu webhook receberá o mesmo objeto de tarefa do polling (status, output, error) — valide sua estrutura de forma defensiva, porque novas tentativas de rede podem entregá-lo mais de uma vez.

Prepare do seu lado uma chave propícia à idempotência para cada tarefa. A API de tarefas atualmente não aceita uma chave de idempotência fornecida pelo cliente, então, se o seu executor de tarefas pode repetir chamadas HTTP com falha, verifique se já existe um taskId armazenado para aquela imagem de origem antes de enviar uma tarefa duplicada — caso contrário, um breve timeout do seu lado pode se transformar em duas cobranças pelo upscale do mesmo arquivo.

Trate duas formas bem distintas de erro. Um corpo de requisição malformado retorna HTTP 400 com um {"code": 400, "error_code": "INVALID_REQUEST", "message": "..."} plano. Uma chave de API ausente ou incorreta retorna HTTP 401 com um {"error": {"code": "permission_denied", "message": "..."}} aninhado. Verifique primeiro o código de status e depois ramifique o tratamento:

if resp.status_code == 401:
    raise RuntimeError(f"auth error: {resp.json()['error']['message']}")
if resp.status_code == 400:
    raise RuntimeError(f"bad request: {resp.json()['message']}")
resp.raise_for_status()

Escolha o modelo conforme a entrada que você tem. As três rotas abaixo ficam no mesmo endpoint /v1/tasks — só mudam a string model e os campos de input:

O que você tem Modelo Campos de entrada obrigatórios
Uma imagem existente e quer um redesenho limpo em 2K/4K seedream-5.0-lite/image-to-image prompt, image_urls, aspect_ratio, resolution (2K|4K)
Uma imagem existente e quer equilibrar qualidade e custo gpt-image-2/image-to-image@ext prompt, image_urls, quality (low|medium|high), resolution (1K|2K|4K)
Nenhuma imagem de origem — gerar um recurso novo em alta resolução a partir de uma descrição textual wan2.7-image/text-to-image prompt (e, opcionalmente, resolution e aspect_ratio)

Observe o sufixo @ext na segunda linha — é uma variante de rota sobre o modelo base gpt-image-2 (a hiapi disponibiliza alguns modelos sob mais de uma rota, com faixas de preço/qualidade ligeiramente diferentes), e não uma família de modelos separada. O custo exato por requisição de cada um deles depende da faixa de resolução e qualidade escolhida, então consulte os números atualizados na página de preços em vez de fixar valores na sua lógica de orçamento.

Valide antes de enviar. Os três modelos rejeitam campos de entrada desconhecidos (additional properties 'x' not allowed) em vez de ignorá-los silenciosamente, e campos de enumeração como resolution e aspect_ratio diferenciam maiúsculas de minúsculas e são sensíveis aos valores. Se você estiver construindo uma camada de encapsulamento, valide no cliente usando os valores exatos de enumeração acima, para que erros de digitação falhem rápido em vez de consumir uma requisição em vão.

Leitura relacionada

Perguntas frequentes

A hiapi tem um modelo dedicado de ampliação de imagem ou super-resolução? Não há um modelo dedicado que preserve os pixels. O fluxo de trabalho acima usa modelos genéricos de imagem-para-imagem para regenerar sua imagem em uma faixa de resolução superior, o que funciona bem para fotos e ilustrações, mas não é ampliação sem perdas.

Posso melhorar a resolução sem alterar o conteúdo da imagem? Você consegue chegar bem perto instruindo o modelo a manter exatamente a composição, as cores e o objeto principal ("a mesma imagem, não altere a composição, não adicione nem remova elementos, apenas aumente os detalhes e a nitidez"), mas, como é um redesenho generativo e não interpolação, ainda haverá diferenças sutis em texturas finas em comparação com um ampliador verdadeiramente sem perdas.

Qual é a resolução máxima que posso gerar? O limite dos três modelos acima é a faixa de resolução 4K. Se você precisar de dimensões maiores que isso, será necessário dividir a imagem de origem em blocos, ampliar cada bloco separadamente, ou adicionar uma etapa de redimensionamento no cliente após a chamada da API.

Preciso de uma chave de API para testar isto? Sim — toda chamada /v1/tasks exige Authorization: Bearer sk-<your-key>. Não há sandbox sem chave para criar tarefas; obtenha primeiro uma chave no painel.

Posso ampliar uma pasta inteira de imagens em lote? Sim — percorra as URLs das suas imagens, envie uma tarefa por imagem e depois faça polling de cada taskId ou (melhor em grande volume) registre uma URL de callback que associe os resultados de volta às suas tarefas usando o taskId armazenado no momento da criação de cada tarefa.

Por que minha requisição falha com "additional properties not allowed"? Você enviou um campo que o schema do modelo não reconhece — por exemplo, usando size em vez de resolution + aspect_ratio, ou copiando um parâmetro extra dos exemplos de outro modelo. Consulte a tabela de campos obrigatórios acima para os nomes exatos de campos aceitos por cada modelo.

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