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 Tracer enforces a limit during the day. When a transaction occurs outside the configured time window, Tracer skips the limit and does not enforce it. The transaction proceeds without counting against that limit.- Format:
HH:MM(24-hour, UTC) - Both fields required: If you set
activeTimeStart, you must also setactiveTimeEnd(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
You can apply time windows to any limit type (DAILY, WEEKLY, MONTHLY, CUSTOM, or PER_TRANSACTION). Without a time window, 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
You can use time windows and custom periods together onCUSTOM limits. Tracer then checks a transaction against the limit only when it falls within both the custom period and the time window.
For example, take a CUSTOM limit with customStartDate Nov 25 to customEndDate Nov 30 and a time window of 09:00 to 18:00. Tracer enforces that limit only 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 you leave out works as a wildcard (matches any value). You must set at least one field. Tracer rejects empty scope objects (
{}) 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.
Tracer keeps a counter 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 Tracer validates a transaction, it 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, Tracer skips the limit (it does not use the client-suppliedtransactionTimestamphere) - Check custom period - If the limit is
CUSTOM, verify the current server time falls withincustomStartDate/customEndDate. If outside, Tracer skips the limit (again, it does not usetransactionTimestamp) - Calculate projected usage - Add transaction amount to current usage
- Compare threshold - Check if projected usage exceeds limit amount
- Return result - If the transaction exceeds any applicable limit, 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 Tracer denies a transaction (by limits or rules) or flags it for review, it rolls back all counter increments 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. That includes 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. Tracer creates limits 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") - asset: ISO 4217 asset 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. Tracer enforces uniqueness on the name exactly as stored, after it trims leading and trailing whitespace. 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 Tracer checked, and its ceiling
- currentUsage: the projected consumption of that cap’s current period and matched scope if Tracer allows this transaction
- attemptedAmount: the amount checked against the cap
- exceeded: whether the attempted amount would push this cap past its ceiling. Tracer evaluates every cap, 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. Use it to review a limit’s overall consumption rather than to answer how much a customer has left in the current period.
Tracer deletes a counter 90 days after its period ends (see Usage tracking). 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 asset fields are immutable. You cannot change them 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), see Limit types earlier in this guide. The same guide covers the optional time-window and custom-period fields and the full scope-field list. The API reference has schema-level details.

