HiAPI
Blogue

Tutorial

Como usar a API Recraft Creative Upscale: curl, Python e uma execução real

Um campo image_url, entrada de 1254 px volta a 4096 px, e o que a tarefa realmente retornou.

Oct 23, 2026
Como usar a API Recraft Creative Upscale: curl, Python e uma execução real

TL;DR

  • recraft/creative-upscale amplia a imagem e redesenha sua textura e detalhes. O corpo da requisição tem apenas um campo: image_url. Sem prompt e sem configurações de escala.
  • Ele segue o fluxo unificado /v1/tasks: POST para obter o taskId, polling em GET /v1/tasks/<taskId>, e download a partir de data.output[0].url.
  • Na nossa execução, um PNG de 1254×1254 retornou após cerca de 60 segundos como WebP de 4096×4096, com aproximadamente 19,8 MB. Planeje o tempo de espera e o tamanho do arquivo.

O que você precisa preparar

Obtenha uma API key hiapi no console e uma URL de imagem publicamente acessível. A página do modelo lista os limites de entrada: PNG recomendado, máximo de 20 MB, 256–4096 px por lado, máximo de 16 MP.

Se você precisa que texto, logos ou detalhes de produto permaneçam intactos, use Recraft Crisp Upscale. O Creative Upscale redesenha, portanto elementos pequenos podem mudar.

Requisição curl mínima

export HIAPI_KEY=sk-your-key

curl -s https://www.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "recraft/creative-upscale",
    "input": { "image_url": "https://example.com/old-illustration.png" }
  }'

A resposta é um identificador de tarefa:

{"code":200,"data":{"taskId":"tk-hiapi-01M5K8J899THH6XJK99TAZ4VSD"},"message":"success"}

Faça polling até que data.status seja success:

curl -s https://www.hiapi.ai/v1/tasks/tk-hiapi-01M5K8J899THH6XJK99TAZ4VSD \
  -H "Authorization: Bearer $HIAPI_KEY"

Python: enviar, fazer polling, salvar

import os, time, requests

BASE = "https://www.hiapi.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}

def upscale(image_url: str, out_path: str) -> str:
    r = requests.post(f"{BASE}/v1/tasks", headers=HEADERS, timeout=30, json={
        "model": "recraft/creative-upscale",
        "input": {"image_url": image_url},
    })
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    deadline = time.time() + 300
    while time.time() < deadline:
        time.sleep(5)
        try:
            d = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        except requests.RequestException:
            continue  # erro de rede transitório: continue o polling do MESMO taskId
        if d["status"] == "success":
            url = d["output"][0]["url"]
            with open(out_path, "wb") as f:
                f.write(requests.get(url, timeout=120).content)
            return task_id
        if d["status"] in ("fail", "failed"):
            raise RuntimeError(f"task {task_id} failed: {d}")
    raise TimeoutError(f"task {task_id} still running; re-poll it, do not resubmit")

upscale("https://example.com/old-illustration.png", "upscaled.webp")

Dois detalhes importam em produção. Primeiro, nunca reenvie após um timeout: cada envio cria uma nova tarefa cobrada, então mantenha o taskId e faça polling dele novamente. Segundo, salve o arquivo imediatamente; a URL de saída tem expireAt e o host é temporário.

Considerações para produção

  • Use callback para tarefas em lote. Em vez de fazer polling, você pode passar callback: {"url": "...", "when": "final"} no corpo da tarefa e deixar o hiapi chamar você quando a tarefa terminar. Use o taskId como chave de deduplicação.
  • Intervalo de polling de 5 segundos é suficiente. Uma tarefa leva cerca de um minuto, então fazer polling mais rápido só aumenta as requisições.
  • Valide a URL antes de enviar. A plataforma rejeita antecipadamente URLs malformadas (veja abaixo), mas uma URL https:// inacessível é outro tipo de falha, que é melhor capturar antecipadamente do seu lado com uma requisição HEAD rápida.

O que vimos em uma execução real

Executamos uma requisição real com a imagem de exemplo da página do modelo (um PNG de 1254×1254 de uma cabana na montanha).

Item Observação
Resposta do envio {"code":200,"data":{"taskId":"tk-hiapi-01M5K8J899THH6XJK99TAZ4VSD"}}
Sequência de status handling → archiving → success
Tempo de created até completed 61 segundos (1792721625 → 1792721686)
Saída Uma imagem, WebP, https://temp.hiapi.ai/.../...-0.webp, com um expireAt cerca de 7 dias depois
Tamanho da entrada PNG 1254×1254, 2,7 MB
Tamanho da saída WebP 4096×4096, aproximadamente 19,8 MB

Pontos que vale saber a partir dessa execução:

  1. A fase archiving ainda não tem output. A tarefa reporta completed com status: "archiving" por alguns ciclos de polling antes de o resultado ser movido para o armazenamento. Apenas status == "success" traz output[0].url, então não leia a URL na primeira vez que vir o timestamp completed.
  2. O resultado não é um 2x limpo. Uma entrada de 1254 px virou 4096 px, cerca de 3,3x por lado. A página do modelo mostra o mesmo par e não expõe um campo de escala, então espere que o tamanho da saída seja decidido pelo modelo, e não por você. Se você precisa de exatamente 2x, o Crisp Upscale é o endpoint que segue essa convenção.
  3. O arquivo de saída é grande. Uma imagem de 19,8 MB ultrapassa o limite de entrada de 20 MB que permitiria alimentá-la de volta diretamente, então não encadeie uma segunda passada sobre a saída sem redimensionar.
  4. Os detalhes são redesenhados, não apenas nitidizados. A descrição da própria página do modelo para esse par de imagens é: composição, iluminação e cores são basicamente preservadas, enquanto troncos, alvenaria de pedra e corrimãos são redesenhados, e alguns elementos pequenos (por exemplo, uma árvore ao lado da varanda) mudam. Revise a saída antes de substituir ativos de marca.
  5. URLs erradas falham rapidamente. Enviar "image_url": "not-a-url" retorna imediatamente HTTP 400: {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: image_url: 'not-a-url' does not match pattern '^https?://'"}. Esse padrão é a única validação que verificamos; não testamos o mínimo de 256 px nem o limite de 16 MP.

Executamos apenas uma tarefa, então o número de 61 segundos é uma amostra única, não um benchmark.

Creative Upscale ou Crisp Upscale?

Ambos aceitam apenas um image_url e não precisam de prompt. A diferença está em como tratam os pixels e no preço.

Creative Upscale Crisp Upscale
ID do modelo recraft/creative-upscale recraft/crisp-upscale
Comportamento Amplia e redesenha texturas e detalhes Dobra largura e altura, preservando conteúdo e texto
Ideal para Ilustrações antigas, artes pequenas ou de baixa resolução Fotos de produto, pôsteres com texto, ativos de design
Preço Muito mais alto por imagem; veja preços Veja o artigo de preços do Crisp

O preço por imagem do Creative Upscale é bem mais alto que o do Crisp (compare os números atualizados na página de preços), então use-o apenas quando você realmente quiser que os detalhes sejam regenerados. Para um fluxo genérico de resolução entre modelos, veja Aumentar a resolução de imagens com hiapi.

Relacionados

FAQ

Preciso de um prompt? Não. A página do modelo descreve uma entrada de imagem única, sem prompt nem outras configurações, e nossa requisição usou apenas image_url.

Posso escolher o tamanho da saída? Não pela API. Não há campo de escala; nossa entrada de 1254 px retornou como 4096 px.

Texto e logos são preservados? Não é garantido. Os detalhes são regenerados e elementos pequenos podem mudar, então use Crisp Upscale para ativos com texto.

Qual formato de saída vou receber? Na nossa execução foi WebP, entregue por uma URL temporária que expira, então baixe imediatamente.

Quanto tempo leva? Nossa execução única levou cerca de um minuto; dimensione a espera do seu cliente nessa ordem de grandeza.

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