DENY o REVIEW y alguien pregunta por qué. Esta guía te lleva desde la decisión que devolvió Tracer hasta una regla con nombre o un límite de gasto con nombre. De ahí llega al registro almacenado y al que puedes entregar a un auditor meses después.
Lo que cambia en tu operación: la respuesta a “¿por qué se bloqueó esto?” deja de ser una búsqueda en logs. Cada decisión llega con los identificadores de lo que la produjo. El mismo registro responde por id años después, y su evento de auditoría se puede comprobar contra la cadena de hashes.
Antes de empezar
- Tracer en ejecución y alcanzable, con una API key — consulta Primeros pasos
- Una respuesta
DENYoREVIEWcon la que trabajar, o elvalidationIdde una - Familiaridad con lo que hacen las reglas y los límites — consulta el Motor de reglas y los Límites de gasto
X-API-Key.
Paso 1: Lee la decisión que devolvió Tracer
POST /v1/validations responde con la decisión completa. Una solicitud nueva responde 201; repetir un requestId responde 200 con la decisión que Tracer ya registró para esa clave.
Para el esquema completo de solicitud y respuesta, consulta Validar una transacción.
Paso 2: Distingue una denegación por regla de una por límite
Lee
reason primero. Nombra lo que produjo la decisión y te dice cuál de los dos pasos siguientes tomar.
reason lleva el mismo texto en decisiones REVIEW — Rule matched with REVIEW action — y el Paso 3 lee una revisión igual que lee una denegación.
En una denegación por regla,
limitUsageDetails vuelve vacío porque Tracer se detiene antes de la verificación de límites — no porque ningún límite aplique a la cuenta.Paso 3: Nombra la regla
matchedRuleIds lista cada regla que coincidió, sea cual sea la acción que lleva cada una — una regla DENY y una regla ALLOW pueden aparecer en la misma denegación. Recupera cada una y lee su action para encontrar la regla detrás de la decisión:
name, la description, la expression, la action y los scopes que un colega necesita para ver por qué disparó — consulta Recuperar una regla.
Compara matchedRuleIds con evaluatedRuleIds cuando la pregunta es la opuesta — “¿por qué mi regla no disparó?”. Una regla ausente de evaluatedRuleIds no fue evaluada para esta transacción, así que empieza por su estado y su scope antes que por su expresión.
Paso 4: Nombra el límite de gasto
En una denegación
limit_exceeded, limitUsageDetails tiene una entrada por cada límite que Tracer verificó, y las entradas marcadas con "exceeded": true son las que el monto empujaría más allá de su techo:
attemptedAmount contra limitAmount, con currentUsage reportando lo que el período actual de ese límite y el scope que coincidió tendrían si esta transacción se permitiera. En la entrada de arriba, una compra de 1500 llevaría un techo diario de 50000 hasta 51500.
Un límite PER_TRANSACTION no mantiene conteo, así que su entrada reporta currentUsage como 0 y attemptedAmount contra limitAmount es toda la comparación.
GET /v1/limits/{limitId} da el nombre y la configuración actuales del límite — consulta Recuperar un límite. El registro de la decisión conserva el techo, el período y el scope tal como estaban cuando se tomó la decisión, así que un límite cambiado desde entonces no cambia lo que dice el registro.
Para cómo cuenta cada período y cómo se acumula el consumo, consulta Límites de gasto.
Paso 5: Recupera el registro más tarde
Cada decisión queda almacenada bajo su
validationId:
transactionType, amount, currency, transactionTimestamp, account y los opcionales segment, portfolio, merchant y metadata — más los mismos decision, reason, matchedRuleIds, evaluatedRuleIds y limitUsageDetails que llevaba la respuesta original, y un createdAt. Consulta Recuperar una validación.
Este es el registro para leer en voz alta en una disputa: es la entrada y el resultado en un solo documento, y no cambia cuando las reglas o los límites cambian después.
Paso 6: Encuentra registros cuando no tienes el id
GET /v1/validations lista las decisiones almacenadas, de la más reciente a la más antigua, con paginación por cursor:
matched_rule_id={ruleId}— cada decisión almacenada con la que coincidió esta reglaexceeded_limit_id={limitId}— cada decisión almacenada que este límite detuvo
validationId, decision, reason, amount, currency, transactionType, accountId, matchedRuleIds, exceededLimitIds, processingTimeMs y createdAt. Toma el validationId del que te interesa y recupéralo con el Paso 5 para tener el registro completo. Consulta Listar validaciones para todos los filtros y los campos de paginación.
Paso 7: Obtén el evento de auditoría detrás de la decisión
El rastro de auditoría registra la decisión con el
validationId como resourceId del evento:
El mismo endpoint lleva el ciclo de vida de reglas y límites — quién los creó, activó o eliminó. Consulta Listar eventos de auditoría para los filtros, y Auditoría y compliance para los tipos de evento y los períodos de retención.
Paso 8: Verifica el evento de auditoría en una auditoría
Pasa el
eventId al endpoint de verificación:
isValid: true establece que cada registro, desde el primero hasta el que indicaste, sigue coincidiendo con el hash almacenado con él. Cada uno también enlaza con el hash del registro anterior, así que dentro de ese tramo ningún registro fue eliminado, reordenado ni tuvo su fecha alterada. totalChecked reporta cuántos registros cubrió la verificación.
En una verificación fallida, isValid es false, message reporta la manipulación y firstInvalidId lleva un número de secuencia interno del registro divergente. Ese número no es un id de evento de auditoría, así que no es un valor para pasar a GET /v1/audit-events/{id}.
Consulta Verificar un evento de auditoría.
Entrega los dos juntos: el evento recuperado en el Paso 7 es el contenido de la decisión, y el resultado de la verificación es la evidencia de que la cadena que lo sostiene está intacta. La llamada de verificación informa sobre la cadena — no devuelve el registro.
Errores comunes
Códigos de error
La lista completa está en la lista de errores de Tracer.

