HiAPI
Blogue

Tutorial

Erro de entrada de imagem na HiAPI: envie uma URL publicamente acessível, não Base64

Oct 22, 2026
Erro de entrada de imagem na HiAPI: envie uma URL publicamente acessível, não Base64

Os modelos de image-to-image e de imagem de referência da HiAPI buscam sua imagem de origem a partir de uma URL HTTP(S) publicamente acessível — eles não aceitam strings de bytes base64, nem conseguem acessar endereços privados. A armadilha mais comum é: uma entrada de imagem inválida parece ter dado certo — o POST /v1/tasks retorna 200 com um taskId, e a falha real só aparece quando você faz o polling da tarefa. Na prática, você verá dois tipos de falha assim:

{ "code": 200, "message": "success",
  "data": { "status": "fail", "model": "gpt-image-2/image-to-image", "storage": "temp", "taskId": "tk-...",
    "error": { "code": "INVALID_REQUEST",
      "message": "The image URL could not be downloaded. Please provide a reachable public HTTP(S) URL and try again." } } }
{ "code": 200, "message": "success",
  "data": { "status": "fail", "model": "gpt-image-2/image-to-image", "storage": "temp", "taskId": "tk-...",
    "error": { "code": "TASK_FAILED", "message": "task failed" } } }

A primeira é o retorno para uma URL inacessível; a segunda é o resultado genérico obtido ao enviar um data URI base64 como imagem — sem nenhuma dica, só um task failed, e é justamente aqui que a maioria fica travada. Observe que o "message": "success" externo indica apenas que a própria requisição de polling foi bem-sucedida; o resultado real está em data.status.

Causas comuns (da maior para a menor probabilidade)

  • Você colou base64 no campo de imagem — uma string data:image/...;base64,.... Esse campo espera uma URL que o servidor consiga buscar, não bytes inline. No gpt-image-2/image-to-image, o data URI é aceito no momento da submissão e, em seguida, a tarefa termina com status: fail, código de erro TASK_FAILED / task failed.

  • A URL não é publicamente acessível. http://localhost, 127.0.0.1, IP de rede interna, arquivos que exigem login para serem vistos, links pré-assinados expirados — todos falham com INVALID_REQUEST — "The image URL could not be downloaded…".

  • Nome de campo errado (varia entre famílias, veja a tabela abaixo). O campo de entrada de imagem não é uniforme entre as famílias de modelos. Um nome errado é barrado por HTTP 400 no momento da submissão, por exemplo, usar image_url por engano no gpt-image-2/image-to-image:

    { "code": 400, "data": null, "error_code": "INVALID_REQUEST",
      "message": "invalid input: input_urls: missing required field \"input_urls\"; <root>: additional properties 'image_url' not allowed" }
    
  • Você usou o model id puro para fazer edição. O id puro (por exemplo, gpt-image-2) é text-to-image puro e não define nenhum campo de imagem, então o campo de imagem é rejeitado: 400 invalid input: <root>: additional properties 'input_urls' not allowed. Para edição, use o id de rota de image-to-image: gpt-image-2/image-to-image.

Como ler o código de erro: é «problema de entrada» ou «problema do upstream»

Divida o retorno em dois momentos: submissão (resposta direta do POST /v1/tasks) e estado terminal (o data.status obtido no polling de GET /v1/tasks/<taskId>):

  • HTTP 400 na submissão, envelope plano {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: ..."} → há um problema na estrutura/campos da sua requisição (problema de entrada). A tarefa nem foi criada, não há cobrança. Basta corrigir o nome do campo ou o model id.
  • HTTP 401 na submissão, envelope aninhado {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} → é um problema de autenticação (key errada ou sem permissão), não um problema de entrada.
  • HTTP 200 + taskId na submissão, mas data.status: "fail" no polling: veja data.error.code —
    • INVALID_REQUEST com message "could not be downloaded" → a URL da imagem não pode ser baixada (ainda é seu problema de entrada: troque a imagem por uma URL publicamente acessível).
    • TASK_FAILED com message "task failed" → falha genérica, sem dica. Primeiro descarte base64 / entrada inválida; se ainda falhar depois disso, trate como problema de «geração no upstream».

Em resumo: os 4xx da submissão são problemas de requisição / autenticação; só o fail no estado terminal pode envolver download ou geração no upstream; e em qualquer caso, não se deixe enganar pelo "message":"success" externo — vale sempre o data.status.

O nome do campo de entrada de imagem varia por modelo

A tabela abaixo foi verificada com base no input schema atual de cada modelo (confira sempre também a página do modelo, pois os campos variam por família):

model id (rota image-to-image) Campo de entrada de imagem Tipo
gpt-image-2/image-to-image input_urls array de strings
seedream-5.0-pro/image-to-image image_urls array de strings
nano-banana-pro image_input array de strings

O campo deve ir dentro do objeto input; a maioria dos modelos de imagem de referência exige um array (mesmo que haja só uma imagem).

Passos de correção

  1. Hospede a imagem em uma URL HTTP(S) publicamente acessível. Faça upload para qualquer object storage / CDN (Cloudflare R2, S3, GCS etc.) e defina o objeto como leitura pública, ou use uma URL pré-assinada ainda válida.
  2. Confirme que é acessível sem autenticação. Em uma sessão limpa (ou em outra máquina que não a sua), rode curl -sI "<suaURL>"; deve retornar 200 e content-type image/*. Se exigir cookie, header ou VPN, o servidor não conseguirá baixar.
  3. Use o model id de image-to-image, não o id puro. Para edição, chame gpt-image-2/image-to-image (ou a rota i2i correspondente ao seu modelo), não gpt-image-2.
  4. Use o nome de campo da documentação desse modelo (input_urls / image_urls / image_input), dentro de input.
  5. Nunca envie base64. Se você só tem os bytes, faça o upload primeiro e envie a URL obtida.
  6. Submeta primeiro, depois faça polling. GET /v1/tasks/<taskId> até data.status ser success ou fail. Em caso de falha, leia data.error.message — se aparecer "could not be downloaded", o problema é da URL, não do seu prompt.

Exemplo mínimo de verificação

Primeiro faça uma verificação de conectividade sem custo: listar modelos não cria nenhuma tarefa nem gasta nada.

curl -s https://api.hiapi.ai/v1/models \
  -H "Authorization: Bearer $HIAPI_API_KEY"

Retornar 200 com um array data indica que sua key está funcionando. Uma key inválida retorna 401 + {"error":{"code":"permission_denied", ... ,"type":"hiapi_error"}} — isso é problema de autenticação, não de entrada. Em seguida, envie uma requisição image-to-image correta: coloque no campo do modelo uma URL publicamente acessível.

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/image-to-image",
    "input": {
      "prompt": "把背景换成干净的影棚白",
      "input_urls": ["https://your-public-host.example.com/source.png"]
    }
  }'

Substitua input_urls pela URL da sua própria imagem acessível. Uma submissão bem-sucedida retorna data.taskId; então faça polling em GET https://api.hiapi.ai/v1/tasks/<taskId> até data.status ser success, e obtenha o resultado em data.output[0].url (essa URL tem validade; baixe ou transfira o quanto antes, não use hotlink).

Links relacionados

Perguntas frequentes

Posso enviar base64 para os modelos image-to-image da HiAPI? Não. O campo de imagem espera uma URL HTTP(S) pública que o servidor consiga baixar. A string data:image/...;base64,... é aceita no momento da submissão em alguns modelos, mas a tarefa termina em seguida com status: fail, código de erro TASK_FAILED / task failed. Faça upload dos bytes para um local público e envie a URL.

Meu POST /v1/tasks retornou 200, mas a tarefa falhou. Por quê? O 200 da submissão indica apenas que a requisição foi aceita. O download da imagem e a geração ocorrem depois. Faça polling em GET /v1/tasks/<taskId>; uma entrada de imagem inválida se revela ali como data.status: fail, com error.code sendo INVALID_REQUEST ("The image URL could not be downloaded…") ou TASK_FAILED.

Em qual campo vai a URL da imagem? Depende do modelo. gpt-image-2/image-to-image usa input_urls, seedream-5.0-pro/image-to-image usa image_urls, nano-banana-pro usa image_input (todos arrays). Antes de enviar a requisição, confira o schema atual na página do modelo.

Posso usar localhost ou uma URL privada? Não. A HiAPI busca a imagem a partir dos próprios servidores dela, então localhost, 127.0.0.1, endereços de rede interna, links visíveis só após login e URLs pré-assinadas expiradas falham todos com "The image URL could not be downloaded.". Use uma URL publicamente resolvível e sem autenticação.

O que significa o erro additional properties 'input_urls' not allowed? Você passou o campo de imagem para um modelo que não o define — geralmente por usar o id puro de text-to-image (gpt-image-2) em vez da rota image-to-image (gpt-image-2/image-to-image), ou por usar o nome de campo de outro modelo. É um 400 de submissão; veja o guia de 400 Bad Request acima.

Tarefas de imagem com falha são cobradas? Requisições rejeitadas com 400 na submissão não são cobradas; mas tarefas que foram aceitas (200 + taskId) e falharam depois podem ser cobradas — veja «Requisições com falha são cobradas?» acima. Por isso, antes de rodar de novo, corrija a URL.

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