Toda resposta de erro segue o mesmo schema , independente do endpoint. Trate erros pelo error.code (string estável), nunca pelo error.message (texto pode mudar).
"message" : " Limite de 100 requisições/minuto excedido. Tente novamente em 23s. " ,
"retry_after_seconds" : 23
"request_id" : " req_01HVZX9YQB7M3J2K5N8P1R4T6W "
Campo Descrição codeString estável UPPER_SNAKE_CASE. Use para lógica de tratamento messageTexto pt-BR (ou en-US se Accept-Language: en-US) para humanos detailsObjeto contextual (campo inválido, retry-after, etc). Varia por código request_idID de correlação. Sempre informe ao suporte
HTTP Code Causa Ação recomendada 400 VALIDATION_FAILEDCampo ausente ou tipo errado Corrija payload, não retente 400 MALFORMED_JSONJSON inválido Corrija sintaxe 400 INVALID_ADDRESSEndereço crypto não-canônico Normalize antes (lowercase ETH, base58 BTC) 400 UNSUPPORTED_BLOCKCHAINBlockchain não suportada Use enum: BITCOIN, ETHEREUM, TRON, SOLANA, POLYGON, BSC 401 UNAUTHENTICATEDSem header ou token inválido Reautentique 401 TOKEN_EXPIREDJWT expirou Use /auth/refresh 401 MFA_STEP_UP_REQUIREDOperação sensível exige MFA recente Faça /auth/mfa/verify antes 403 FORBIDDEN_SCOPEAPI key sem escopo necessário Gere nova key com escopo correto 403 MODULE_NOT_ENTITLEDTenant não tem o módulo no plano Upgrade ou ative módulo no admin 404 RESOURCE_NOT_FOUNDRecurso inexistente ou em outro tenant Não retente 409 IDEMPOTENCY_CONFLICTMesma Idempotency-Key com body diferente Use chave nova 409 DUPLICATE_RESOURCERecurso único já existe (ex: external_id) Trate como sucesso silencioso 409 STATE_CONFLICTOperação inválida no estado atual (ex: resolver alerta já resolvido) Releia o estado 422 BUSINESS_RULE_FAILEDRegra de negócio bloqueou (ex: KYC pendente) Veja details.rule_id 429 RATE_LIMITEDLimite por tenant/IP/endpoint atingido Respeite Retry-After
HTTP Code Causa Ação recomendada 500 INTERNAL_ERRORBug inesperado Retry com backoff exponencial. Se persistir, abra ticket com request_id 502 UPSTREAM_UNAVAILABLEBureau externo (Exato, Chainalysis) fora Retry após 30s; nosso fallback geralmente cobre em <60s 503 SERVICE_DEGRADEDModo degradado (alguma integração caiu) Decisão pode vir REVIEW em vez de APPROVE; reprocesse depois 504 UPSTREAM_TIMEOUTBureau passou de 2s Idem 502
const RETRYABLE = new Set ([ 408 , 429 , 500 , 502 , 503 , 504 ]);
async function callWithRetry ( fn , maxAttempts = 4 ) {
for ( let attempt = 1 ; attempt <= maxAttempts ; attempt ++ ) {
if ( ! RETRYABLE . has ( err . status ) || attempt === maxAttempts ) throw err ;
const retryAfter = err . headers ?. [ ' retry-after ' ];
const delayMs = retryAfter
? parseInt ( retryAfter ) * 1000
: Math . min ( 1000 * Math . pow ( 2 , attempt ) , 30000 );
await new Promise ( r => setTimeout ( r , delayMs + Math . random () * 500 ));
Code Quando aparece Significado KYC_TIER_INSUFFICIENTTransação acima do limite para o tier do cliente Faça upgrade KYC (ENHANCED) antes SANCTIONS_HITCliente ou contraparte em lista OFAC/ONU/COAF Não desbloquear sem revisão compliance TRAVEL_RULE_REQUIREDTransação ≥ R$ 1.000 entre VASPs Envie IVMS101 antes de liquidar COAF_REPORTING_TRIGGEREDTransação dispara SAR automático Aguarde envio em até 24h
Quando abrir ticket no suporte (dev-support@sentinexrisk.com), envie:
request_id da resposta de erro
Timestamp da chamada (UTC)
Endpoint + método HTTP
tenant_id (não envie payload com PII!)
Tempo de resposta SLA: P1 < 1h, P2 < 4h úteis, P3 < 1 dia útil.