This guide walks you through setting up Tracer and running your first validation. In just a few steps, you’ll have a working environment ready to validate transactions in real time.
Why use Tracer
| Benefit | Description |
|---|
| Real-time validation | Make ALLOW/DENY/REVIEW decisions in under 80ms (p99) |
| Flexible rules | Expression-based rule engine for custom business logic |
| Spending control | Configure limits by account, portfolio, segment, and period |
| Complete audit trail | Immutable validation records for SOX/GLBA compliance |
| Product-agnostic | Supports any transaction type (Card, Wire, PIX, Crypto) |
By the end of this guide, you will:
- Understand Tracer architecture and core concepts
- Have a working development environment
- Run your first transaction validation
- Configure a spending limit
What is Tracer
Tracer is a transaction validation platform that evaluates rules and limits and returns instant decisions. Your system calls Tracer before executing transactions and acts on the decision (ALLOW, DENY, or REVIEW) according to your business logic.
How it works
In this flow:
- Rules evaluate expressions against the transaction context
- Limits check spending thresholds for applicable scopes
- Decision returns ALLOW, DENY, or REVIEW based on evaluation results
Core contexts
Tracer is built around three bounded contexts:
- Validation Context - Orchestrates requests, coordinates evaluation, records audit trail
- Rules Context - Manages rule definitions and expression evaluation
- Limits Context - Manages spending limits and usage tracking
Prerequisites
Before you start, make sure you have:
Infrastructure dependencies
| Component | Version | Purpose |
|---|
| PostgreSQL | 16+ | Data persistence and audit trail |
Ports
| Service | Port | Description |
|---|
| Tracer API | 8080 | Main REST API |
| PostgreSQL | 5432 | Database |
Step 1: Set up the environment
You can run Tracer with Docker Compose or locally for development.
Option A: Docker Compose (recommended)
This is the fastest way to start. PostgreSQL starts automatically with the service.
Clone the repository and start the services:
# Clone the repository
git clone https://github.com/lerianstudio/tracer.git
cd tracer
# Setup environment
cp .env.example .env
# Start all services
make up
Verify service health:
# Check Tracer health
curl http://localhost:8080/health
# Check readiness (database connection)
curl http://localhost:8080/ready
Option B: Local run
For development, you can run Tracer locally:
# Set environment variables
export DB_HOST="localhost"
export DB_NAME="tracer"
export API_KEY="your-secure-api-key"
export API_KEY_ENABLED="true"
export SERVER_PORT="8080"
export LOG_LEVEL="INFO"
# Start the service
go run cmd/app/main.go
Essential environment variables
| Variable | Description | Example |
|---|
DB_HOST | PostgreSQL host | localhost |
DB_NAME | PostgreSQL database name | tracer |
API_KEY | API Key for authentication | your-secure-api-key |
API_KEY_ENABLED | Enable API Key authentication | true, false |
SERVER_PORT | API port | 8080 |
LOG_LEVEL | Log level | INFO, DEBUG, ERROR |
Step 2: Authenticate to the API
Tracer uses API Key authentication for all requests.
API Key authentication
Include the API Key in the X-API-Key header:
GET /v1/rules
X-API-Key: your-secure-api-key
cURL example
# Check API health (no authentication required)
curl http://localhost:8080/health
# List rules (authenticated)
curl -H "X-API-Key: your-secure-api-key" \
http://localhost:8080/v1/rules
API Keys should be kept secure. Never expose your API Key in client-side code or public repositories.
Spending limits control transaction amounts by scope (account, portfolio, segment) and period (daily, monthly, per-transaction).
Create a limit
POST /v1/limits
X-API-Key: {api_key}
Content-Type: application/json
{
"name": "Daily Corporate Limit",
"limitType": "DAILY",
"maxAmount": 5000000,
"currency": "BRL",
"scopes": [
{
"segmentId": "corporate-segment-uuid",
"transactionType": "CARD"
}
]
}
All monetary amounts are expressed in the smallest currency unit (e.g., centavos for BRL). R$ 50,000.00 = 5,000,000.
Response
{
"limitId": "limit-uuid-123",
"name": "Daily Corporate Limit",
"limitType": "DAILY",
"maxAmount": 5000000,
"currency": "BRL",
"scopes": [
{
"segmentId": "corporate-segment-uuid",
"transactionType": "CARD"
}
],
"status": "DRAFT",
"resetAt": "2026-01-30T00:00:00Z",
"createdAt": "2026-01-29T10:00:00Z",
"updatedAt": "2026-01-29T10:00:00Z"
}
Query limit usage
GET /v1/limits/{limitId}/usage
X-API-Key: {api_key}
{
"limitId": "limit-uuid-123",
"limitAmount": 5000000,
"currentUsage": 1500000,
"utilizationPercent": 30.0,
"nearLimit": false,
"resetAt": "2026-01-30T00:00:00Z"
}
Step 4: Validate your first transaction
With limits configured, you’re ready to validate a transaction.
Submit a transaction for validation
POST /v1/validations
X-API-Key: {api_key}
Content-Type: application/json
{
"requestId": "req-uuid-123",
"transactionType": "CARD",
"subType": "debit",
"amount": 150000,
"currency": "BRL",
"transactionTimestamp": "2026-01-29T10:30:00Z",
"account": {
"accountId": "acc-uuid-123",
"type": "checking",
"status": "active"
},
"segment": {
"segmentId": "corporate-segment-uuid"
},
"portfolio": {
"portfolioId": "portfolio-uuid-456"
},
"merchant": {
"merchantId": "merchant-uuid-789",
"category": "5411",
"country": "BR"
},
"metadata": {
"channel": "MOBILE_APP",
"deviceId": "device-abc123"
}
}
ALLOW response
{
"requestId": "req-uuid-123",
"validationId": "val-uuid-xyz",
"decision": "ALLOW",
"reason": "Transaction approved",
"matchedRuleIds": [],
"evaluatedRuleIds": ["rule-uuid-1", "rule-uuid-2"],
"limitUsageDetails": [
{
"limitId": "limit-uuid-123",
"limitAmount": 5000000,
"currentUsage": 1650000,
"exceeded": false
}
],
"processingTimeMs": 23
}
DENY response
When Tracer returns a DENY decision, you receive details about the reason. Your system should then block the transaction:
{
"requestId": "req-uuid-456",
"validationId": "val-uuid-abc",
"decision": "DENY",
"reason": "limit_exceeded",
"matchedRuleIds": [],
"evaluatedRuleIds": ["rule-uuid-1"],
"limitUsageDetails": [
{
"limitId": "limit-uuid-123",
"limitAmount": 5000000,
"currentUsage": 4900000,
"exceeded": true
}
],
"processingTimeMs": 18
}
Step 5: Create a validation rule
Rules let you define custom business logic that evaluates during validation.
Create a rule
POST /v1/rules
X-API-Key: {api_key}
Content-Type: application/json
{
"name": "Block high-value transactions",
"description": "Deny transactions above BRL 10,000 (1,000,000 centavos)",
"expression": "transaction.amount > 1000000",
"action": "DENY",
"scopes": [
{
"transactionType": "CARD"
}
]
}
Response
{
"ruleId": "rule-uuid-new",
"name": "Block high-value transactions",
"description": "Deny transactions above BRL 10,000 (1,000,000 centavos)",
"expression": "transaction.amount > 1000000",
"action": "DENY",
"scopes": [
{
"transactionType": "CARD"
}
],
"status": "DRAFT",
"createdAt": "2026-01-29T11:00:00Z",
"updatedAt": "2026-01-29T11:00:00Z"
}
Activate the rule
Rules are created in DRAFT status. Activate to start evaluation:
POST /v1/rules/{ruleId}/activate
X-API-Key: {api_key}
{
"id": "rule-uuid-new",
"status": "ACTIVE",
"updatedAt": "2026-01-29T11:05:00Z"
}
Observability
Tracer exposes endpoints for monitoring and observability.
Health endpoints
| Endpoint | Description |
|---|
GET /health | Liveness check (app running) |
GET /ready | Readiness check (database available) |
Key metrics
Tracer exposes Prometheus-compatible metrics:
tracer_validations_total{decision} - Total validations by decision
tracer_validation_duration_seconds - Validation latency histogram
tracer_rule_evaluations_total - Total rule evaluations
tracer_limit_checks_total{result} - Limit checks by result
tracer_auth_failures_total{reason} - Authentication failures by reason
tracer_active_rules - Number of active rules
Verification
Confirm that everything is working correctly.
Checklist
Connectivity test
# Check API health (liveness)
curl http://localhost:8080/health
# Check readiness (database connection)
curl http://localhost:8080/ready
Expected responses
Health check (liveness):
Readiness check:
{
"status": "READY",
"checks": [
{
"component": "database",
"status": "OK"
}
]
}
Common errors
Authentication
| Code | Message | Resolution |
|---|
401 | Invalid API Key | Verify the API Key is correct |
401 | Missing authorization | Include the X-API-Key header |
Transaction validation
| Code | Message | Resolution |
|---|
400 | Invalid transaction format | Check the request payload structure |
400 | Missing required field | Include all required fields |
504 | Processing timeout | Transaction exceeded 80ms budget |
Spending limits
| Code | Message | Resolution |
|---|
400 | Invalid limit configuration | Check limit values and scope |
404 | Limit not found | Verify the limit ID |
Rules
| Code | Message | Resolution |
|---|
400 | Invalid expression syntax | Check expression syntax |
400 | Expression must return boolean | Ensure expression evaluates to true/false |
Next steps
You’ve successfully set up Tracer and validated your first transaction. From here, you can explore more advanced features:
Quick reference
Main endpoints
| Operation | Method | Endpoint |
|---|
| Health check | GET | /health |
| Readiness check | GET | /ready |
| Validate transaction | POST | /v1/validations |
| Get validation | GET | /v1/validations/{validationId} |
| List validations | GET | /v1/validations |
| Create limit | POST | /v1/limits |
| Get limit | GET | /v1/limits/{limitId} |
| Update limit | PATCH | /v1/limits/{limitId} |
| Get limit usage | GET | /v1/limits/{limitId}/usage |
| Create rule | POST | /v1/rules |
| Get rule | GET | /v1/rules/{ruleId} |
| Update rule | PATCH | /v1/rules/{ruleId} |
| Activate rule | POST | /v1/rules/{ruleId}/activate |
| Deactivate rule | POST | /v1/rules/{ruleId}/deactivate |
| Delete rule | DELETE | /v1/rules/{ruleId} |
Transaction types
| Type | Description | subType examples |
|---|
CARD | Card-based transactions | debit, credit, prepaid |
WIRE | Wire transfers | domestic, international, ach |
PIX | Brazilian instant payment | instant, scheduled |
CRYPTO | Cryptocurrency | bitcoin, ethereum, stablecoin |
Decision types
| Decision | Description | Your system should |
|---|
ALLOW | Tracer recommends approval | Proceed with the transaction |
DENY | Tracer recommends denial | Block the transaction and inform the user |
REVIEW | Tracer recommends review | Queue for manual review in your system |
Tracer returns decisions as recommendations. Your system is responsible for implementing the appropriate action based on each decision.