Nunca repita
invalid_request, invalid_amount, unknown_asset_or_rail, asset_not_offered, unauthorized. A solicitação está com defeito: repeti-la inalterada dá o mesmo resultado. Corrija-a ou exiba o motivo.
Developers
Todo erro carrega um código estável e legível por máquina e um status HTTP coerente. O código é o que sua integração deve usar para ramificar: o texto pode evoluir, o código não.
O formato atual é deliberadamente mínimo. É estável, e é isso que importa: um código e nada que vaze um detalhe interno.
{ "error": "rate_stale" }{
"error": "rail_not_open",
"reason": {
"fr": "La retenue TDS de 1 % et l’enregistrement FIU-IND exigent une entite locale…",
"en": "The 1% TDS withholding and FIU-IND registration require a local entity…"
}
}Alguns erros carregam um objeto de motivo bilíngue, destinado a ser exibido como está ao usuário. Um canal fechado é um deles: o motivo explica uma restrição regulatória nomeada, não uma indisponibilidade, e exibi-lo evita uma solicitação de suporte. A API versionada adicionará um id de solicitação a este envelope, para que você possa nos apontar uma linha precisa em nossos logs.
Estes códigos são retornados hoje pelo endpoint de cotação.
| code | HTTP | O que significa | O que fazer |
|---|---|---|---|
invalid_request | 400 | O corpo da solicitação falha na validação do esquema: campo ausente, tipo errado, valor fora dos limites permitidos. | Verifique se o valor é uma string e não um número, e se a direção é exatamente “sell” ou “receive”. |
invalid_amount | 400 | O valor não pode ser analisado ou carrega mais decimais do que o ativo ou a moeda aceita. | Trunque para a precisão da unidade: 6 decimais para USDT, 8 para BTC, 2 para o euro, 0 para o franco CFA. |
unknown_asset_or_rail | 404 | O identificador do ativo ou do canal não existe no catálogo. | Os identificadores são estáveis e nunca reatribuídos. Recarregue o catálogo em vez de adivinhá-los. |
rail_not_open | 409 | O canal existe, mas não está aberto. A resposta carrega o motivo exato, em ambos os idiomas. | Mostre o motivo como está: ele explica uma restrição regulatória, não uma interrupção. Ofereça um canal aberto no mesmo país. |
asset_not_offered | 409 | O ativo está no catálogo, mas não é oferecido — o caso de ativos com anonimato aprimorado. | Não o ofereça em seu seletor. O catálogo o retorna com seu motivo para que você possa explicá-lo. |
rate_stale | 503 | O último preço conhecido excede a idade máxima tolerada. O mecanismo se recusa a cotar em vez de servir um preço desatualizado como firme. | Tente novamente após alguns segundos. Não armazene em cache a última cotação bem-sucedida para preencher a lacuna: isso seria exatamente o erro que este código evita. |
rate_unavailable | 503 | Nenhum preço está disponível para este par ativo/moeda. | Desative o par em sua interface em vez de mostrar uma estimativa. Uma estimativa exibida torna-se uma expectativa. |
quote_failed | 500 | Erro inesperado durante o cálculo. Nenhuma cotação é retornada. | Tente novamente uma vez; se o erro persistir, escreva para nós com o carimbo de data/hora exato da chamada. |
Estes códigos acompanham endpoints que ainda não estão abertos. Eles são publicados para que o tratamento de erros seja escrito uma única vez.
| code | HTTP | O que significa | O que fazer |
|---|---|---|---|
unauthorized | 401 | Chave ausente, revogada ou usada no ambiente errado. | Uma chave sk_test não funciona em produção, e o inverso também não: isso é intencional. |
idempotency_conflict | 409 | A mesma chave de idempotência já foi usada com um corpo de solicitação diferente. | Uma chave pertence a uma intenção. Se o conteúdo muda, a chave muda; caso contrário, não há como saber qual das duas ordens reproduzir. |
quote_expired | 409 | A cotação passou da sua janela de bloqueio. | Faça uma nova cotação e tenha o novo valor aceito. Nunca reajustamos o preço silenciosamente contra o cliente. |
beneficiary_rejected | 422 | Os dados do beneficiário falham na validação do canal: soma de verificação inválida, formato não conforme ou nome que não corresponde à identidade verificada. | A resposta nomeia o campo problemático. O nome do beneficiário deve ser a identidade verificada: nenhum pagamento a terceiros é possível. |
country_not_served | 451 | O país de destino não é atendido: sanções, medidas restritivas ou ausência de um quadro local. | O código 451 é escolhido deliberadamente em vez de um 404: quando recusamos, dizemos que é uma recusa e por quê. |
rate_limited | 429 | Muitas chamadas dentro da janela deslizante. | Respeite o cabeçalho Retry-After. Cotações são baratas de enfileirar, caras de bombardear. |
not_found | 404 | O recurso não existe ou não pertence à sua chave. | Ambos os casos retornam o mesmo código: uma resposta que os distinguisse permitiria que qualquer um enumerasse as referências de outras pessoas. |
Um valor fora dos limites do canal retorna uma cotação válida, com um objeto limitError. Não é uma falha: é uma informação que sua interface deve exibir.
"limitError": { "code": "below_min", "limit": "20.00" }Tratar este caso como um erro HTTP privaria você do valor calculado e, portanto, da capacidade de dizer ao usuário “você está 16,53 EUR abaixo do mínimo para este método de pagamento”. O limite se aplica ao valor líquido, aquele que o beneficiário recebe.
Três famílias, três comportamentos. Repetir um erro de validação em um loop apenas preenche seus logs.
invalid_request, invalid_amount, unknown_asset_or_rail, asset_not_offered, unauthorized. A solicitação está com defeito: repeti-la inalterada dá o mesmo resultado. Corrija-a ou exiba o motivo.
rate_stale, rate_unavailable, quote_failed e qualquer limitação de taxa. Aguarde alguns segundos, com um intervalo crescente entre as tentativas. Não preencha o intervalo com uma cotação em cache.
rail_not_open, quote_expired, beneficiary_rejected, country_not_served. A situação exige uma escolha humana: ofereça outro canal, uma cotação nova, dados corrigidos.