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: Every decision reports how much of each cap it consumed
- Period counting: Daily, weekly, and monthly limits start a new count at each period boundary
- 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: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
customEndDate onward, Tracer stops checking the limit.
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 error code0009. - 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 keeps one usage counter per limit, per matched scope, per period. The validation decision reports that counter — see Read consumption.
A counter is kept for 90 days after its period ends, then a background worker deletes it.
How limits work
Tracer evaluates limits during every validation request.
Limit check flow
When a transaction is validated, Tracer checks all applicable limits:Figure 1. How spending limits work
- 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 non-deleted limits — unlike rule names, which are unique only within their scope context. Uniqueness is enforced on the name exactly as stored, after leading and trailing whitespace is trimmed: the comparison is case-sensitive and does not collapse whitespace inside the name, so
Daily Card Limit and daily card limit are two distinct, both-acceptable limits. Deleting a limit frees its name for reuse. A collision returns 409 Conflict with error code 0442.List and query limits
Query limits for management and auditing using
GET /v1/limits.
Query parameters
Get a specific limit
UseGET /v1/limits/{id} to retrieve the full limit definition including scopes and current status.
Read consumption
From the decision
EveryPOST /v1/validations response carries limitUsageDetails, with one entry per limit Tracer checked. Each entry reports:
- limitId and limitAmount — which cap was checked, and its ceiling
- currentUsage — the projected consumption of that cap’s current period and matched scope if this transaction is allowed
- attemptedAmount — the amount checked against the cap
- exceeded — whether the attempted amount would push this cap past its ceiling; every cap is evaluated, so more than one entry can carry
exceeded: true, and any of them produces the DENY
From the limit
GET /v1/limits/{id}/usage reports a cumulative total. Its currentUsage adds up the usage counters recorded for the limit, across periods and scopes, so use it to review a limit’s overall consumption rather than to answer how much a customer has left in the current period.
A counter is deleted 90 days after its period ends (see Usage tracking), so on a long-running limit this total covers only the periods still retained, not the limit’s full lifetime.
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:
Figure 2. Spending limits lifecycle
States
Transitions
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”
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
- Read the decision payload -
limitUsageDetailsshows how much of each cap every transaction consumed - 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
For limit type definitions (DAILY, WEEKLY, MONTHLY, CUSTOM, PER_TRANSACTION), the optional time-window and custom-period fields, and the full scope-field list, see Limit types earlier in this guide and the API reference for schema-level details.

