POST /v1/validations, acts on ALLOW / DENY / REVIEW, and moves on. Tracer never reaches back into your stack. There are no webhooks or callbacks, and the integration ends with the response.
What changes in your operation: decisioning moves from in-process logic to an external call. The call is synchronous (request/response, no webhooks), so it sits on the critical path of the transaction. Done well, it adds under 80ms p99 and gives you a single point for policy and validation history. Done poorly (no timeout, no retry strategy, no fallback), it becomes a single point of failure.
Trade-off to be honest about: you’re adding a network hop. The good news is the contract is simple: idempotent by requestId, no callbacks, deterministic three-state response. The bad news is you must think about timeouts, retries, and what to do if Tracer is unreachable. Most of this guide is about that.
This guide covers payload requirements, the integration flow, and practices that keep the validation call inside your latency budget.
Tracer sits outside your ledger: it never calls Midaz. Your application orchestrates the two. It calls Tracer to validate, and submits the transaction to Midaz only if the decision is ALLOW. Tracer evaluates your configured policies and limits against the context you send, not account balances. The ledger stays the source of truth for what an account holds.
Midaz can also drive Tracer through an optional per-ledger reservation seam. It remains one-way, Ledger → Tracer. The rest of this guide covers the application-orchestrated HTTP pattern. The seam contract appears below.
Integration overview
Tracer expects calls from authorization systems (payment gateways, workflow orchestrators, or transaction processors) that need real-time validation decisions. The integration follows a simple request-response pattern:
Figure 1. Integration overview with Tracer
Midaz Ledger reservation seam
This opt-in seam belongs to Ledger HTTP v2. Ledger HTTP v1 never invokes it. The Tracer public HTTP API is v1-only and has no reservation operations. Ledger calls the gRPC service
lerian.midaz.reservation.v1.ReservationService. This service is an internal service-to-service transport, not a public API.
Tracer always starts this gRPC listener, on port 4021 by default. To use a different port, set TRACER_GRPC_PORT to a listen address in the form :4021.
On Ledger, set TRACER_BASE_URL to the listener address as host:port. When TRACER_BASE_URL is unset, Ledger makes no reservation call. Ledger calls Tracer only when the per-ledger tracer.mode is advisory or enforce. An unset or off mode skips reservations even when you set TRACER_BASE_URL. An honored per-call skip also bypasses the seam.
The seam has five transitions:
Deployment order
Deploy Tracer from Midaz v4.2.0 before you deploy the Ledger. While a Ledger from v4.2.0 runs, do not roll Tracer back to an earlier version. An earlier Tracer drops the account type, the metadata and the revert flag of each reserve request.Rules on a reserve
On eachReserve, Tracer evaluates your active rules first, with the same evaluator as POST /v1/validations. Then it reserves limit capacity. On a reserve, the no-match default does not apply. When no rule matches, the reserve continues to the limit check. A reserve for a revert skips rules and still reserves limit capacity.
The reserve request carries the amount, the asset, the ID and type of the first internal source account, the transaction timestamp and scalar metadata values, as strings. It carries no transaction type, segment, portfolio or merchant.
Outcomes on the Ledger
A reservation denial is a successful response, not a transport error. Theadvisory mode never blocks the transaction. The enforce mode rejects the transaction before any balance movement:
With the open posture, the Ledger also proceeds without rule or limit checks when Tracer refuses the Ledger’s credentials.
The Ledger can also return
0536 for a reserve. The Midaz error list describes each code.
Confirm and release failures do not block the transaction.
Payload-Complete Pattern
Tracer uses the Payload-Complete Pattern. Every request must carry all context required for validation. This design ensures:
Your responsibilities
As the integrating system, you are responsible for:- Enriching the payload with account, segment, portfolio, and merchant data before calling Tracer
- Providing accurate context for rule and limit evaluation. Tracer cannot fetch missing data
- Handling the decision (ALLOW, DENY, or REVIEW) appropriately in your workflow
- Implementing retry logic if Tracer is temporarily unavailable
- Managing review workflows when Tracer returns
REVIEW. Tracer does not include case management
Tracer’s responsibilities
Tracer is responsible for:- Evaluating rules against the provided context
- Checking limits against current usage
- Storing validation history for investigation and reporting
- Returning decision with detailed information
Integration flow
Follow these steps to integrate your system with Tracer.
Step 1: Prepare the transaction context
Before calling Tracer, gather all relevant data from your systems:Figure 2. Preparing transaction context
Step 2: Call Tracer API
Send a POST request to/v1/validations with the complete transaction context including:
- Transaction details (type, subType, amount, asset, timestamp)
- Account information (required)
- Optional: segment, portfolio, merchant, and custom
Step 3: Handle the response
Process the decision returned by Tracer:
The response includes the
validationId for correlation with validation history, details about which rules matched, and current limit usage information.
Using metadata
Metadata allows you to pass custom fields that your rules can evaluate. Use this for context like channel, device information, customer tier, or any business-specific attributes.Metadata keys must be alphanumeric with underscores only, maximum 64 characters. Maximum 50 entries per request.
Request idempotency
Validation requests are idempotent based on the
requestId field. If you send the same requestId twice, Tracer returns the cached result from the first request instead of reprocessing.
The response body is identical in both cases. Your client should handle both status codes as success.
Why it matters: Network timeouts and retries can cause duplicate requests. Without idempotency, a retried request could double-count against limits or create duplicate validation records. The
requestId ensures exactly-once processing semantics.
Idempotency contract:
- Same
requestId→ Same response (guaranteed) - Different
requestId→ Independent processing (even if transaction data is identical)
Authentication
Tracer supports two authentication modes. You can use them independently or together.
API key authentication
The simplest option. Send your API key in theX-API-Key header with every request.
Plugin authentication (Access Manager)
For enterprise deployments, Tracer can delegate authentication to the Lerian Access Manager. This enables centralized authentication across all Lerian services.Authentication priority
When you enable both modes, Tracer uses this priority:- If
PLUGIN_AUTH_ENABLED=trueand the endpoint has no API-key-only flag → Plugin auth - If
API_KEY_ENABLED=trueor the endpoint carries the API-key-only flag → API key auth
/v1/* API surface documented in this reference.
You can configure the
/v1/validations endpoint for API-key-only authentication via API_KEY_ENABLED_ONLY_VALIDATION=true. This is useful in high-throughput scenarios where plugin auth adds unacceptable latency. This flag is incompatible with multi-tenant mode (MULTI_TENANT_ENABLED=true). The service fails to start with error code 0458.Multi-tenant authentication
WhenMULTI_TENANT_ENABLED=true, Tracer runs in multi-tenant mode and the authentication model changes:
- Plugin auth is mandatory. The service fails to start with error code
0457ifPLUGIN_AUTH_ENABLED=false. - Every
/v1/*request must carry a JWT bearer token issued by Access Manager:Authorization: Bearer <jwt>. tenantIdcomes from the JWT claim, not from a header, path, body, metadata, or rule scope. There is noX-Tenant-IDheader. The tenant identifier has no effect anywhere other than the token claim.- Each tenant operates on its own PostgreSQL database. The multi-tenancy platform service resolves the tenant-specific connection at request time.
- Public endpoints (
/health,/readyz,/metrics,/version) stay unauthenticated in multi-tenant mode too. The bearer-token requirement applies only to/v1/*.
"code": "Unauthenticated". Missing API keys return the same code, with no separate TRC code.
One case is distinct. A token that parses but carries no sub claim returns HTTP 401 and error code 0474 up front. The sub claim is what the audit writer uses to attribute the action to a principal. Tracer fails loudly rather than recording the change against a generic system actor. Make sure your Access Manager tokens always carry it.
If the multi-tenant deployment hits its per-instance tenant cap, requests for cold tenants return HTTP 503 with error code 0466 and a Retry-After header. The client should back off and retry. The cap auto-resets as the LRU pool evicts cold tenants.
See Multi-tenancy for the platform-wide tenant model.
Performance considerations
Optimize your integration for low latency and high reliability.
Timeout budget
Tracer targets a response in under 80ms (p99). Configure your client timeout accordingly:Retry strategy
Implement retry logic for transient failures:Fallback behavior
Decide what happens when Tracer is unavailable:
Your choice depends on your risk tolerance and business requirements.
Data freshness
Since you control the payload enrichment, data freshness is your responsibility. Tracer trusts the data you provide and cannot detect stale information.
Date and time format
All datetime fields must use RFC3339 format with mandatory timezone: Valid formats:
Integration checklist
Before going to production, verify:
- Your API Key is in place and secure
- Each request includes a unique requestId (UUID)
- Client handles both 201 and 200 responses as success
- Your client timeout is 100ms
- Your retry logic covers 5xx errors
- You chose a fallback behavior
- Your payload carries all required fields
- Timestamps use RFC3339 format with timezone
- Asset codes are 1 to 100 uppercase letters
- Your system handles each decision (ALLOW/DENY/REVIEW)
- Your system logs validation IDs for validation-history correlation
Example integration (pseudocode)
Next steps
- Rules engine - Create rules that evaluate against the context you provide
- Spending limits - Configure limits that apply to your transaction scopes
- Validation history and compliance - Query validation history and use it in your compliance processes

