HiAPI
Blogue

Tutorial

Não está recebendo callbacks do HiAPI? Guia de diagnóstico e correção de problemas de entrega de Webhook

Oct 14, 2026
Não está recebendo callbacks do HiAPI? Guia de diagnóstico e correção de problemas de entrega de Webhook

Você incluiu callback.url ao enviar uma tarefa para POST https://api.hiapi.ai/v1/tasks, querendo que o HiAPI fizesse um POST ativo para notificá-lo após a conclusão da tarefa, mas a tarefa já aparece como success em GET /v1/tasks/{taskId}, e seu endpoint de callback não recebeu nenhuma requisição. Esse tipo de problema, em oito de cada dez casos, não está no lado do HiAPI, mas sim na acessibilidade do endereço de callback, na capacidade do receptor de retornar 2xx conforme o contrato, e em possíveis conflitos entre polling e callback. Abaixo, vamos investigar item por item conforme o contrato real de callback, e fornecer passos de correção que podem ser aplicados imediatamente.

Se sua tarefa demora muito para atingir o estado final (data.status permanece por muito tempo em queued/handling/archiving), isso é outro tipo de problema; consulte Guia de diagnóstico e repetição para tarefas travadas ou com timeout no HiAPI. Este artigo trata apenas do cenário em que a tarefa já foi concluída, mas a notificação de callback não é recebida.

Sintomas do problema

A manifestação típica é que tudo está normal no lado da tarefa, GET /v1/tasks/{taskId} retorna data.status como success (ou fail), mas nos logs do seu endpoint de callback implantado na internet pública não há nenhum registro de POST vindo do HiAPI; ou então recebe ocasionalmente mas perde com frequência; ou ainda o mesmo taskId é entregue duas vezes, sendo tratado como anomalia pela sua lógica de deduplicação.

Primeiro, estabeleça um fato: callback é apenas uma forma de obter o resultado, não o único canal. Tarefas assíncronas do HiAPI sempre podem ter o estado final obtido por polling ativo via GET /v1/tasks/{taskId}; o callback (Webhook) serve apenas para economizar o polling. Portanto, "não receber callback" não significa "não conseguir o resultado"; primeiro use polling para confirmar que a tarefa está boa, e depois localize o problema de entrega.

O contrato real do callback (alinhe primeiro, depois depure)

Ao registrar o callback, callback é um campo de nível superior de POST /v1/tasks, no mesmo nível de model e input, e não pode ser colocado dentro de input:

{
  "model": "gpt-image-2",
  "input": { "prompt": "a calm blue data center" },
  "callback": {
    "url": "https://your-domain.com/hiapi/callback",
    "when": "final"
  }
}

Alguns pontos que você deve memorizar:

  • callback.url deve ser uma URL http(s) acessível pela internet pública; o HiAPI fará POST para ela a partir da internet pública.
  • callback.when atualmente aceita apenas final: entrega uma vez quando a tarefa atinge o estado final, e tanto success quanto fail disparam. Não há callback por progresso ou por etapas.
  • O método de entrega é POST + Content-Type: application/json, e o corpo da requisição é completamente idêntico ao campo data de GET /v1/tasks/{taskId}, ou seja, o objeto de detalhes da tarefa, contendo status, output, error, taskId, created, completed, etc.
  • Em caso de falha de entrega (não 2xx / timeout / erro de rede), há reentrega conforme imediato → +1 minuto → +5 minutos → +20 minutos, no máximo 4 vezes; após 4 falhas não há mais tentativas, e isso não afeta o estado da própria tarefa.
  • O callback de estado final tem semântica de pelo menos uma vez (at least once), não exatamente uma vez. O mesmo taskId pode ser entregue múltiplas vezes, e o receptor deve fazer deduplicação idempotente por taskId.

Os detalhes do contrato estão na documentação oficial: Criação de tarefa e campo callback, Visão geral da API assíncrona (repetição de callback e idempotência).

Causas comuns (ordenadas por probabilidade de ocorrência)

1. Endereço de callback não acessível pela internet pública (mais comum)

Foi escrito como http://localhost:3000/..., IP de rede interna, ou domínio que só resolve em DNS interno. O HiAPI não consegue alcançar sua máquina local a partir da internet pública, então naturalmente não consegue entregar. Desenvolvimento local é onde isso acontece com mais frequência.

2. O receptor não retorna 2xx

O handler lança exceção, retorna redirecionamento 3xx, é bloqueado por middleware de autenticação como 401/403, ou retorna 5xx. O HiAPI considera sucesso de entrega apenas HTTP 2xx; todo o resto entra em repetição, e quando a janela de repetição se esgota, manifesta-se como "não recebido".

3. Timeout de processamento

O handler executa tarefas pesadas primeiro (baixar produtos, transferir para armazenamento de objetos, gravar no banco de dados, enviar mensagens) e só depois retorna 200; demorando demais, é considerado timeout e dispara repetição, e com muitas repetições acumuladas parece perda de pacotes.

4. Colocar callback dentro de input

É um campo de nível superior; se colocado dentro de input, não será reconhecido como registro de callback; além disso, o input de cada modelo tem schema estrito, e adicionar chaves desconhecidas geralmente causa erro síncrono no envio: invalid input: <root>: additional properties 'callback' not allowed, e a tarefa nem chega a ser enviada com sucesso.

5. when preenchido com valor diferente de final

Atualmente só suporta final; preencher outro valor será rejeitado.

6. Conflito entre polling e callback

Se você tanto ativou o polling quanto espera o callback, o polling pode obter o estado final primeiro e fechar o registro local da tarefa; quando o callback chega, não encontra o registro correspondente e é tratado como "não recebido".

7. Bloqueio por certificado ou WAF

O endereço de callback usa certificado autoassinado / expirado, ou o WAF bloqueia o POST anônimo sem User-Agent convencional e sem seus cabeçalhos de autenticação próprios como tráfego suspeito.

Passos de correção

  1. Primeiro confirme que a tarefa em si está boa. Use GET /v1/tasks/{taskId} para verificar data.status; se for success/fail, a tarefa já está no estado final e o problema está na etapa de entrega; se ainda estiver em estado não final, é outro tipo de problema (veja a investigação de travamento no início).
  2. Troque o endereço de callback por um domínio https público. De uma máquina externa, execute curl -i -X POST https://your-domain.com/hiapi/callback -d '{}' para confirmar que consegue conectar e retorna 2xx. Para depuração em localhost, use um túnel público para mapear a porta local para a internet.
  3. Primeiro registre o callback de forma confiável e depois retorne 2xx rapidamente. Ao receber a requisição, primeiro grave o conteúdo do callback no banco de dados ou em fila persistente (esta etapa deve ser rápida), e só retorne 2xx após gravar com sucesso; deixe tarefas pesadas como download e transferência para processamento assíncrono em background. Não retorne 200 antes de gravar: se o processo travar logo depois, esse callback será perdido, e o HiAPI não reenviará após receber 2xx. Ao mesmo tempo, isente esse caminho do middleware de autenticação, pois o callback do HiAPI não traz seus cabeçalhos de autenticação próprios.
  4. Verifique a posição e os valores de callback. Confirme que está no nível superior do corpo da requisição (no mesmo nível de model e input), url é http(s) público, e when é final.
  5. Faça deduplicação idempotente por taskId. Ao receber o callback, primeiro verifique localmente se esse taskId já foi processado; se não, grave no banco / dispare ações subsequentes; sob semântica at-least-once, chegadas duplicadas são normais, não descarte duplicatas como exceção.
  6. Adicione um polling de fallback. Para taskId que excederam o tempo esperado sem receber callback, faça ativamente GET /v1/tasks/{taskId} para consultar o estado final. Callback é otimização, polling é a linha de base; ambos devem ser unificados pela mesma lógica idempotente.
  7. Transfira os produtos o mais rápido possível. O output[].url no corpo do callback é um link temporário (storage é temp, expireAt é timestamp Unix, expira em cerca de 7 dias); após recebê-lo, baixe ou transfira imediatamente para seu próprio armazenamento, não armazene hotlink diretamente.

Exemplo mínimo de verificação

Primeiro, sem envolver callback, use "envio + polling" para provar que sua key e a integração em si estão funcionando (use o id do modelo puro):

# 1. Enviar tarefa
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","input":{"prompt":"a calm blue data center"}}'
# → {"code":200,"message":"success","data":{"taskId":"tk-hiapi-..."}}

# 2. Usar o taskId retornado para polling do estado final
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxx \
  -H "Authorization: Bearer $HIAPI_API_KEY"
# → data.status vai de queued/handling/archiving para success (com output) ou fail (com error)

Se o envio retornar HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}, significa que a API key está incorreta; verifique no console e tente novamente. Após confirmar que a integração está OK, adicione callback de nível superior ao corpo do POST e verifique o receptor item por item conforme os passos de correção acima.

FAQ

O callback nunca chega, mas a tarefa na verdade foi bem-sucedida; ainda posso obter o resultado? Sim. A qualquer momento você pode usar GET /v1/tasks/{taskId} para ler data.status e data.output; a perda do callback não afeta sua obtenção ativa do resultado.

Quantas vezes o callback é repetido e com qual intervalo? Em caso de não 2xx / timeout / erro de rede, reentrega conforme imediato → +1 minuto → +5 minutos → +20 minutos, no máximo 4 vezes. Após 4 falhas não há mais tentativas, e isso não afeta o estado success/fail da própria tarefa.

É normal receber dois callbacks para a mesma tarefa? Sim. O callback de estado final tem semântica de "pelo menos uma vez"; basta fazer deduplicação idempotente por taskId, não trate entregas duplicadas como erro.

Como receber callbacks em desenvolvimento local? O HiAPI não consegue alcançar localhost e endereços de rede interna. Ou use um túnel público para mapear a porta local para a internet pública, ou na fase local use diretamente polling, e mude para callback quando for para produção.

Quais campos existem no corpo da requisição de callback? Completamente idêntico ao data de GET /v1/tasks/{taskId}, incluindo taskId, status, output (array de produtos em caso de sucesso), error (code e message em caso de falha), created, completed, etc. Veja detalhes em documentação de detalhes da tarefa.

Não receber o callback causa cobrança extra? Não. A falha da tarefa em si não gera cobrança, e a cota reservada será devolvida; o sucesso ou não da entrega do callback também não altera o resultado de cobrança da tarefa; a cobrança é calculada apenas com base no sucesso final da geração da tarefa.

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