HiAPI
Blogue

Tutorial

Como usar recraft/creative-upscale pela API HiAPI: guia de requisições com curl e Python

Nov 3, 2026
文章封面图:深青底色上以扁平几何切面构成的水晶矿物剖面,青绿双色点缀,印刷图版风格。

O papel do recraft/creative-upscale no fluxo de trabalho do desenvolvedor

recraft/creative-upscale é um endpoint de imagem para imagem: você envia uma imagem existente e o modelo retorna uma versão maior, reconstruída pelo modelo. A palavra-chave aqui é criativo (creative). Uma etapa clássica de upscaling (bilinear, Lanczos ou um modelo genérico de super-resolução) preserva a entrada o mais fielmente possível. O upscaling criativo permite regenerar detalhes que nunca existiram nos pixels de origem — as bordas são resintetizadas, as texturas são inferidas, e pequenas regiões desfocadas podem ser nitidificadas em conteúdo plausível, e não apenas interpolado.

Isso o distingue de uma ferramenta simples de redimensionamento e determina que ele ocupa uma posição diferente no pipeline.

Quando usá-lo

  • Atualização de material. Uma miniatura ou imagem antiga de produto precisa ser exibida em um tamanho maior, e o redimensionamento comum pareceria desfocado comparado aos vizinhos em resolução nativa.
  • Trabalho com imagens de referência e renderizações. Arte conceitual, storyboards ou imagens provisórias precisam ser exibidos em tamanho grande sem revelar sua origem de baixa resolução.
  • Upscaling dentro de um ciclo de geração. Você gerou uma imagem em um tamanho de trabalho menor e quer um material final sem executar todo o fluxo de geração novamente em uma tela maior.

Quando não usá-lo

Se a exigência é fidelidade exata byte a byte — digitalizações de arquivo, documentos, atlas de texturas em que os valores dos pixels são dados — não use um modelo criativo. Os detalhes regenerados são suposições plausíveis, não reconstruções; para fins de medição ou arquivamento, essa suposição é um defeito. Nesse caso, use um reamostrador determinístico e reserve o modelo criativo para saídas perceptivas.

A forma da chamada

Esse endpoint segue o mesmo padrão de requisição dos outros endpoints de imagem da HiAPI: uma requisição POST JSON autenticada para o caminho do modelo, contendo uma imagem de entrada e um objeto de parâmetros. Se você já integrou qualquer outro modelo de imagem da plataforma, esse modelo mental se transfere diretamente — e é exatamente esse o propósito de rotear essas chamadas por uma interface unificada. Uma chamada funcional com curl se torna o modelo para cada endpoint de imagem que você usar depois.

Uma forma útil de entender esta etapa: ela consome uma imagem em que você já confia (composição, conteúdo e cores definidos) e retorna uma variante maior e mais detalhada. As decisões de conteúdo pertencem ao upstream; recraft/creative-upscale é a fase de acabamento.

Pré-requisitos e configuração do endpoint

Antes de escrever a primeira requisição, reúna quatro coisas. Nenhuma delas exige um SDK especial — a integração inteira é comunicação HTTPS pura com corpo de requisição JSON.

1. Chave de API

Você precisa de uma chave de API da HiAPI com acesso aos modelos de imagem. Trate-a como segredo: carregue-a a partir de uma variável de ambiente, em vez de colá-la em um script, e nunca a envie para o repositório de versão.

export HIAPI_API_KEY="your-key-here"

A chave é passada no cabeçalho da requisição, não na URL nem no corpo JSON. Mantê-la fora da string de consulta também a mantém fora do histórico do shell e dos logs de proxy.

2. URL base

A URL base é o host da sua API HiAPI. Todas as chamadas de modelo são caminhos relativos sob ela, então você pode defini-la como variável e reutilizá-la em todos os scripts:

export HIAPI_BASE_URL="https://api.hiapi.ai"

Consulte a documentação de referência da API da plataforma para obter a URL base canônica e o prefixo de caminho da sua conta, e armazene-os nessa única variável. Assim, uma mudança de host ou de versão é uma edição de uma linha.

3. Identificador do modelo

O ID do modelo é um segmento de caminho e deve ser escrito exatamente como publicado: recraft/creative-upscale. Ele contém uma barra, o que importa em algumas ferramentas — a seção de depuração detalha isso. Maiúsculas e minúsculas e hífens contam. Um caractere errado gera um erro de modelo não encontrado que, se você ler a mensagem apenas superficialmente, parece um problema de autenticação.

4. Imagem de teste

Tenha uma imagem pronta no disco e saiba seu caminho exato e tipo MIME. Use um arquivo pequeno na primeira execução, para que uma falha seja claramente um problema de requisição, e não de tamanho de payload ou de timeout. Você reutilizará a mesma imagem para execuções de comparação, então escolha algo com detalhes visíveis (tecidos, vegetação, placas sem texto), não um degradê uniforme.

Checklist de cabeçalhos da requisição

Toda requisição a partir daqui carrega os mesmos cabeçalhos:

  • Authorization: Bearer $HIAPI_API_KEY
  • Content-Type: application/json

Se você enviar a imagem no corpo JSON como base64 ou data URI, esses dois cabeçalhos serão suficientes. Se, em vez disso, você fizer upload do arquivo primeiro para obter uma URL, faça esse upload como uma chamada separada e armazene a URL gerada separadamente da requisição ao modelo.

Com a chave, a URL base, o ID do modelo e uma imagem de teste, você pode fazer uma chamada real em menos de um minuto.

Requisição funcional com curl

A seguir está uma chamada pronta para executar. Substitua o valor da imagem pela sua própria entrada — pode ser uma URL acessível publicamente ou um data URI codificado em base64, dependendo do que o modo de entrada do modelo aceita.

curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "image": "https://example.com/test-input.png"
    },
    "parameters": {
      "upscale": 2
    }
  }' \
  -o response.json

Usar -o para gravar a resposta em um arquivo, em vez de deixá-la fluir para o terminal, mantém o JSON intacto para análise e torna a chamada scriptável.

O papel de cada parte

  • -X POST —— o endpoint é POST; um GET retorna erro de método, facilmente confundido com um problema de permissão.
  • URL —— a URL base, seguida pelo caminho do modelo com o ID completo. Como o ID contém uma barra, o caminho tem dois segmentos após a coleção de modelos; mantenha-o como uma única string e, a menos que a documentação indique esse comportamento esperado, não deixe a biblioteca cliente recodificá-lo como recraft%2Fcreative-upscale.
  • Authorization —— token bearer. Se você receber 401 exatamente neste comando, a chave ou o formato do cabeçalho estão errados; nada mais no corpo da requisição foi validado ainda.
  • Content-Type: application/json —— obrigatório. Sem ele, alguns gateways tratam o corpo como dados de formulário e a requisição nunca chega ao modelo.
  • input.image —— a imagem de origem. Prefira uma URL durante a iteração: mantém o comando curto e as diferenças claras.
  • parameters.upscale —— controle de upscaling. Comece com um fator moderado e aumente depois de confirmar a resposta.

Duas variantes úteis

Para enviar um arquivo local como base64 em vez de uma URL:

B64=$(base64 -w0 ./test-input.png)

curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"input\": { \"image\": \"data:image/png;base64,${B64}\" },
    \"parameters\": { \"upscale\": 2 }
  }" \
  -o response.json

Para ver o código de status HTTP e o corpo da resposta ao mesmo tempo durante a depuração, adicione -w '\nHTTP %{http_code}\n' e remova -o.

Trate este comando como seu template. Depois que ele retornar uma imagem, cada alteração seguinte — um fator diferente, uma imagem de origem diferente — será apenas a edição de dois campos, não uma nova integração.

A mesma requisição em Python

A versão em Python não deve ser um copiar e colar do corpo curl; deve ser uma pequena função reutilizável, para que execuções de comparação posteriores exijam apenas uma chamada cada. Use apenas a biblioteca padrão — sem SDK.

import base64
import json
import os
import pathlib
import urllib.request

HIAPI_BASE_URL = os.environ["HIAPI_BASE_URL"].rstrip("/")
HIAPI_API_KEY = os.environ["HIAPI_API_KEY"]
MODEL = "recraft/creative-upscale"


def creative_upscale(image: str, upscale: int = 2, timeout: int = 120) -> dict:
    """Envia uma imagem para recraft/creative-upscale e retorna o JSON analisado."""
    payload = {
        "input": {"image": image},
        "parameters": {"upscale": upscale},
    }
    request = urllib.request.Request(
        url=f"{HIAPI_BASE_URL}/v1/models/{MODEL}",
        data=json.dumps(payload).encode("utf-8"),
        headers={
            "Authorization": f"Bearer {HIAPI_API_KEY}",
            "Content-Type": "application/json",
        },
        method="POST",
    )
    with urllib.request.urlopen(request, timeout=timeout) as response:
        return json.loads(response.read().decode("utf-8"))


def as_data_uri(path: str) -> str:
    data = pathlib.Path(path).read_bytes()
    mime = "image/png" if path.lower().endswith(".png") else "image/jpeg"
    return f"data:{mime};base64,{base64.b64encode(data).decode('ascii')}"


if __name__ == "__main__":
    result = creative_upscale(as_data_uri("test-input.png"), upscale=2)
    print(json.dumps(result, indent=2)[:2000])

Por que essa forma

  • Configuração a partir de variáveis de ambiente. A URL base e a chave são lidas uma vez na importação, então nenhum segredo aparece no arquivo, e trocar de ambiente exige apenas um export.
  • Uma função, uma responsabilidade. creative_upscale recebe uma referência de imagem e um fator e retorna o JSON analisado. Todas as informações sobre parâmetros permanecem visíveis no ponto de chamada.
  • Timeout explícito. Modelos de imagem demoram mais que endpoints de texto. Defina um timeout intencionalmente, em vez de herdar um padrão curto demais, e mantenha-o longo o suficiente para que chamadas lentas mas bem-sucedidas não sejam repetidas desnecessariamente.
  • Um auxiliar para arquivos locais. as_data_uri significa que você pode passar uma URL ou um caminho local sem alterar a lógica da requisição.

Se você preferir um cliente baseado em sessão

A mesma chamada com httpx exige apenas duas substituições — criar um cliente, definir o cabeçalho Authorization padrão e então fazer post do corpo JSON. As invariantes importantes não mudam: o ID do modelo permanece um único segmento de caminho não codificado, a chave fica nos cabeçalhos e o corpo mantém a separação input / parameters. Se você corresponder a esses três pontos, seu cliente será intercambiável com qualquer outro da plataforma.

Quando você o integrar a um pipeline, retorne o dicionário analisado e deixe o chamador decidir como persistir a imagem — essa separação torna o tratamento de resposta da próxima seção reutilizável.

Parâmetros de upscaling e criatividade

Os valores que você envia importam menos do que onde os envia. Primeiro confirme que a posição está correta e depois ajuste os números.

Dois buckets, um contrato

Cada requisição se divide em:

  • input —— a própria imagem. O objeto da operação. Nada sobre o comportamento do modelo vai aqui.
  • parameters —— os controles. O fator de upscaling e as configurações de criatividade pertencem a este objeto, como irmãos.

Essa divisão é o contrato. A primeira execução deve confirmar que o modelo aceita seu posicionamento — ou seja, que a chamada ao menos retorna uma imagem — antes de você começar a otimizar valores. Se um parâmetro for colocado no bucket errado, você normalmente obterá uma imagem gerada com valores padrão, ou um erro de validação apontando um campo desconhecido. Em qualquer dos casos, é um erro de posicionamento, não de qualidade, e ajustar configurações de qualidade não o corrigirá.

Fator de upscaling

O fator controla o tamanho da saída em relação à entrada. Como raciocinar sobre ele:

  • É um multiplicador, então custo e latência crescem com ele. Passar de um fator moderado para o máximo não é um passo linear em tempo de renderização. Trate cada aumento como um novo experimento, não como ajuste de um controle deslizante.
  • A resolução de entrada ainda importa. O modelo criativo tem mais com o que trabalhar quando existe alguma estrutura. Uma entrada minúscula dá a ele mais liberdade para inventar, o que às vezes é o objetivo e às vezes é um acidente.
  • Escolha o fator pelo tamanho alvo, não pelo máximo. Se a imagem precisa de 2× para caber no lugar, peça 2×. Pedir o máximo e depois reduzir descarta o ganho e cobra por ele.

Controle de criatividade

A criatividade é o botão que determina quanto o modelo pode substituir (em vez de ampliar). Configurações baixas se comportam mais como upscaling fiel; configurações altas fazem o modelo ressintetizar de forma mais agressiva, o que pode salvar uma origem desfocada ou blocada, mas também pode introduzir detalhes que você não queria.

Trate esse parâmetro como uma alavanca de fidelidade, com interpretações concretas em ambos os extremos:

  • Preservar —— logotipos, rostos, imagens de catálogo de produtos, qualquer coisa que o espectador possa comparar com o original.
  • Regenerar —— arte conceitual, fundos, texturas, imagens decorativas, em que a plausibilidade vence a exatidão.

Método de trabalho

Altere um parâmetro por vez, mantenha a entrada fixa e registre os valores junto com a saída. Uma pequena matriz — a mesma imagem em dois fatores, cada fator em duas configurações de criatividade — já basta para caracterizar o endpoint com seu próprio conteúdo. Não pegue emprestados valores "melhores" de outras pessoas; modelos criativos interagem fortemente com a entrada, e configurações adequadas para fotos raramente são adequadas para ilustrações planas.

Se um valor for rejeitado diretamente em vez de produzir um resultado ruim, é o contrato informando o domínio do parâmetro — consulte a referência de parâmetros do endpoint para obter as faixas aceitáveis, em vez de adivinhar.

Ler a resposta e salvar a imagem

Analise a resposta defensivamente. O tipo de payload faz parte do contrato, mas pode variar entre URL e bloco base64 embutido, e seu cliente não deve quebrar dependendo de qual recebe.

Primeiro, veja o JSON bruto

Antes de escrever o analisador, execute a chamada curl uma vez com -o response.json e leia o arquivo. Identifique o campo que carrega a imagem. Normalmente é um destes:

  • uma URL apontando para o arquivo gerado, ou
  • uma string embutida, normalmente base64 ou um data URI.

Procure também metadados que valha a pena registrar: dimensões, o ID do modelo ecoado e qualquer identificador que possa ser usado em um pedido de suporte.

Uma função de salvamento tolerante a falhas

import base64
import pathlib
import urllib.request


def extract_image(result: dict) -> str:
    """Encontra o payload da imagem, seja qual for a forma retornada."""
    for container in (result, result.get("data"), result.get("output")):
        if isinstance(container, list) and container:
            container = container[0]
        if isinstance(container, dict):
            for key in ("image", "url", "b64_json", "image_url"):
                value = container.get(key)
                if isinstance(value, str) and value:
                    return value
    raise ValueError(f"no image field in response: {sorted(result)}")


def save_image(payload: str, out_path: str = "upscaled.png") -> pathlib.Path:
    path = pathlib.Path(out_path)
    if payload.startswith("data:"):
        payload = payload.split(",", 1)[1]
        path.write_bytes(base64.b64decode(payload))
    elif payload.startswith("http://") or payload.startswith("https://"):
        with urllib.request.urlopen(payload) as response:
            path.write_bytes(response.read())
    else:
        path.write_bytes(base64.b64decode(payload))
    return path

O ponto não é que este seja o único analisador correto — é que a função declara suas suposições (data:, http(s)://, base64 puro) e lança um erro claro quando nenhuma corresponde. Quando a forma da resposta mudar, você só precisa atualizar uma função, não cada script que consome a imagem.

Salvar com segurança no fluxo curl

curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json -o response.json

python - <<'PY'
import json
from save_image import extract_image, save_image
result = json.load(open("response.json"))
print(save_image(extract_image(result), "out.png"))
PY

Dois hábitos que vale manter: gravar um novo nome de arquivo a cada execução, para que uma falha ou escrita parcial nunca sobrescreva um bom resultado; e verificar as dimensões da saída depois de salvar — um HTTP 200 bem-sucedido com dimensões inesperadas significa que os parâmetros não entraram em vigor, o que é mais fácil de detectar aqui do que depois de três etapas do pipeline.

Depurar falhas comuns

A maioria das falhas na primeira execução é trivial. Percorra esta lista em ordem; ela cobre a grande maioria dos casos.

401 / 403 —— autenticação

  • A chave foi carregada no mesmo shell em que o comando é executado? echo $HIAPI_API_KEY deve imprimir um valor não vazio.
  • O cabeçalho é exatamente Authorization: Bearer <key> — incluindo o espaço e a palavra Bearer?
  • A chave acabou na URL ou no corpo JSON em vez do cabeçalho? Coloque-a de volta.
  • A chave está restrita aos modelos de imagem? Uma chave válida para uma área do produto pode não valer para este endpoint.

404 —— modelo ou rota não encontrados

Isso quase sempre é um problema no ID do modelo. Compare caractere a caractere com o identificador publicado recraft/creative-upscale: a barra, as minúsculas e o hífen em creative-upscale são essenciais. Uma armadilha relacionada é o escape de URL pelo cliente — se você vir recraft%2Fcreative-upscale na linha de requisição e a chamada retornar 404, sua camada HTTP codificou a barra; configure-a para não mexer no segmento de caminho.

Confirme também que você não duplicou o prefixo do caminho (por exemplo, a URL base já termina com o segmento de versão e o caminho o repete). Usar uma única variável para a URL base torna isso fácil de detectar.

400 —— requisição compreendida, mas rejeitada

Leia a mensagem em vez de adivinhar. Causas comuns:

  • Formato de entrada da imagem errado. Base64 truncado (geralmente porque uma variável do shell foi cortada, ou pelo prefixo data:image/png;base64, ausente quando o modo espera um data URI completo), ou uma URL que não pode ser acessada publicamente.
  • Parâmetro fora da faixa ou no lugar errado. Um fator que o modelo não aceita, ou upscale enviado no nível superior em vez de dentro de parameters.
  • Tipo de conteúdo ausente. Content-Type como text/plain ou totalmente ausente transforma o corpo JSON em um documento não analisável.

413 / 422 / timeout —— tamanho e duração

Imagens de origem muito grandes podem falhar na validação antes de o modelo ser executado. Reduza a entrada moderadamente, tente novamente e confirme que a forma da requisição está razoável antes de enviar o arquivo em resolução total. Para timeouts, distinga lento de falhou: aumente o timeout do cliente uma vez; se a chamada então tiver sucesso, a correção pertence à configuração do cliente, não ao payload.

Regra de triagem rápida

Se o erro menciona autenticação, modelo ou formato de entrada, você não chegou à lógica de upscaling — nenhum valor de criatividade ou fator está envolvido ainda. Corrija o wrapper, tente novamente a requisição mais simples possível (uma pequena imagem de teste, parâmetros padrão) e só então comece a mudar configurações. Depurar nessa ordem evita o erro clássico: compensar cabeçalhos quebrados ajustando parâmetros.

Construir testes de comparação reproduzíveis

O upscaling criativo depende muito de julgamento, então use uma base fixa em vez da memória. O objetivo é um pequeno framework de teste que responda "essa configuração realmente ajuda?" sem você precisar rever visualmente arquivos antigos.

Entrada fixa

  • Uma imagem de teste, versionada no repositório. Escolha algo com detalhes recuperáveis — tecidos, vegetação, bordas de construções. Coloque-a no repositório ao lado do script, para que toda execução e todo membro da equipe use a mesma origem.
  • Parâmetros fixos. O fator e os valores de criatividade ficam em listas no script, não na sua cabeça ou em mensagens de chat.
  • ID de modelo fixo. Pelo mesmo motivo do checklist de cabeçalhos: recraft/creative-upscale escrito uma vez, em uma constante.

Um executor mínimo de matriz

import itertools, json, pathlib

FACTORS = [2, 4]
CREATIVITY = ["preserve", "regenerate"]  # use exatamente os valores aceitos pela documentação

src = as_data_uri("fixtures/test-input.png")
out_dir = pathlib.Path("runs"); out_dir.mkdir(exist_ok=True)

for factor, mode in itertools.product(FACTORS, CREATIVITY):
    result = creative_upscale(src, upscale=factor, creativity=mode)
    name = f"f{factor}-{mode}"
    save_image(extract_image(result), out_dir / f"{name}.png")
    (out_dir / f"{name}.json").write_text(json.dumps(result, indent=2))
    print(name, "ok")

Dois detalhes importam mais que o código. Primeiro, salve a resposta JSON bruta ao lado de cada imagem — quando o resultado parecer errado, a resposta informa se os parâmetros foram aplicados ou silenciosamente ignorados. Segundo, nomeie os arquivos a partir dos valores dos parâmetros, para que a listagem do diretório seja a matriz e você nunca precise se perguntar qual arquivo veio de qual configuração.

Compare de forma consistente

  • Observe a saída no tamanho de exibição esperado, não ampliada. Detalhes criativos impressionantes a 400% podem parecer artificiais no tamanho em que o usuário realmente vê a imagem.
  • Verifique as dimensões programaticamente como parte da execução. Uma incompatibilidade significa que o fator não entrou em vigor, o que é um relatório de bug contra sua própria requisição, não uma questão estética.
  • Julgue segundo critérios definidos: fidelidade à origem versus nitidez percebida, escolhidos por categoria de ativo. Escreva esse critério ao lado da matriz, para que a próxima pessoa saiba o que "melhor" significa.

Quando a matriz se estabilizar, o framework vira um teste de regressão: execute-o novamente após qualquer alteração no código do cliente e compare com os diretórios de execuções anteriores. Como cada chamada deste guia compartilha a mesma forma de requisição dos outros endpoints de imagem da plataforma, o executor que você construiu aqui se generaliza para qualquer modelo que você integrar em seguida.

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