Spending limits are how product and risk teams cap exposure per customer, per segment, or per portfolio without writing code. Common use cases: a daily ceiling on card spending for retail customers, a monthly cap on a specific MCC, a campaign-window limit for a marketing promotion. What changes in your operation: spending caps stop being constants hardcoded in config files or scattered across services. They become versioned data with a clear lifecycle (DRAFT → ACTIVE → INACTIVE), they reset on the period boundary automatically, and they’re audit-trailed every time a transaction would have pushed past one. Trade-off to be honest about: counters need to stay consistent across replicas and races. Tracer handles that transactionally — if a transaction is denied or sent to REVIEW, the counter rolls back. You give up “local clever logic in each service” and gain a single, consistent number. Spending limits in Tracer let you control transaction amounts by scope (account, portfolio, segment) and period (daily, weekly, monthly, custom, or per-transaction). Limits are evaluated in real-time alongside rules, in the sameDocumentation Index
Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
Use this file to discover all available pages before exploring further.
POST /v1/validations call.
Why use spending limits
- Customer protection: Detect overspending and return DENY decisions for unauthorized large transactions
- Risk management: Monitor exposure per account, segment, or portfolio
- Flexible scoping: Apply limits at different granularity levels
- Real-time tracking: Monitor usage and remaining amounts instantly
- Automatic resets: Daily, weekly, monthly, and custom limits reset automatically
- Time windows: Restrict limit enforcement to specific hours of the day
- Custom periods: Define date-bound limits for campaigns, promotions, or compliance requirements
- Understand limit types, time windows, and scoping options
- Create and configure spending limits with period-based controls
- Monitor limit usage in real-time
- Manage the limit lifecycle
Core concepts
Understand the building blocks of spending limits.
Limit types
Tracer supports five types of spending limits:| Type | Description | Reset behavior |
|---|---|---|
DAILY | Maximum amount per day | Resets at midnight UTC |
WEEKLY | Maximum amount per week | Resets every Monday at 00:00 UTC |
MONTHLY | Maximum amount per month | Resets on 1st of month, midnight UTC |
CUSTOM | Maximum amount within a user-defined date range | Resets at customEndDate + 1 day at midnight UTC |
PER_TRANSACTION | Maximum amount per single transaction | No tracking; each transaction evaluated independently |
Time windows
Time windows restrict when a limit is enforced during the day. When a transaction occurs outside the configured time window, the limit is skipped (not enforced) and the transaction is allowed to proceed without counting against that limit.- Format:
HH:MM(24-hour, UTC) - Both fields required: If
activeTimeStartis set,activeTimeEndmust also be set (and vice versa) - Half-open interval: Start is inclusive, end is exclusive
[start, end) - Overnight windows supported: Setting
activeTimeStart: "20:00"andactiveTimeEnd: "06:00"creates a window from 8 PM to 6 AM UTC
Time windows can be applied to any limit type (DAILY, WEEKLY, MONTHLY, CUSTOM, or PER_TRANSACTION). If no time window is configured, the limit is active 24/7.
limitType:DAILYmaxAmount:"1000.00"activeTimeStart:"20:00"activeTimeEnd:"06:00"- Scope: PIX transactions
Custom periods
Custom periods define a date range during which a limit is active. This is useful for campaigns, promotions, seasonal events, or compliance requirements with specific date boundaries.- Required fields:
customStartDateandcustomEndDate(only forCUSTOMtype) - Half-open interval: Start is inclusive, end is exclusive
[start, end) - Maximum duration: 5 years
- Cannot be in the past: The
customEndDatemust not be entirely before the current date
limitType:CUSTOMmaxAmount:"100000.00"customStartDate:"2026-11-25T00:00:00Z"customEndDate:"2026-11-30T00:00:00Z"- Scope: CARD transactions in the retail segment
Combining time windows and custom periods
Time windows and custom periods can be used together onCUSTOM limits. When combined, a transaction must be within both the custom period and the time window to be evaluated against the limit.
For example, a CUSTOM limit with customStartDate Nov 25 to customEndDate Nov 30 and a time window of 09:00 to 18:00 would only enforce the limit during business hours within the Black Friday period.
Scopes
Scopes define which transactions a limit applies to. Unlike rules, every limit must have at least one scope object — limits cannot be global. Within a single scope object, the supported fields are:segmentId- Apply to transactions from a specific segmentportfolioId- Apply to transactions from a specific portfolioaccountId- Apply to transactions from a specific accountmerchantId- Apply to transactions to a specific merchanttransactionType- Apply to specific transaction types (CARD, WIRE, PIX, CRYPTO)subType- Apply to a specific transaction subtype (e.g.,debit,credit)
- Within one scope object: fields combine with AND. A field that is not specified is treated as a wildcard (matches any value). At least one field must be set — empty scope objects (
{}) are rejected with TRC-0125. - Across multiple scope objects on the same limit: they combine with OR. The limit applies if any scope object matches the transaction.
Usage tracking
ForDAILY, WEEKLY, MONTHLY, and CUSTOM limits, Tracer tracks:
- Current usage - Total amount consumed in the current period (as a decimal value)
- Utilization percent - Percentage of limit used
- Reset time - When the limit will reset to zero
How limits work
Tracer evaluates limits during every validation request.
Limit check flow
When a transaction is validated, Tracer checks all applicable limits:
- Find limits - Query all active limits matching the transaction scope
- Check time window - If the limit has a time window configured, verify the current server time falls within
activeTimeStart/activeTimeEnd. If outside, the limit is skipped (the client-suppliedtransactionTimestampis not used here) - Check custom period - If the limit is
CUSTOM, verify the current server time falls withincustomStartDate/customEndDate. If outside, the limit is skipped (again,transactionTimestampis not used) - Calculate projected usage - Add transaction amount to current usage
- Compare threshold - Check if projected usage exceeds limit amount
- Return result - If any applicable limit is exceeded — or any DENY rule matches — Tracer returns a DENY decision (your system should then block the transaction)
Limit checks and counter increments are transactional. If a transaction is denied (by limits or rules) or flagged for review, all counter increments are rolled back atomically. This prevents limit leakage from partial operations.
When a limit is skipped during evaluation,
limitUsageDetails[i] includes skipped: true and a skipReason field with one of two values:"outside_time_window"— current server time is outside the limit’sactiveTimeStart/activeTimeEndwindow"outside_custom_period"— current server time is outside the limit’scustomStartDate/customEndDaterange
transactionTimestamp, to prevent timestamp-manipulation attacks.Why server time instead of
transactionTimestamp. The client can set transactionTimestamp to whatever they want — including a value crafted to fall inside an active window when the real transaction would fall outside it. If Tracer trusted the client clock for time-window enforcement, anyone with access to the payload could bypass off-hours limits. Pinning the window check to Tracer’s own clock removes that attack surface. The downside is that small clock drift between Tracer pods can cause edge-case skips around the window boundary; in practice, Tracer’s NTP-synced clocks keep this in single-digit milliseconds.Example scenario
A corporate segment has a daily limit of R$ 50,000 ("50000.00") for CARD transactions.
If current usage is R 8,000 arrives:
- Projected usage: R 8,000 = R$ 53,000
- Limit: R$ 50,000
- Result: Tracer returns DENY decision (your system should block the transaction)
Create a limit
Create limits using
POST /v1/limits. Limits are created in DRAFT status by default.
A limit requires:
- name: A descriptive name (e.g., “Daily Corporate Card Limit”)
- limitType: DAILY, WEEKLY, MONTHLY, CUSTOM, or PER_TRANSACTION
- maxAmount: Maximum amount as a decimal value (e.g.,
"50000.00") - currency: ISO 4217 currency code (e.g., BRL, USD)
- scopes: At least one scope to define which transactions it applies to
- activeTimeStart: Start of the daily time window in
HH:MMformat (e.g.,"09:00") - activeTimeEnd: End of the daily time window in
HH:MMformat (e.g.,"17:00") - customStartDate: Start date for
CUSTOMlimits (ISO 8601 timestamp, required for CUSTOM) - customEndDate: End date for
CUSTOMlimits (ISO 8601 timestamp, required for CUSTOM)
Limit names must be globally unique (across all limits). Name comparison is case-insensitive and ignores extra whitespace. Attempting to create or update a limit with a duplicate name returns a
409 Conflict response.List and query limits
Query limits for management and auditing using
GET /v1/limits.
Query parameters
| Parameter | Type | Description |
|---|---|---|
name | string | Filter by name (case-insensitive partial match) |
status | string | Filter by status (DRAFT, ACTIVE, INACTIVE) |
limit_type | string | Filter by limit type (DAILY, WEEKLY, MONTHLY, CUSTOM, PER_TRANSACTION) |
account_id | string | Filter by scope: account ID |
segment_id | string | Filter by scope: segment ID |
portfolio_id | string | Filter by scope: portfolio ID |
merchant_id | string | Filter by scope: merchant ID |
transaction_type | string | Filter by scope: transaction type (CARD, WIRE, PIX, CRYPTO) |
sub_type | string | Filter by scope: subtype (e.g., debit, credit) |
limit | integer | Items per page (default: 10, max: 100) |
cursor | string | Pagination cursor |
sort_by | string | Sort field: created_at, updated_at, name, max_amount |
sort_order | string | Sort direction: ASC, DESC (default: DESC) |
Get a specific limit
UseGET /v1/limits/{id} to retrieve the full limit definition including scopes and current status.
Query limit usage
Monitor limit consumption using
GET /v1/limits/{id}/usage.
The response includes:
- currentUsage: Amount consumed in current period
- utilizationPercent: Percentage of limit used
- nearLimit: True when
utilizationPercent > 80— strictly greater than 80%, not equal (for proactive management) - resetAt: When the limit resets (DAILY, WEEKLY, MONTHLY, and CUSTOM only)
The
nearLimit flag turns true when utilizationPercent > 80 — strictly greater than 80%, not equal — so usage at exactly 80% does not yet trip the flag.Update a limit
Update limits using
PATCH /v1/limits/{id}. The limitType and currency fields are immutable and cannot be changed after creation.
Limit lifecycle
Limits follow the same lifecycle as rules:

States
| State | Description |
|---|---|
DRAFT | Limit created but not active; can be modified freely |
ACTIVE | Limit is checked during validations |
INACTIVE | Limit is not checked; preserved for ; can be reactivated |
DELETED | Permanently removed; does not appear in listings |
Transitions
| Operation | From | To | Description |
|---|---|---|---|
| Create | - | DRAFT | Limits are created in DRAFT status by default |
| Activate | DRAFT, INACTIVE | ACTIVE | Start checking this limit |
| Deactivate | ACTIVE | INACTIVE | Stop checking this limit |
| Draft | INACTIVE | DRAFT | Return to draft for editing |
| Delete | DRAFT, INACTIVE | DELETED | Permanently remove (cannot delete ACTIVE limits) |
Best practices
Recommendations for effective limit management.
Naming
- Be descriptive - Include the scope and type in the name
- Use consistent patterns - e.g., “Daily Limit”
| Less clear | More clear |
|---|---|
Limit 1 | Daily Corporate Card Limit |
VIP limit | Monthly VIP PIX Limit |
BF promo | Custom Black Friday Card Limit |
Scope design
- Start broad, refine as needed - Begin with segment-level limits, add account-level for exceptions
- Avoid overlapping scopes - Multiple limits on the same scope can cause confusion
- Use transaction types - Different payment methods may need different limits
Time window design
- Use for regulatory compliance - BACEN nighttime PIX limits are a common use case
- Consider timezone impact - Time windows use UTC; account for your users’ local timezone offset
- Combine with custom periods - Use time windows inside custom periods for precise campaign controls
Monitoring
- Watch nearLimit flags - Proactively contact customers nearing limits
- Review denied transactions - High denial rates may indicate limits are too restrictive
- Adjust seasonally - Consider temporary limit increases during high-spending periods or use
CUSTOMlimits for specific date ranges
Quick reference
Key endpoints and configuration options.
Endpoints
| Operation | Method | Endpoint |
|---|---|---|
| Create limit | POST | /v1/limits |
| List limits | GET | /v1/limits |
| Get limit | GET | /v1/limits/{id} |
| Update limit | PATCH | /v1/limits/{id} |
| Activate limit | POST | /v1/limits/{id}/activate |
| Deactivate limit | POST | /v1/limits/{id}/deactivate |
| Draft limit | POST | /v1/limits/{id}/draft |
| Delete limit | DELETE | /v1/limits/{id} |
| Get usage | GET | /v1/limits/{id}/usage |

