> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Validate a transaction before the ledger (API)

> Your system asks Tracer for ALLOW, DENY or REVIEW by your rules and spending limits, and posts the transaction to Midaz only after ALLOW.

Ask Tracer for a decision on each transaction, and post it to Midaz only after ALLOW.

## Participants

***

* **Your institution.** Your system collects the transaction context, calls Tracer, acts on the decision and posts the transaction.
* **Tracer.** Evaluates your active rules and spending limits, and returns the decision. It consumes no limit.
* **Midaz.** The ledger that records the transaction after ALLOW.

## Before you start

***

* Your system can call the Tracer API with a valid credential. See the [Tracer integration guide](https://docs.lerian.studio/en/products/tracer/integration-guide.md).
* Your rules and spending limits are ACTIVE in Tracer. See [Set up rules and spending limits](https://docs.lerian.studio/en/diagrams/lerian-products/tracer-set-up-rules-and-limits.md).

## Diagram

***

![Validate a transaction before the ledger](https://mintcdn.com/lerian-49cb71fc/iQaGwPqOofAi9HOo/images/en/d2/id-tracer-validate-before-ledger.svg?fit=max\&auto=format\&n=iQaGwPqOofAi9HOo\&q=85\&s=13fff1ec744d7fbe2aecec58ff1d7cf5)

## Steps

***

| # | From | To | Message | Lerian API | What happens |
| - | - | - | - | - | - |
| 1 | Your institution | Tracer | Lerian API | [`POST /v1/validations`](https://docs.lerian.studio/en/reference/products/tracer/validate-transaction) | Send the full transaction context with a new `requestId`. |
| 2 | Tracer | Tracer | Internal step | | Tracer evaluates your active rules. Unless the result is already `DENY` or `REVIEW`, it checks your active spending limits. |
| 3 | Tracer | Your institution | Lerian API | Response to step 1 | Tracer returns `ALLOW`, `DENY` or `REVIEW` with the `validationId`, the matched rules and the limit usage. A new request returns `201`. A known `requestId` returns `200`. |
| 4 | Your institution | Your institution | Internal step | | Post the transaction after `ALLOW`. Refuse it after `DENY`. Send a `REVIEW` to your own review process. |
| 5 | Your institution | Midaz | Lerian API | [`POST /v2/transactions/direct`](https://docs.lerian.studio/en/reference/products/midaz/v2/create-transaction-direct) | Post the transaction to the ledger, only after `ALLOW`. |
| 6 | Midaz | Your institution | Lerian API | Response to step 5 | Midaz returns the created transaction with `201`. |

## How you know it finished

***

Tracer returned a decision with its `validationId`. After `ALLOW`, Midaz returned the created transaction.

## Rules

***

* A matched `DENY` rule decides `DENY`, and Tracer then does not check the limits. Next, a matched `REVIEW` rule or a rule that Tracer cannot evaluate decides `REVIEW`. Then a matched `ALLOW` rule decides `ALLOW`. Last, when no rule matches and Tracer can evaluate every rule, the default decision of your Tracer configuration applies: `ALLOW` or `DENY`. Tracer then checks an `ALLOW` against your limits. An amount that would take a limit past its maximum decides `DENY` with the reason `limit_exceeded`.
* This journey reads your spending limits and counts nothing against them. Only a transaction that Midaz creates with Tracer enabled consumes a limit. See [Check Midaz transactions with Tracer](https://docs.lerian.studio/en/diagrams/lerian-products/tracer-check-ledger-transactions.md).
* A `requestId` that Tracer already knows returns the stored decision when the request is the same. A different request with that `requestId`, or one that the other validate route stored, returns `409` with code `0084`.
* To decide by your rules alone, send the same request to [`POST /v1/validations/rules-only`](https://docs.lerian.studio/en/reference/products/tracer/validate-transaction-by-rules-only).

## What can go wrong

***

| Situation | What you see | What to do |
| - | - | - |
| Tracer does not answer in time. | No response. | Send the same request with the same `requestId`. Tracer returns the stored decision if it has one. If not, it decides now. |
| Tracer answers `409` with code `0084`. | The `requestId` is already stored for another request. | Send the request with a new `requestId`. |
| Midaz does not answer in time. | No response. | The result is not known. Send the same request with the same `X-Idempotency` key before the key expires. |

## Related

***

* [Check Midaz transactions with Tracer](https://docs.lerian.studio/en/diagrams/lerian-products/tracer-check-ledger-transactions.md)
* [Investigate a decision in the audit trail](https://docs.lerian.studio/en/diagrams/lerian-products/tracer-investigate-a-decision.md)
* [Tracer integration guide](https://docs.lerian.studio/en/products/tracer/integration-guide.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.