> ## 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.

# Limites de gastos

> Configure limites de gastos do Tracer por conta, portfólio ou segmento, com períodos diário, semanal, mensal e personalizado, janelas de tempo e controles de ciclo de vida.

Limites de gastos são como times de produto e de risco limitam a exposição por cliente, por segmento ou por portfólio sem escrever código. Casos de uso comuns: um teto diário para gastos com cartão de clientes de varejo, um teto mensal para um MCC específico, um limite de janela de campanha para uma promoção de marketing.

**O que muda na sua operação:** os tetos de gastos deixam de existir como constantes fixas em arquivos de configuração ou espalhadas entre serviços. Eles passam a ser dados versionados com um ciclo de vida claro (DRAFT → ACTIVE → INACTIVE). Cada novo período começa a contar do zero, e cada um é registrado na trilha de auditoria toda vez que uma transação teria ultrapassado um deles.

**Contrapartida:** os contadores precisam se manter consistentes entre réplicas e condições de corrida. O Tracer trata isso de forma transacional. Se o Tracer nega uma transação ou a envia para REVIEW, o contador é revertido. Você abre mão da "lógica local inteligente em cada serviço" e ganha um número único e consistente.

> [!TIP]
>
> Este guia é para gerentes de produto configurando tetos, times de risco revisando exposição, compliance auditando o que o Tracer negou, e desenvolvedores integrando a chamada de validação. A seção Tipos de limite não pressupõe conhecimento de API. As seções de ciclo de vida e PATCH pressupõem REST básico.

**Limites de gastos** no Tracer permitem controlar valores de transação por escopo (conta, portfólio, segmento) e período (diário, semanal, mensal, personalizado ou por transação). O Tracer avalia limites em tempo real junto com regras, na mesma chamada `POST /v1/validations`.

## Por que usar limites de gastos

***

* **Proteção ao cliente**: detecta gastos excessivos e retorna decisões DENY para transações grandes não autorizadas
* **Gestão de risco**: monitora a exposição por conta, segmento ou portfólio
* **Escopo flexível**: aplica limites em diferentes níveis de granularidade
* **Contagem por período**: limites diários, semanais e mensais começam uma nova contagem a cada fronteira de período
* **Janelas de tempo**: restringe a aplicação do limite a horas específicas do dia
* **Períodos personalizados**: define limites com datas fixas para campanhas, promoções ou exigências de compliance

Ao final deste guia, você vai:

* Entender tipos de limite, janelas de tempo e opções de escopo
* Criar e configurar limites de gastos com controles baseados em período
* Monitorar o uso de limites em tempo real
* Gerenciar o ciclo de vida do limite

***

## Conceitos básicos

***

Entenda os blocos de construção dos limites de gastos.

### Tipos de limite

O Tracer aceita cinco tipos de limites de gastos:

| Tipo | Descrição | Contagem por período |
| - | - | - |
| `DAILY` | Valor máximo por dia | Uma nova contagem começa a cada dia no horário de reinício (00:00 UTC por padrão) |
| `WEEKLY` | Valor máximo por semana | Uma nova contagem começa a cada segunda-feira no horário de reinício (00:00 UTC por padrão) |
| `MONTHLY` | Valor máximo por mês | Uma nova contagem começa no dia 1º do mês no horário de reinício (00:00 UTC por padrão) |
| `CUSTOM` | Valor máximo dentro de um intervalo de datas definido pelo usuário | Uma contagem para todo o intervalo; a partir de `customEndDate`, o Tracer para de conferir o limite |
| `PER_TRANSACTION` | Valor máximo por transação individual | Nenhuma contagem é mantida; cada transação é conferida por conta própria |

### Horário de reinício

`resetTime` move o início de cada período `DAILY`, `WEEKLY` e `MONTHLY` para outro horário do dia, no formato `HH:MM` (24 horas, UTC). Sem ele, cada período começa às 00:00 UTC. Defina-o ao criar o limite. Você não pode alterá-lo depois.

O Tracer rejeita `resetTime` em um limite `CUSTOM` ou `PER_TRANSACTION` com o código de erro `0537`. Quando o limite tem uma janela de tempo, `resetTime` não deve cair dentro da janela. Ele pode ser igual a `activeTimeStart` ou `activeTimeEnd`. Um horário de reinício dentro da janela retorna o código de erro `0538`.

### Janelas de tempo

Janelas de tempo restringem quando o Tracer aplica um limite durante o dia. Quando uma transação ocorre fora da janela de tempo configurada, o Tracer pula o limite e não o aplica. A transação prossegue sem contar contra esse limite.

* **Formato**: `HH:MM` (24 horas, UTC)
* **Os dois campos são obrigatórios**: se você define `activeTimeStart`, deve definir também `activeTimeEnd` (e vice-versa)
* **Intervalo semiaberto**: o início é inclusivo, o fim é exclusivo `[start, end)`
* **Janelas noturnas aceitas**: definir `activeTimeStart: "20:00"` e `activeTimeEnd: "06:00"` cria uma janela das 8 da noite às 6 da manhã, UTC

> [!NOTE]
>
> Você pode aplicar janelas de tempo a qualquer tipo de limite (DAILY, WEEKLY, MONTHLY, CUSTOM ou PER\_TRANSACTION). Sem uma janela de tempo, o limite fica ativo 24/7.

**Exemplo: compliance em Pix**

Uma instituição financeira precisa aplicar limites de transferência Pix mais baixos durante o período noturno. O período noturno do Pix vai das 20:00 às 06:00 no horário de Brasília (UTC-3), ou seja, das 23:00 às 09:00 UTC:

* `limitType`: `DAILY`
* `maxAmount`: `"1000.00"`
* `activeTimeStart`: `"23:00"`
* `activeTimeEnd`: `"09:00"`
* `resetTime`: `"09:00"`
* Escopo: transações Pix

O Tracer confere transações entre 23:00 e 09:00 UTC contra o limite de R\$ 1.000. Esse limite não afeta transações fora dessa janela.

`resetTime: "09:00"` começa cada contagem diária quando a janela fecha. Sem ele, a contagem reinicia às 00:00 UTC (21:00 em Brasília), no meio da janela. Um cliente pode então gastar os R\$ 1.000 inteiros antes das 21:00 no horário de Brasília e de novo depois.

> [!WARNING]
>
> Atualize todos os pods do Tracer para o Midaz v4.2.0 ou posterior antes de criar um limite com `resetTime`. Um pod em uma versão anterior aceita a requisição, mas descarta o campo. Até que todos os pods rodem a v4.2.0, um pod anterior ainda reinicia a contagem às 00:00 UTC.

### Períodos personalizados

Períodos personalizados definem um intervalo de datas durante o qual um limite fica ativo. Isso é útil para campanhas, promoções, eventos sazonais ou exigências de compliance com fronteiras de data específicas.

* **Campos obrigatórios**: `customStartDate` e `customEndDate` (apenas para o tipo `CUSTOM`)
* **Intervalo semiaberto**: o início é inclusivo, o fim é exclusivo `[start, end)`
* **Duração máxima**: 5 anos
* **Não pode estar no passado**: `customEndDate` não deve estar inteiramente antes da data atual

> [!WARNING]
>
> Os campos `customStartDate` e `customEndDate` são obrigatórios para limites `CUSTOM` e proibidos para os demais tipos de limite.

**Exemplo: campanha de Black Friday**

Um varejista quer definir um limite de gastos especial para o período da Black Friday:

* `limitType`: `CUSTOM`
* `maxAmount`: `"100000.00"`
* `customStartDate`: `"2026-11-25T00:00:00Z"`
* `customEndDate`: `"2026-11-30T00:00:00Z"`
* Escopo: transações CARD no segmento de varejo

O uso se acumula em toda a janela em uma única contagem. A partir de `customEndDate`, o Tracer para de conferir o limite.

### Combinando janelas de tempo e períodos personalizados

Você pode usar janelas de tempo e períodos personalizados juntos em limites `CUSTOM`. O Tracer então confere uma transação contra o limite apenas quando ela cai dentro tanto do período personalizado quanto da janela de tempo.

Por exemplo, tome um limite `CUSTOM` com `customStartDate` de 25 de novembro a `customEndDate` de 30 de novembro e uma janela de tempo de `09:00` a `18:00`. O Tracer aplica esse limite apenas durante o horário comercial dentro do período da Black Friday.

### Escopos

Escopos definem a quais transações um limite se aplica. Diferente das regras, todo limite deve ter pelo menos um objeto de escopo. Limites não podem ser globais.

Dentro de um único objeto de escopo, os campos aceitos são:

* `segmentId`: aplica-se a transações de um segmento específico
* `portfolioId`: aplica-se a transações de um portfólio específico
* `accountId`: aplica-se a transações de uma conta específica
* `merchantId`: aplica-se a transações para um comerciante específico
* `scheme`: aplica-se a um esquema de pagamento, como `CARD` ou `PIX`. `transactionType` é o nome obsoleto desse campo
* `subType`: aplica-se a um subtipo de transação específico (por exemplo, `debit`, `credit`)

**Semântica de correspondência:**

* **Dentro de um objeto de escopo:** os campos se combinam com AND. Um campo que você omite funciona como curinga (corresponde a qualquer valor). Você deve definir pelo menos um campo. O Tracer rejeita objetos de escopo vazios (`{}`) com o código de erro `0009`.
* **Entre vários objetos de escopo no mesmo limite:** eles se combinam com OR. O limite se aplica se qualquer objeto de escopo corresponder à transação.

**Não há hierarquia entre limites.** Uma transação pode corresponder a vários limites, por exemplo um limite de nível de conta e um de nível de segmento. O Tracer então confere todos os limites aplicáveis de forma independente em uma única transação. Se a transação excede qualquer limite aplicável, o Tracer a nega. O Tracer não confere nenhum limite quando uma regra retorna `DENY` ou quando a requisição usa `POST /v1/validations/rules-only`.

### Rastreamento de uso

Para limites `DAILY`, `WEEKLY`, `MONTHLY` e `CUSTOM`, o Tracer mantém um contador de uso por limite, por escopo correspondido, por período. A decisão de validação reporta esse contador. Veja [Ler o consumo](#read-consumption).

Para contadores `DAILY`, `WEEKLY` e `MONTHLY`, `expiresAt` é 90 dias após o reset do período. Para contadores `CUSTOM`, é 90 dias após `customEndDate`. Contadores expirados ficam elegíveis para limpeza. A exclusão física exige um worker de limpeza habilitado que execute com sucesso.

***

## Como os limites funcionam

***

O Tracer avalia limites durante requisições de validação.

### Fluxo de conferência de limite

![Como o Tracer confere os limites de gastos aplicáveis durante uma requisição de validação e atualiza seus contadores de uso](https://mintcdn.com/lerian-49cb71fc/vdBt8wfgjsNRO1rf/images/pt/d2/how-limits-works.svg?fit=max\&auto=format\&n=vdBt8wfgjsNRO1rf\&q=85\&s=116c53171edaff7951f67a08e76b5fd4)

Figura 1. Como funcionam os limites de gastos

1. **Encontrar limites**: consulta todos os limites ativos que correspondem ao escopo da transação
2. **Conferir a janela de tempo**: se o limite tem uma janela de tempo configurada, verifica se o horário atual do servidor cai dentro de `activeTimeStart`/`activeTimeEnd`. Se estiver fora, o Tracer pula o limite (ele não usa o `transactionTimestamp` fornecido pelo cliente aqui)
3. **Conferir o período personalizado**: se o limite é `CUSTOM`, verifica se o horário atual do servidor cai dentro de `customStartDate`/`customEndDate`. Se estiver fora, o Tracer pula o limite (de novo, não usa `transactionTimestamp`)
4. **Calcular o uso projetado**: soma o valor da transação ao uso atual
5. **Comparar com o limite**: verifica se o uso projetado excede o valor do limite
6. **Retornar o resultado**: se a transação excede qualquer limite aplicável, ou qualquer regra DENY corresponde, o Tracer retorna uma decisão DENY (seu sistema deve então bloquear a transação)

> [!NOTE]
>
> As conferências de limite e os incrementos de contador são transacionais. Se o Tracer nega uma transação (por limites ou regras) ou a sinaliza para revisão, ele reverte todos os incrementos de contador de forma atômica. Isso evita vazamento de limite por operações parciais.

> [!NOTE]
>
> Quando o Tracer pula um limite durante a avaliação, `limitUsageDetails[i]` inclui `skipped: true` e um campo `skipReason` com um de dois valores:
>
> * `"outside_time_window"`: o horário atual do servidor está fora da janela `activeTimeStart`/`activeTimeEnd` do limite
> * `"outside_custom_period"`: o horário atual do servidor está fora do intervalo `customStartDate`/`customEndDate` do limite
>
> O Tracer reporta limites pulados para fins de transparência, mas eles não participam da decisão DENY, e seus contadores não são incrementados. A conferência da janela usa o horário do servidor, não o `transactionTimestamp` fornecido pelo cliente, para evitar ataques de manipulação de timestamp.

> [!NOTE]
>
> **Por que o horário do servidor em vez do `transactionTimestamp`.** O cliente pode definir `transactionTimestamp` como quiser. Isso inclui um valor forjado para cair dentro de uma janela ativa quando a transação real cairia fora dela. Se o Tracer confiasse no relógio do cliente para aplicar a janela de tempo, qualquer um com acesso ao payload poderia contornar limites de horário restrito. Fixar a conferência da janela no próprio relógio do Tracer elimina essa superfície de ataque. A desvantagem é que uma pequena variação de relógio entre pods do Tracer pode causar pulos em casos extremos perto da fronteira da janela.

### Cenário de exemplo

Um segmento corporativo tem um limite diário de R\$ 50.000 (`"50000.00"`) para transações CARD.

Se o uso atual é R$ 45.000 e chega uma nova transação de R$ 8.000:

* Uso projetado: R$ 45.000 + R$ 8.000 = R\$ 53.000
* Limite: R\$ 50.000
* Resultado: o Tracer retorna a decisão DENY (seu sistema deve bloquear a transação)

***

## Criar um limite

***

Crie limites usando `POST /v1/limits`. Por padrão, o Tracer cria limites com status `DRAFT`.

Um limite requer:

* **name**: um nome descritivo (por exemplo, "Daily Corporate Card Limit")
* **limitType**: DAILY, WEEKLY, MONTHLY, CUSTOM ou PER\_TRANSACTION
* **maxAmount**: valor máximo como um valor decimal (por exemplo, `"50000.00"`). Não pode ser negativo. Um `maxAmount` de `0` nega todas as transações no escopo do limite.
* **asset**: código de ativo de 1 a 100 letras maiúsculas (por exemplo, BRL, USD)
* **scopes**: pelo menos um escopo para definir a quais transações se aplica

Campos opcionais:

* **activeTimeStart**: início da janela de tempo diária no formato `HH:MM` (por exemplo, `"09:00"`)
* **activeTimeEnd**: fim da janela de tempo diária no formato `HH:MM` (por exemplo, `"17:00"`)
* **customStartDate**: data de início para limites `CUSTOM` (timestamp ISO 8601, obrigatório para CUSTOM)
* **customEndDate**: data de fim para limites `CUSTOM` (timestamp ISO 8601, obrigatório para CUSTOM)
* **resetTime**: início de cada período `DAILY`, `WEEKLY` ou `MONTHLY` no formato `HH:MM` (por exemplo, `"09:00"`)

> [!NOTE]
>
> Os nomes de limite devem ser únicos entre os seus limites não excluídos, diferente dos nomes de regra, que são únicos apenas dentro do contexto do seu escopo. O Tracer aplica a unicidade sobre o nome exatamente como armazenado, depois de remover espaços em branco do início e do fim. A comparação diferencia maiúsculas de minúsculas e não condensa espaços em branco dentro do nome, então `Daily Card Limit` e `daily card limit` são dois limites distintos, ambos aceitáveis. Excluir um limite libera o nome para reutilização. Uma colisão retorna `409 Conflict` com o código de erro `0442`.

Para a estrutura completa do payload e detalhes de campo, veja a [referência da API](https://docs.lerian.studio/pt/reference/products/tracer/create-limit.md).

***

## Listar e consultar limites

***

Consulte limites para gestão e auditoria usando `GET /v1/limits`.

### Parâmetros de consulta

| Parâmetro | Tipo | Descrição |
| - | - | - |
| `name` | string | filtra por nome (correspondência parcial, sem diferenciar maiúsculas de minúsculas) |
| `status` | string | filtra por status (DRAFT, ACTIVE, INACTIVE) |
| `limit_type` | string | filtra por tipo de limite (DAILY, WEEKLY, MONTHLY, CUSTOM, PER\_TRANSACTION) |
| `account_id` | string | filtra por escopo: id da conta |
| `segment_id` | string | filtra por escopo: id do segmento |
| `portfolio_id` | string | filtra por escopo: id do portfólio |
| `merchant_id` | string | filtra por escopo: id do comerciante |
| `scheme` | string | filtra por escopo: esquema de pagamento, como `CARD` ou `PIX`. `transaction_type` é o nome obsoleto desse filtro |
| `sub_type` | string | filtra por escopo: subtipo (por exemplo, debit, credit) |
| `limit` | integer | itens por página (padrão: 10, máximo: 100) |
| `cursor` | string | cursor de paginação |
| `sort_by` | string | campo de ordenação: `created_at`, `updated_at`, `name`, `max_amount` |
| `sort_order` | string | direção de ordenação: `ASC`, `DESC` (padrão: DESC) |

### Obter um limite específico

Use `GET /v1/limits/{id}` para obter a definição completa do limite, incluindo escopos e status atual.

***

## Ler o consumo

***

### A partir da decisão

Toda resposta bem-sucedida de `POST /v1/validations`, `201` ou `200`, carrega `limitUsageDetails`. Cada entrada reporta:

* **limitId** e **limitAmount**: qual teto o Tracer conferiu, e seu valor máximo
* **currentUsage**: o consumo projetado do período atual e do escopo correspondido desse teto, se o Tracer permitir esta transação. Ele inclui a capacidade retida por reservas não confirmadas do ledger do Midaz. Para um limite `PER_TRANSACTION`, ou um limite que o Tracer ignorou, ele é `0`
* **attemptedAmount**: o valor conferido contra o teto
* **exceeded**: se o valor tentado levaria este teto a ultrapassar seu valor máximo. O Tracer avalia todo teto, então mais de uma entrada pode carregar `exceeded: true`, e qualquer uma delas produz o DENY

### A partir do limite

`GET /v1/limits/{id}/usage` reporta o período atual do limite. Seu `currentUsage` é o que o escopo mais consumido usou nesse período, incluindo a capacidade retida por reservas não confirmadas do ledger do Midaz. Para um limite `PER_TRANSACTION`, ele é `0`.

Para um limite com `maxAmount` de `0`, `utilizationPercent` é `100` e `nearLimit` é `true`.

***

## Atualizar um limite

***

Atualize limites usando `PATCH /v1/limits/{id}`. Os campos `limitType`, `asset` e `resetTime` são imutáveis. Você não pode alterá-los após a criação.

> [!WARNING]
>
> Alterar o valor do limite não limpa a contagem atual. Se você reduzir um limite abaixo do que o período atual já consumiu, o Tracer nega as transações seguintes até o próximo período começar.

***

## Ciclo de vida do limite

***

Limites seguem o mesmo ciclo de vida das regras:

![Ciclo de vida de regras e limites no Tracer, mostrando as transições de status pelas quais uma definição passa desde a criação até a aplicação ativa](https://mintcdn.com/lerian-49cb71fc/TGLv2g3qhXqf0dqb/images/pt/d2/rules-limits-lifecycle-tracer.svg?fit=max\&auto=format\&n=TGLv2g3qhXqf0dqb\&q=85\&s=dd2a8bcdc09f13bfa1f595facd3f8857)

Figura 2. Ciclo de vida dos limites de gastos

### Estados

| Estado | Descrição |
| - | - |
| `DRAFT` | limite criado mas não ativo; pode ser modificado livremente |
| `ACTIVE` | o limite é conferido durante as validações |
| `INACTIVE` | o limite não é conferido; preservado para a trilha de auditoria (Um registro cronológico e imutável de cada ação e transação no sistema, essencial para conformidade regulatória e resolução de disputas.); pode ser reativado |
| `DELETED` | limite excluído; não aparece nas listagens e não pode ser reativado |

### Transições

| Operação | De | Para | Descrição |
| - | - | - | - |
| Criar | - | DRAFT | por padrão, os limites são criados com status DRAFT |
| Ativar | DRAFT, INACTIVE | ACTIVE | começa a conferir este limite |
| Desativar | ACTIVE | INACTIVE | para de conferir este limite |
| Rascunho | INACTIVE | DRAFT | retorna para rascunho para edição |
| Excluir | DRAFT, INACTIVE | DELETED | exclui este limite (não é possível excluir limites ACTIVE) |

***

## Boas práticas

***

Recomendações para uma gestão eficaz de limites.

### Nomenclatura

* **Seja descritivo**: inclua o escopo e o tipo no nome
* **Use padrões consistentes**: por exemplo, "Daily {Segment} {Type} Limit"

| Menos claro | Mais claro |
| - | - |
| `Limit 1` | `Daily Corporate Card Limit` |
| `VIP limit` | `Monthly VIP Pix Limit` |
| `BF promo` | `Custom Black Friday Card Limit` |

### Design de escopo

* **Comece amplo, refine conforme necessário**: comece com limites de nível de segmento, adicione nível de conta para exceções
* **Evite escopos sobrepostos**: vários limites no mesmo escopo podem gerar confusão
* **Use esquemas de pagamento**: métodos de pagamento diferentes podem precisar de limites diferentes

### Design de janela de tempo

* **Use para compliance regulatório**: os limites noturnos de Pix do BACEN são um caso de uso comum
* **Considere o impacto do fuso horário**: janelas de tempo usam UTC. Leve em conta o deslocamento do fuso horário local dos seus usuários
* **Combine com períodos personalizados**: use janelas de tempo dentro de períodos personalizados para controles precisos de campanha

### Monitoramento

* **Revise as transações negadas**: taxas altas de negação podem indicar que os limites estão restritivos demais
* **Ajuste sazonalmente**: considere aumentos temporários de limite durante períodos de gasto alto, ou use limites `CUSTOM` para intervalos de data específicos

> [!WARNING]
>
> **Armadilhas comuns ao trabalhar com limites:**
>
> * **"Meu cliente está reportando gasto excessivo. Ele deveria ter batido no limite."** Confira se o limite está `ACTIVE`. O Tracer não avalia um limite em estado DRAFT ou INACTIVE. Confirme também que o escopo do limite realmente corresponde à transação (segmento, esquema de pagamento etc.).
> * **"Meu PATCH diminuiu o limite, mas as transações continuam sendo negadas."** Diminuir o limite não limpa a contagem. Se o período atual já consumiu mais do que o novo teto, o Tracer nega as transações seguintes até o próximo período começar.
> * **"Tentei excluir um limite ACTIVE e fui rejeitado."** A exclusão volta `422` com o código `0363`. Envie `POST /v1/limits/{id}/deactivate` primeiro, depois `DELETE /v1/limits/{id}`. Isso é intencional: evita remover uma aplicação ativa por acidente.

***

## Referência rápida

***

Principais endpoints e opções de configuração.

### Endpoints

| Operação | Método | Endpoint |
| - | - | - |
| Criar limite | POST | `/v1/limits` |
| Listar limites | GET | `/v1/limits` |
| Obter limite | GET | `/v1/limits/{id}` |
| Atualizar limite | PATCH | `/v1/limits/{id}` |
| Ativar limite | POST | `/v1/limits/{id}/activate` |
| Desativar limite | POST | `/v1/limits/{id}/deactivate` |
| Rascunhar limite | POST | `/v1/limits/{id}/draft` |
| Excluir limite | DELETE | `/v1/limits/{id}` |
| Obter uso | GET | `/v1/limits/{id}/usage` |

Para as definições de tipo de limite (DAILY, WEEKLY, MONTHLY, CUSTOM, PER\_TRANSACTION), veja [Tipos de limite](#limit-types) anteriormente neste guia. O mesmo guia cobre os campos opcionais de janela de tempo e de período personalizado e a lista completa de campos de escopo. A [referência da API](https://docs.lerian.studio/pt/reference/products/tracer/create-limit.md) tem detalhes em nível de esquema.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.