> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fraudeg.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Razones de la decisión

> Cómo leer flags: código, categoría, severidad, y por qué el vocabulario es estable

`flags` es la explicación de por qué se tomó una decisión: la lista de señales de riesgo que
se activaron en la transacción. Es una clave de primer nivel de `data` — no vive dentro de
`decision`. Cada entrada trae cuatro campos: `code`, `category`, `severity` y `description`.

| Campo         | Qué es                                                                     |
| ------------- | -------------------------------------------------------------------------- |
| `code`        | Código público estable — el que programas contra él, ej. `AUTH_3DS_FAILED` |
| `category`    | Tipo de señal que originó la razón, ej. `authentication`                   |
| `severity`    | `low`, `medium` o `high` — ordinal, para triage                            |
| `description` | Descripción legible de la señal, en inglés                                 |

<Note>
  No confundas `flags` con `decision.reason`. `flags` trae las señales completas, con sus
  cuatro campos. `decision.reason` es una lista corta de **strings**, con el mismo vocabulario
  de códigos, más las entradas `custom_rule:<id>` y `entity_block:<kind>:<value>` cuando la
  decisión la elevó una regla tuya o tu lista de entidades. Ver
  [Formato de respuesta](/referencia/respuesta) y el catálogo en
  [Flags](/referencia/flags).
</Note>

## Los `code` son un vocabulario estable, no un reflejo del motor

Este es el punto que importa: `code` es un vocabulario público, deliberadamente
**desacoplado** de cómo el motor evalúa por dentro. FraudEG agrega y ajusta señales de
forma continua — eso es trabajo interno permanente — pero los códigos públicos no cambian
por eso. Cuando una señal nueva cuenta la misma historia que un código existente, se agrega
a ese código; no se te va apareciendo un código nuevo cada vez que el motor cambia por
dentro.

<Tip>
  Puedes hacer `switch` sobre `code` con confianza. Es la superficie pensada para programar
  contra ella — a diferencia del motor interno, que puede cambiar sin previo aviso, el
  catálogo de códigos es el contrato estable. Y como es el mismo vocabulario en `flags[].code`
  y en `decision.reason`, el mismo `switch` te sirve para los dos.
</Tip>

## `severity` es para priorizar, no para calcular

`severity` (`low` / `medium` / `high`) es ordinal — sirve para ordenar señales por
importancia al momento de hacer triage manual sobre una transacción retenida. No es un
número: no la sumes, no la promedies, no la uses para derivar un score. Para eso ya existe
[`risk_score`](/conceptos/score-y-decision), que es un eje completamente distinto.

## Si aparece un código que no reconoces

Trátalo como una señal genérica y no cambies tu lógica de negocio por él. La acción que
importa nunca sale de una razón individual — sale de `decision.type`. Ver
[Decisiones de transacción](/conceptos/decisiones).

## Categorías

Las señales se agrupan por tipo: autenticación, dispositivo, geografía, red,
velocidad, usuario, pago y envío, entre otras. La categoría (`category`) te dice de qué
familia viene la señal — por ejemplo, `VELOCITY_DEVICE_BURST` cae en la categoría de
velocidad.

## Dónde está el catálogo completo

Esta página explica cómo leer `flags`, no lista los códigos. El catálogo completo de
`code`, con su `category`, `severity` y `description`, vive en un solo lugar:
[Catálogo de flags](/referencia/flags).

Siguiente paso: [Ciclo de vida de la transacción](/conceptos/ciclo-de-vida).
