DENY ou REVIEW e alguém está perguntando por quê. Este guia leva você da decisão que o Tracer devolveu até uma regra com nome ou um limite de gasto com nome. De lá ele chega ao registro armazenado e ao que você pode entregar a um auditor meses depois.
O que muda na sua operação: a resposta para “por que isso foi bloqueado?” deixa de ser uma busca em logs. Cada decisão chega com os identificadores do que a produziu. O mesmo registro responde por id anos depois, e o evento de auditoria dele pode ser conferido contra a cadeia de hashes.
Antes de começar
- Tracer em execução e acessível, com uma API key — veja Primeiros passos
- Uma resposta
DENYouREVIEWpara trabalhar, ou ovalidationIdde uma - Familiaridade com o que regras e limites fazem — veja o Motor de regras e os Limites de gasto
X-API-Key.
Passo 1: Leia a decisão que o Tracer devolveu
POST /v1/validations responde com a decisão completa. Uma requisição nova responde 201; repetir um requestId responde 200 com a decisão que o Tracer já registrou para aquela chave.
Para o schema completo de requisição e resposta, veja Validar uma transação.
Passo 2: Distinga uma negativa por regra de uma por limite
Leia
reason primeiro. Ele nomeia o que produziu a decisão e diz qual dos dois passos seguintes tomar.
reason carrega o mesmo texto em decisões REVIEW — Rule matched with REVIEW action — e o Passo 3 lê uma revisão do mesmo jeito que lê uma negativa.
Em uma negativa por regra,
limitUsageDetails volta vazio porque o Tracer para antes da verificação de limites — não porque nenhum limite se aplique à conta.Passo 3: Nomeie a regra
matchedRuleIds lista toda regra que casou, qualquer que seja a ação que cada uma carrega — uma regra DENY e uma regra ALLOW podem aparecer na mesma negativa. Recupere cada uma e leia sua action para encontrar a regra por trás da decisão:
name, a description, a expression, a action e os scopes que um colega precisa para ver por que ela disparou — veja Recuperar uma regra.
Compare matchedRuleIds com evaluatedRuleIds quando a pergunta for a oposta — “por que minha regra não disparou?”. Uma regra ausente de evaluatedRuleIds não foi avaliada para esta transação, então comece pelo status e pelo escopo dela antes da expressão.
Passo 4: Nomeie o limite de gasto
Em uma negativa
limit_exceeded, limitUsageDetails traz uma entrada por limite que o Tracer verificou, e as entradas marcadas com "exceeded": true são as que o valor empurraria além do teto:
attemptedAmount contra limitAmount, com currentUsage informando o que o período atual daquele limite e o escopo que casou teriam se esta transação fosse permitida. Na entrada acima, uma compra de 1500 levaria um teto diário de 50000 a 51500.
Um limite PER_TRANSACTION não mantém contagem, então sua entrada informa currentUsage como 0 e attemptedAmount contra limitAmount é toda a comparação.
GET /v1/limits/{limitId} dá o nome e a configuração atuais do limite — veja Recuperar um limite. O registro da decisão guarda o teto, o período e o escopo como estavam quando a decisão foi tomada, então um limite alterado depois disso não muda o que o registro diz.
Para como cada período conta e como o consumo acumula, veja Limites de gasto.
Passo 5: Recupere o registro mais tarde
Cada decisão fica armazenada sob o seu
validationId:
transactionType, amount, currency, transactionTimestamp, account e os opcionais segment, portfolio, merchant e metadata — mais os mesmos decision, reason, matchedRuleIds, evaluatedRuleIds e limitUsageDetails que a resposta original carregava, e um createdAt. Veja Recuperar uma validação.
Este é o registro para ler em voz alta numa disputa: é a entrada e o resultado em um só documento, e ele não muda quando regras ou limites mudam depois.
Passo 6: Encontre registros quando você não tem o id
GET /v1/validations lista as decisões armazenadas, da mais recente para a mais antiga, com paginação por cursor:
matched_rule_id={ruleId}— toda decisão armazenada com a qual esta regra casouexceeded_limit_id={limitId}— toda decisão armazenada que este limite barrou
validationId, decision, reason, amount, currency, transactionType, accountId, matchedRuleIds, exceededLimitIds, processingTimeMs e createdAt. Pegue o validationId daquele que você quer e recupere-o com o Passo 5 para ter o registro completo. Veja Listar validações para todos os filtros e os campos de paginação.
Passo 7: Puxe o evento de auditoria por trás da decisão
O rastro de auditoria registra a decisão com o
validationId como resourceId do evento:
O mesmo endpoint carrega o ciclo de vida de regras e limites — quem os criou, ativou ou deletou. Veja Listar eventos de auditoria para os filtros, e Auditoria e compliance para os tipos de evento e os períodos de retenção.
Passo 8: Verifique o evento de auditoria em uma auditoria
Passe o
eventId ao endpoint de verificação:
isValid: true estabelece que todo registro, do primeiro até aquele que você indicou, continua correspondendo ao hash armazenado com ele. Cada um também se liga ao hash do registro anterior, então dentro desse trecho nenhum registro foi removido, reordenado ou teve sua data alterada. totalChecked informa quantos registros a verificação cobriu.
Em uma verificação que falha, isValid é false, message informa a adulteração e firstInvalidId carrega um número de sequência interno do registro divergente. Esse número não é um id de evento de auditoria, então não é um valor para passar a GET /v1/audit-events/{id}.
Veja Verificar um evento de auditoria.
Entregue os dois juntos: o evento recuperado no Passo 7 é o conteúdo da decisão, e o resultado da verificação é a evidência de que a cadeia que o sustenta está intacta. A chamada de verificação informa sobre a cadeia — ela não devolve o registro.
Erros comuns
Códigos de erro
A lista completa está na lista de erros do Tracer.

