- Erros de requisição da API — a resposta HTTP de uma chamada síncrona da API (autenticação, cobrança, requisições malformadas, recursos inexistentes). Veja Erros de requisição da API.
- Códigos de falha de prediction — a requisição foi aceita e enfileirada, mas a prediction em si terminou com
status: "failed". A falha é descrita pelo objetoerrorda prediction, que você obtém nos endpoints de status da prediction, nas entregas de webhook e no endpoint de resultado. Veja Códigos de falha de prediction.
Códigos de falha de prediction
Uma prediction que falha carrega um objetoerror:
Predictions que falham não são cobradas; os créditos reservados para a requisição são liberados.
Uma prediction que não falhou carrega
error: null. Veja Nota de migração se você integrou antes de 17 de agosto de 2026.
Onde o erro chega até você
O mesmo objetoerror é publicado em todos os canais, então você pode lê-lo onde já costuma olhar:
Ler uma falha no endpoint de resultado
Pedir a saída de uma prediction que falhou devolve um400 com a falha que a causou, sob o código de nível de requisição PREDICTION_FAILED:
error.codeéPREDICTION_FAILED, um erro de requisição da API que significa “a prediction cuja saída você pediu não produziu nenhuma”;error.detailsé o objetoerrorda própria prediction — idêntico ao que/statusinforma para a mesma requisição, de modo que os dois endpoints nunca podem discordar sobre o motivo da falha. Faça as ramificações do seu código porerror.details.reasoneerror.details.retryable.
error.message repete a mensagem da prediction, então um cliente que só lê a mensagem de nível superior ainda recebe algo útil.
Dois timestamps, dois significados. O timestamp de nível superior é quando esta resposta HTTP foi produzida; error.details.timestamp é quando a prediction falhou. Para uma prediction que você busca dias depois, os dois ficam a dias de distância. Leia o de dentro sempre que quiser falar da falha.
As bibliotecas cliente oficiais desempacotam isso para você: result() lança um erro cujos code, reason e retryable são os da própria prediction, idênticos aos que subscribe() lança para a mesma falha.
Uma prediction ainda na fila ou em execução, ou uma que foi cancelada, continua devolvendo o mesmo 400 genérico de sempre.
Como decidir se vale a pena tentar de novo
Leiaretryable. Ele responde a exatamente uma pergunta — enviar esta mesma requisição outra vez levaria a um resultado diferente? — e é independente do code: o mesmo code pode ser retentável em uma falha e não ser em outra.
retryable é opcional. Quando estiver ausente, recorra ao padrão por code da tabela abaixo. Esse era o comportamento da Sunra antes de o campo existir, então recorrer a ele é sempre seguro; apenas menos preciso.
code
reason
reason nomeia a causa específica por trás do code. Use-o para métricas, roteamento e diagnóstico de suporte; use retryable para a decisão de tentar de novo.
Cada reason publicada hoje tem a sua própria seção abaixo, e a âncora é a própria reason — #input_fetch_failed, #moderation_blocked e assim por diante — de modo que um relatório de erro pode apontar direto para o que ela significa.
input_validation_failed
code: invalid_input · retryable: false
A requisição não passou na validação de schema ou de parâmetros da própria Sunra. O message aponta o campo problemático.
O que fazer: corrija o campo apontado. A mesma requisição vai continuar falhando.
provider_rejected_input
code: invalid_input · retryable: false
O provider do modelo rejeitou um ou mais parâmetros de entrada. Quando o provider informa quais, o message repassa essa informação; alguns providers apenas informam que a entrada era inaceitável, e nesse caso dizemos exatamente isso em vez de adivinhar.
O que fazer: revise seus parâmetros à luz do schema do modelo — um valor fora da faixa, uma combinação sem suporte, uma proporção ou uma duração que o modelo não aceita.
input_fetch_failed
code: invalid_input · retryable: false ou true
Um arquivo de entrada referenciado por URL não pôde ser baixado. Esta é a única reason cujo retryable realmente varia, então leia o campo em vez de supor:
false— o host nos recusou: um4xx, um endereço do qual não temos permissão de baixar, um redirecionamento ou um arquivo acima do limite de tamanho;true— o host esteve momentaneamente inacessível: um5xx, um timeout ou uma falha de DNS.
message ecoa a URL que você enviou, para você identificar qual entrada falhou — com a query string removida, de modo que credenciais carregadas em uma presigned URL nunca sejam refletidas de volta para você:
retryable for false, verifique se a URL é acessível publicamente e se um link presigned não expirou. Quando for true, tente de novo.
moderation_blocked
code: unsafe_content · retryable: false
Bloqueado pelo sistema de segurança de conteúdo do provider do modelo — seja o prompt e a mídia de entrada, seja a saída gerada.
O que fazer: altere o prompt ou a mídia. Reenviar o mesmo conteúdo será bloqueado de novo.
provider_rate_limited
code: service_provider_error · retryable: true
O provider do modelo está limitando a taxa de requisições.
O que fazer: tente de novo com backoff, ou roteie para outro modelo.
provider_unavailable
code: service_provider_error · retryable: true
O provider do modelo não conseguiu atender à requisição.
O que fazer: tente de novo mais tarde, ou roteie para outro modelo.
provider_timeout
code: task_timeout · retryable: true
A prediction não terminou dentro do tempo permitido.
O que fazer: tente de novo — um momento de menor carga, ou uma requisição menor (duração mais curta, resolução mais baixa), aumenta as chances.
provider_account_error
code: internal_server_error · retryable: false
A nossa própria conta junto ao provider do modelo tem um problema — cobrança, credenciais ou uma cota permanente. A culpa é nossa, não da sua entrada.
O que fazer: nada do seu lado; tentar de novo não adianta e já somos alertados automaticamente. Roteie para outro modelo se precisar dessa capacidade agora.
endpoint_misconfigured
code: internal_server_error · retryable: false
Este endpoint de modelo está mal configurado do nosso lado.
O que fazer: nada do seu lado; tentar de novo não adianta e já somos alertados automaticamente. Se for urgente, entre em contato com o suporte informando o request_id.
queue_enqueue_failed
code: internal_server_error · retryable: true
A prediction não pôde ser colocada na fila.
O que fazer: envie a requisição novamente.
reaped_stalled
code: internal_server_error · retryable: true
A prediction travou e foi encerrada.
O que fazer: envie a requisição novamente.
Valores desconhecidos
Tantocode quanto reason são conjuntos abertos. Novos valores são acrescentados conforme classificamos mais falhas, sem anúncio de breaking change. Sua integração não pode quebrar, descartar o erro nem rejeitar o payload ao encontrar um valor que não reconhece.
reasondesconhecido — trate como sereasonestivesse ausente e decida com base emretryable(ou no padrão porcode). Guarde o valor bruto nos seus logs; é o caminho mais rápido para o suporte identificar a falha.codedesconhecido — trate comointernal_server_error. Vale conhecer um valor sentinela pelo nome:unknown_error_code, que a Sunra emite quando uma prediction falhou mas não foi possível recuperar nenhuma classificação para ela.
Nota de migração: error é null quando não há erro
Em vigor desde 17 de agosto de 2026. O objetoerror tem uma única representação em todos os canais. Três diferenças entre eles deixaram de existir:
errorénullquando a prediction não falhou.GET /v1/predictions/{prediction_id}costumava responder com um objeto vazio —"error": {}— em toda prediction bem-sucedida, enfileirada ou cancelada. Agora ele responde"error": null, que é o que o endpoint de status da fila já fazia. Se você testa se o objeto está vazio (Object.keys(response.error).length === 0), troque isso por uma verificação de nulo (response.error === null).- Uma falha sempre carrega um
codee ummessagenão vazios. Quando uma falha registrou algo que não conseguimos classificar, você agora recebe o valor sentinelaunknown_error_codee uma mensagem genérica, em vez de um campo ausente, vazio ou que não é uma string. - Falhas registradas como texto puro chegam até você como texto. Um punhado de predictions de abril de 2026 guardou o erro como uma string pura.
GET /v1/predictions/{prediction_id}costumava descartá-la, e o endpoint de status da fila costumava substituí-la pela mensagem sentinela; agora ambos a publicam comomessagesobcode: "unknown_error_code".
error já estava presente em todas essas respostas, e apenas o seu valor mudou. As entregas de webhook não foram alteradas — elas eram o formato para o qual os outros canais convergiram — e error continua ausente de uma entrega succeeded, em vez de ser enviado como null.
Janela de compatibilidade. Não há período de emissão dupla; a API parou de produzir "error": {} nessa data. Se você reprocessa ou reexecuta payloads capturados antes dela, trate null e {} como a mesma coisa até que esses dados armazenados saiam de circulação.
Mudança futura: algumas falhas vão receber um code mais específico
Hoje boa parte das falhas é reportada como service_provider_error, incluindo muitas que não são transitórias nem culpa do provider. À medida que classificamos os providers um a um, essas falhas migram para o code que realmente as descreve:
- um provider rejeitando a sua entrada de forma determinística passa a ser
invalid_input(antesservice_provider_error); - um problema do lado da Sunra, como um endpoint mal configurado ou a nossa própria conta no provider, passa a ser
internal_server_error(antesservice_provider_error); - um arquivo de entrada que não conseguimos baixar passa a ser
invalid_input(antesinternal_server_error).
code está sendo introduzido — os cinco valores acima continuam sendo o conjunto completo dos códigos classificados. O que muda é qual deles uma determinada falha recebe, e isso muda gradualmente, provider a provider. Se o seu código ramifica com base em code, este é um bom momento para migrar essa lógica para retryable e reason, que descrevem a falha diretamente e não são afetados pela reclassificação.