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

# Límites de gasto

> Guía para configurar y gestionar límites de gasto en Tracer para control de transacciones y protección del cliente.

export const GMetadata = ({children}) => <Tooltip headline="Metadatos" tip="Información adicional en formato clave-valor adjunta a entidades como cuentas o transacciones — como IDs externos, números de referencia o códigos de departamento." cta="Ver glosario" href="/es/glossary">
    {children}
  </Tooltip>;

export const GAuditTrail = ({children}) => <Tooltip headline="Registro de auditoría" tip="Un registro cronológico e inmutable de cada acción y transacción en el sistema — esencial para el cumplimiento regulatorio y la resolución de disputas." cta="Ver glosario" href="/es/glossary">
    {children}
  </Tooltip>;

Los límites de gasto son cómo los equipos de producto y riesgo limitan la exposición por cliente, por segmento o por portafolio sin escribir código. Casos comunes: un tope diario de gasto con tarjeta para clientes minoristas, un tope mensual sobre un MCC específico, un límite con ventana de campaña para una promoción de marketing.

**Qué cambia en tu operación:** los topes de gasto dejan de ser constantes hardcoded en archivos de configuración o dispersos por varios servicios. Se vuelven datos versionados con un ciclo de vida claro (DRAFT → ACTIVE → INACTIVE), se reinician automáticamente en la frontera del período, y quedan en el rastro de auditoría cada vez que una transacción habría pasado sobre uno de ellos.

**El trade-off honesto:** los contadores necesitan mantenerse consistentes entre réplicas y races. Tracer maneja eso transaccionalmente — si una transacción se deniega o va a REVIEW, el contador hace rollback. Renuncias a "lógica local astuta en cada servicio" y ganas un número único y consistente.

<Tip>
  **¿Para quién es esta guía?** Product managers configurando topes, equipos de riesgo revisando exposición, compliance auditando lo que se denegó, y devs integrando la llamada de validación. La sección "Tipos de límite" no asume conocimiento de API; las secciones de ciclo de vida y PATCH asumen REST básico.
</Tip>

Los **límites de gasto** en Tracer te permiten controlar los montos de transacción por alcance (cuenta, portafolio, segmento) y período (diario, semanal, mensual, personalizado o por transacción). Los límites se evalúan en tiempo real junto con las reglas, en la misma llamada `POST /v1/validations`.

## Por qué usar límites de gasto

***

* **Protección del cliente**: Detecta el gasto excesivo y devuelve decisiones DENY para transacciones grandes no autorizadas
* **Gestión de riesgo**: Monitorea la exposición por cuenta, segmento o portafolio
* **Alcance flexible**: Aplica límites en diferentes niveles de granularidad
* **Seguimiento en tiempo real**: Monitorea el uso y los montos restantes instantáneamente
* **Reinicios automáticos**: Los límites diarios, semanales, mensuales y personalizados se reinician automáticamente
* **Ventanas de tiempo**: Restringe la aplicación de límites a horarios específicos del día
* **Períodos personalizados**: Define límites con fechas específicas para campañas, promociones o requisitos regulatorios

Al final de esta guía, podrás:

* Comprender los tipos de límites, ventanas de tiempo y opciones de alcance
* Crear y configurar límites de gasto con controles por período
* Monitorear el uso de límites en tiempo real
* Gestionar el ciclo de vida de los límites

***

## Conceptos principales

***

Comprende los componentes básicos de los límites de gasto.

### Tipos de límites

Tracer soporta cinco tipos de límites de gasto:

| Tipo              | Descripción                                                       | Comportamiento de reinicio                                     |
| ----------------- | ----------------------------------------------------------------- | -------------------------------------------------------------- |
| `DAILY`           | Monto máximo por día                                              | Se reinicia a medianoche UTC                                   |
| `WEEKLY`          | Monto máximo por semana                                           | Se reinicia cada lunes a las 00:00 UTC                         |
| `MONTHLY`         | Monto máximo por mes                                              | Se reinicia el 1ro del mes, medianoche UTC                     |
| `CUSTOM`          | Monto máximo dentro de un rango de fechas definido por el usuario | Se reinicia en `customEndDate` + 1 día a medianoche UTC        |
| `PER_TRANSACTION` | Monto máximo por transacción individual                           | Sin seguimiento; cada transacción se evalúa independientemente |

### Ventanas de tiempo

Las ventanas de tiempo restringen **cuándo** se aplica un límite durante el día. Cuando una transacción ocurre fuera de la ventana de tiempo configurada, el límite se **omite** (no se aplica) y la transacción puede continuar sin contabilizarse contra ese límite.

* **Formato**: `HH:MM` (24 horas, UTC)
* **Ambos campos requeridos**: Si `activeTimeStart` está definido, `activeTimeEnd` también debe estarlo (y viceversa)
* **Intervalo semi-abierto**: Inicio inclusivo, fin exclusivo `[inicio, fin)`
* **Ventanas nocturnas soportadas**: Definir `activeTimeStart: "20:00"` y `activeTimeEnd: "06:00"` crea una ventana de 20:00 a 06:00 UTC

<Note>
  Las ventanas de tiempo pueden aplicarse a **cualquier** tipo de límite (DAILY, WEEKLY, MONTHLY, CUSTOM o PER\_TRANSACTION). Si no se configura ninguna ventana de tiempo, el límite está activo 24/7.
</Note>

**Ejemplo: Cumplimiento PIX**

Una institución financiera necesita aplicar límites menores para transferencias PIX durante el horario nocturno (según recomendación del BACEN):

* `limitType`: `DAILY`
* `maxAmount`: `"1000.00"`
* `activeTimeStart`: `"20:00"`
* `activeTimeEnd`: `"06:00"`
* Alcance: transacciones PIX

Las transacciones entre las 20:00 y las 06:00 UTC se verifican contra el límite de R\$ 1.000. Las transacciones fuera de esta ventana no son afectadas por este límite.

### Períodos personalizados

Los períodos personalizados definen un **rango de fechas** durante el cual un límite está activo. Esto es útil para campañas, promociones, eventos estacionales o requisitos regulatorios con fechas específicas.

* **Campos requeridos**: `customStartDate` y `customEndDate` (solo para tipo `CUSTOM`)
* **Intervalo semi-abierto**: Inicio inclusivo, fin exclusivo `[inicio, fin)`
* **Duración máxima**: 5 años
* **No puede estar en el pasado**: El `customEndDate` no puede estar completamente antes de la fecha actual

<Warning>
  Los campos `customStartDate` y `customEndDate` son **requeridos** para límites `CUSTOM` y **prohibidos** para otros tipos de límite.
</Warning>

**Ejemplo: Campaña Black Friday**

Un minorista desea establecer un límite especial de gasto para el período de Black Friday:

* `limitType`: `CUSTOM`
* `maxAmount`: `"100000.00"`
* `customStartDate`: `"2026-11-25T00:00:00Z"`
* `customEndDate`: `"2026-11-30T00:00:00Z"`
* Alcance: transacciones CARD en el segmento minorista

El uso se acumula durante todo el período de 5 días. Después del 30 de noviembre, el límite ya no se aplica.

### Combinando ventanas de tiempo y períodos personalizados

Las ventanas de tiempo y los períodos personalizados pueden usarse juntos en límites `CUSTOM`. Cuando se combinan, una transacción debe estar dentro **tanto** del período personalizado **como** de la ventana de tiempo para ser evaluada contra el límite.

Por ejemplo, un límite `CUSTOM` con `customStartDate` 25 Nov a `customEndDate` 30 Nov y una ventana de tiempo de `09:00` a `18:00` aplicaría el límite solo durante el horario comercial dentro del período de Black Friday.

### Alcances

Los alcances definen a qué transacciones se aplica un límite. A diferencia de las reglas, **todo límite debe tener al menos un objeto de alcance** — los límites no pueden ser globales.

Dentro de un único objeto de alcance, los campos soportados son:

* `segmentId` - Aplicar a transacciones de un segmento específico
* `portfolioId` - Aplicar a transacciones de un portafolio específico
* `accountId` - Aplicar a transacciones de una cuenta específica
* `merchantId` - Aplicar a transacciones hacia un comercio específico
* `transactionType` - Aplicar a tipos de transacción específicos (CARD, WIRE, PIX, CRYPTO)
* `subType` - Aplicar a un subtipo de transacción específico (ej.: `debit`, `credit`)

**Semántica de coincidencia:**

* **Dentro de un objeto de alcance:** los campos se combinan con AND. Un campo no especificado funciona como comodín (coincide con cualquier valor). Al menos un campo debe estar definido — objetos de alcance vacíos (`{}`) son rechazados con el código de error `0009`.
* **Entre múltiples objetos de alcance en el mismo límite:** se combinan con OR. El límite aplica si **cualquier** objeto de alcance coincide con la transacción.

**Sin jerarquía entre límites.** Cuando una transacción coincide con múltiples límites (por ejemplo, un límite a nivel de cuenta y otro a nivel de segmento), Tracer verifica **todos** los límites aplicables de forma independiente en una sola transacción. La transacción se deniega tan pronto como cualquiera de ellos sea excedido.

### Seguimiento de uso

Para límites `DAILY`, `WEEKLY`, `MONTHLY` y `CUSTOM`, Tracer rastrea:

* **Uso actual** - Monto total consumido en el período actual (como valor decimal)
* **Porcentaje de utilización** - Porcentaje del límite usado
* **Tiempo de reinicio** - Cuándo el límite se reiniciará a cero

Los contadores de uso se retienen por **90 días** después de la expiración para fines de auditoría, y luego son limpiados automáticamente por un worker en segundo plano.

***

## Cómo funcionan los límites

***

Tracer evalúa los límites durante cada solicitud de validación.

### Flujo de verificación de límites

Cuando se valida una transacción, Tracer verifica todos los límites aplicables:

<Frame caption="Figura 1. Cómo funcionan los límites de gasto">
  <img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/es/d2/how-limits-works.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=a0c69572ef5a9ac9af7bbb92c0ecee65" alt="Cómo Tracer verifica todos los límites de gasto aplicables durante una solicitud de validación y actualiza sus contadores de uso" width="1224" height="284" data-path="images/es/d2/how-limits-works.svg" />
</Frame>

1. **Encontrar límites** - Consultar todos los límites activos que coinciden con el alcance de la transacción
2. **Verificar ventana de tiempo** - Si el límite tiene ventana de tiempo configurada, verificar que la **hora actual del servidor** esté dentro de `activeTimeStart`/`activeTimeEnd`. Si está fuera, el límite se **omite** (el `transactionTimestamp` provisto por el cliente no se usa aquí)
3. **Verificar período personalizado** - Si el límite es `CUSTOM`, verificar que la **hora actual del servidor** esté dentro de `customStartDate`/`customEndDate`. Si está fuera, el límite se **omite** (de nuevo, el `transactionTimestamp` no se usa)
4. **Calcular uso proyectado** - Agregar el monto de la transacción al uso actual
5. **Comparar umbral** - Verificar si el uso proyectado excede el monto del límite
6. **Devolver resultado** - Si algún límite aplicable es excedido — o alguna regla DENY coincide — Tracer devuelve una decisión DENY (tu sistema debe entonces bloquear la transacción)

<Note>
  Las verificaciones de límite e incrementos de contadores son **transaccionales**. Si una transacción es denegada (por límites o reglas) o marcada para revisión, todos los incrementos de contadores se revierten atómicamente. Esto previene fugas de límites por operaciones parciales.
</Note>

<Note>
  Cuando un límite se **omite** durante la evaluación, `limitUsageDetails[i]` incluye `skipped: true` y un campo `skipReason` con uno de dos valores:

  * `"outside_time_window"` — la hora actual del servidor está fuera de la ventana `activeTimeStart`/`activeTimeEnd` del límite
  * `"outside_custom_period"` — la hora actual del servidor está fuera del rango `customStartDate`/`customEndDate` del límite

  Los límites omitidos se reportan por transparencia pero **no** participan de la decisión DENY y sus contadores **no** se incrementan. La verificación de la ventana usa **hora del servidor**, no el `transactionTimestamp` provisto por el cliente, para prevenir ataques de manipulación de timestamp.
</Note>

<Info>
  **Por qué hora del servidor en vez de `transactionTimestamp`.** El cliente puede establecer `transactionTimestamp` con cualquier valor — incluyendo uno forjado para caer dentro de una ventana activa cuando la transacción real caería fuera. Si Tracer confiara en el reloj del cliente para enforcement de ventana de tiempo, cualquiera con acceso al payload podría burlar límites de horario restringido. Anclar la verificación al reloj del propio Tracer elimina esa superficie de ataque. La desventaja es que pequeños desvíos de reloj entre pods de Tracer pueden causar skips en casos de borda cerca del límite de la ventana; en la práctica, los relojes sincronizados vía NTP mantienen esto en milisegundos de un dígito.
</Info>

### Escenario de ejemplo

Un segmento corporativo tiene un límite diario de R\$ 50.000 (`"50000.00"`) para transacciones CARD.

Si el uso actual es R$ 45.000 y llega una nueva transacción de R$ 8.000:

* Uso proyectado: R$ 45.000 + R$ 8.000 = R\$ 53.000
* Límite: R\$ 50.000
* Resultado: Tracer devuelve decisión **DENY** (tu sistema debe bloquear la transacción)

***

## Crear un límite

***

Crea límites usando `POST /v1/limits`. Los límites se crean en estado `DRAFT` por defecto.

Un límite requiere:

* **name**: Un nombre descriptivo (ej.: "Límite Diario Tarjeta Corporativa")
* **limitType**: DAILY, WEEKLY, MONTHLY, CUSTOM o PER\_TRANSACTION
* **maxAmount**: Monto máximo como valor decimal (ej., `"50000.00"`)
* **currency**: Código de moneda ISO 4217 (ej.: BRL, USD)
* **scopes**: Al menos un alcance para definir a qué transacciones se aplica

Campos opcionales:

* **activeTimeStart**: Inicio de la ventana de tiempo diaria en formato `HH:MM` (ej.: `"09:00"`)
* **activeTimeEnd**: Fin de la ventana de tiempo diaria en formato `HH:MM` (ej.: `"17:00"`)
* **customStartDate**: Fecha de inicio para límites `CUSTOM` (timestamp ISO 8601, requerido para CUSTOM)
* **customEndDate**: Fecha de fin para límites `CUSTOM` (timestamp ISO 8601, requerido para CUSTOM)

<Note>
  Los nombres de límite deben ser globalmente únicos (entre todos los límites). La comparación de nombres ignora mayúsculas/minúsculas y espacios extra. Intentar crear o actualizar un límite con nombre duplicado devuelve respuesta `409 Conflict`.
</Note>

Para la estructura completa del payload y detalles de campos, consulta la [Referencia de API](/es/reference/tracer/create-limit).

***

## Listar y consultar límites

***

Consulta límites para gestión y auditoría usando `GET /v1/limits`.

### Parámetros de consulta

| Parámetro          | Tipo    | Descripción                                                                   |
| ------------------ | ------- | ----------------------------------------------------------------------------- |
| `name`             | string  | Filtrar por nombre (coincidencia parcial, no distingue mayúsculas)            |
| `status`           | string  | Filtrar por estado (DRAFT, ACTIVE, INACTIVE)                                  |
| `limit_type`       | string  | Filtrar por tipo de límite (DAILY, WEEKLY, MONTHLY, CUSTOM, PER\_TRANSACTION) |
| `account_id`       | string  | Filtrar por alcance: ID de cuenta                                             |
| `segment_id`       | string  | Filtrar por alcance: ID de segmento                                           |
| `portfolio_id`     | string  | Filtrar por alcance: ID de portafolio                                         |
| `merchant_id`      | string  | Filtrar por alcance: ID de comercio                                           |
| `transaction_type` | string  | Filtrar por alcance: tipo de transacción (CARD, WIRE, PIX, CRYPTO)            |
| `sub_type`         | string  | Filtrar por alcance: subtipo (ej., debit, credit)                             |
| `limit`            | integer | Elementos por página (predeterminado: 10, máx: 100)                           |
| `cursor`           | string  | Cursor de paginación                                                          |
| `sort_by`          | string  | Campo de ordenamiento: `createdAt`, `updatedAt`, `name`, `maxAmount`          |
| `sort_order`       | string  | Dirección de ordenamiento: `ASC`, `DESC` (predeterminado: DESC)               |

### Obtener un límite específico

Usa `GET /v1/limits/{id}` para recuperar la definición completa del límite incluyendo alcances y estado actual.

***

## Consultar uso del límite

***

Monitorea el consumo del límite usando `GET /v1/limits/{id}/usage`.

La respuesta incluye:

* **currentUsage**: Monto consumido en el período actual
* **utilizationPercent**: Porcentaje del límite utilizado
* **nearLimit**: True cuando `utilizationPercent > 80` — **estrictamente mayor que 80%**, no igual (para gestión proactiva)
* **resetAt**: Cuándo se reinicia el límite (solo DAILY, WEEKLY, MONTHLY y CUSTOM)

<Note>
  El indicador `nearLimit` queda en true cuando `utilizationPercent > 80` — estrictamente mayor que 80%, no igual — por lo que un uso exactamente en 80% aún no activa el flag.
</Note>

***

## Actualizar un límite

***

Actualiza límites usando `PATCH /v1/limits/{id}`. Los campos `limitType` y `currency` son inmutables y no pueden cambiarse después de la creación.

<Warning>
  Cambiar el monto del límite no reinicia el uso actual. Si reduces un límite por debajo del uso actual, las transacciones subsiguientes serán denegadas hasta que el período se reinicie.
</Warning>

***

## Ciclo de vida de los límites

***

Los límites siguen el mismo ciclo de vida que las reglas:

<Frame caption="Figura 2. Ciclo de vida de los límites">
  <img src="https://mintcdn.com/lerian-49cb71fc/ZrZBZTM4DWnrahSd/images/es/d2/rules-limits-lifecycle-tracer.svg?fit=max&auto=format&n=ZrZBZTM4DWnrahSd&q=85&s=7abfad053b78d3ca81f0783dfa91a2c8" alt="Ciclo de vida de las reglas y los límites en Tracer, con las transiciones de estado por las que pasa una definición desde su creación hasta su aplicación activa" width="531" height="1050" data-path="images/es/d2/rules-limits-lifecycle-tracer.svg" />
</Frame>

### Estados

| Estado     | Descripción                                                                                                       |
| ---------- | ----------------------------------------------------------------------------------------------------------------- |
| `DRAFT`    | Límite creado pero no activo; puede ser modificado libremente                                                     |
| `ACTIVE`   | El límite se verifica durante las validaciones                                                                    |
| `INACTIVE` | El límite no se verifica; preservado para el <GAuditTrail>rastro de auditoría</GAuditTrail>; puede ser reactivado |
| `DELETED`  | Eliminado permanentemente; no aparece en listados                                                                 |

### Transiciones

| Operación  | De              | A        | Descripción                                                    |
| ---------- | --------------- | -------- | -------------------------------------------------------------- |
| Crear      | -               | DRAFT    | Los límites se crean en estado DRAFT por defecto               |
| Activar    | DRAFT, INACTIVE | ACTIVE   | Iniciar verificación de este límite                            |
| Desactivar | ACTIVE          | INACTIVE | Dejar de verificar este límite                                 |
| Borrador   | INACTIVE        | DRAFT    | Devolver a borrador para edición                               |
| Eliminar   | DRAFT, INACTIVE | DELETED  | Eliminar permanentemente (no se puede eliminar límites ACTIVE) |

***

## Mejores prácticas

***

Recomendaciones para gestión efectiva de límites.

### Nomenclatura

* **Sé descriptivo** - Incluye el alcance y tipo en el nombre
* **Usa patrones consistentes** - ej., "Diario {Segmento} {Tipo} Límite"

| Menos claro  | Más claro                            |
| ------------ | ------------------------------------ |
| `Límite 1`   | `Límite Diario Tarjeta Corporativa`  |
| `Límite VIP` | `Límite Mensual PIX VIP`             |
| `Promo BF`   | `Límite Custom Black Friday Tarjeta` |

### Diseño de alcance

* **Comienza amplio, refina según sea necesario** - Comienza con límites a nivel de segmento, agrega a nivel de cuenta para excepciones
* **Evita alcances superpuestos** - Múltiples límites en el mismo alcance pueden causar confusión
* **Usa tipos de transacción** - Diferentes métodos de pago pueden necesitar diferentes límites

### Diseño de ventanas de tiempo

* **Usa para cumplimiento regulatorio** - Límites nocturnos de PIX del BACEN son un caso de uso común
* **Considera el impacto de zona horaria** - Las ventanas de tiempo usan UTC; considera el desfase horario de tus usuarios
* **Combina con períodos personalizados** - Usa ventanas de tiempo dentro de períodos personalizados para controles precisos de campañas

### Monitoreo

* **Observa los indicadores nearLimit** - Contacta proactivamente a los clientes que se acercan a los límites
* **Revisa las transacciones denegadas** - Tasas altas de denegación pueden indicar límites demasiado restrictivos
* **Ajusta estacionalmente** - Considera aumentos temporales de límites durante períodos de alto gasto o usa límites `CUSTOM` para rangos de fechas específicos

<Warning>
  **Tropezones comunes al trabajar con límites:**

  * **"Mi cliente está reportando sobregasto — debería haber chocado con el límite."** Verifica si el límite está `ACTIVE`. Un límite en DRAFT o INACTIVE no se evalúa. Confirma también que el alcance del límite realmente coincide con la transacción (segmento, tipo de transacción, etc.).
  * **"Mi PATCH bajó el límite pero las transacciones se siguen denegando incluso después del reset del período."** Bajar el límite no reinicia el contador. Si el uso actual ya está por encima del nuevo techo, las transacciones subsecuentes se denegarán hasta el próximo `resetAt`.
  * **"Intenté eliminar un límite ACTIVE y obtuve un 400."** Los límites ACTIVE no pueden ser eliminados — `POST /v1/limits/{id}/deactivate` primero, luego `DELETE /v1/limits/{id}`. Es intencional: previene eliminar accidentalmente un enforcement activo.
  * **"Mi indicador `nearLimit` no se está disparando al 80% aunque el uso está exactamente ahí."** El indicador usa estrictamente mayor (`utilizationPercent > 80`), por lo que un uso de exactamente 80% no lo activa.
</Warning>

***

## Referencia rápida

***

Endpoints y opciones de configuración clave.

### Endpoints

| Operación               | Método | Endpoint                     |
| ----------------------- | ------ | ---------------------------- |
| Crear límite            | POST   | `/v1/limits`                 |
| Listar límites          | GET    | `/v1/limits`                 |
| Obtener límite          | GET    | `/v1/limits/{id}`            |
| Actualizar límite       | PATCH  | `/v1/limits/{id}`            |
| Activar límite          | POST   | `/v1/limits/{id}/activate`   |
| Desactivar límite       | POST   | `/v1/limits/{id}/deactivate` |
| Mover límite a borrador | POST   | `/v1/limits/{id}/draft`      |
| Eliminar límite         | DELETE | `/v1/limits/{id}`            |
| Obtener uso             | GET    | `/v1/limits/{id}/usage`      |

Para la definición de los tipos de límite (DAILY, WEEKLY, MONTHLY, CUSTOM, PER\_TRANSACTION), los campos opcionales de ventana de tiempo y período personalizado, y la lista completa de campos de alcance, consulta [Tipos de límite](#tipos-de-l%C3%ADmites) anteriormente en esta guía y la [referencia de la API](/es/reference/tracer/create-limit) para detalles a nivel de schema.
