> ## 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.

# Accounting and accrual runs

> How Lender books to the ledger: accounting profiles and posting rules, durable posting intents, accrual runs, and journal references.

Money events, such as a disbursement, a repayment, or an interest accrual, reach the ledger (The core financial book that records all transactions, balances, and operations for an organization. It is the single source of truth for a business unit's finances.). Lender's accounting layer is how they get there. A product declares its posting rules once. From then on, each of those events books automatically and traceably.

## Accounting profiles and posting rules

***

An **accounting profile** binds a product version to the ledger. It defines the **posting rules**: the double-entry (Every financial movement is recorded as at least two operations: a debit from one account and a credit to another, so the system always balances.) legs that fire for each kind of financial event. It also defines the ledger organization and ledger the resulting transactions book into. You create a profile per product:

`POST /api/v1/loan-products/{id}/accounting-profiles`

Lender validates the posting rules when you create the profile. A product therefore cannot go live with legs that would not balance.

## Posting intents and the relay

***

Lender does not call the ledger inline. When a financial event happens, Lender persists a durable **posting intent**. That write happens in the same database transaction that changes domain state. A relay then posts the balanced transaction to Midaz asynchronously. These properties make bookings reliable:

* **The intent commits with the state change**: both land in one database transaction, through a transactional outbox.
* **Idempotent**: each posting carries a deterministic key, so retries collapse to one ledger transaction.
* **Fails closed**: if routing cannot resolve a non-empty ledger target, Lender refuses the post and does not write it to the wrong place.

[Lender in the platform](/en/products/lender/lender-in-the-platform) describes the full path.

## Accrual runs

***

An **accrual run** recognizes interest and the other time-based amounts. One run closes the last civil month that had fully ended before its business date, for every loan it selects. It also produces the postings for that month.

`POST /api/v1/accrual-runs` starts a run. Lender selects the candidate loan accounts itself, recognizes interest per account, and writes one posting intent per recognition.

> [!TIP]
>
> Recognition is idempotent per loan account, per accounting month, and per amount kind. A run started twice for the same month recognizes interest once.

## Retrying a run

***

A recognition is durable the moment the run commits. The ledger booking is not. When a posting never arrives, retry the run instead of starting a new one.

`POST /api/v1/accrual-runs/{id}/retry` names the items to re-send, and takes the same `X-Idempotency` header the run itself takes. It is a second attempt on the same run, so Lender records no second run.

Lender rebuilds the posting behind every named item the ledger has not acknowledged, and enqueues it under the deterministic key the original run used. The relay delivers it, and the ledger treats a duplicate as a duplicate rather than as a second booking. Lender leaves alone the items the ledger already acknowledged.

The answer names, item by item, what it could not re-send. It also names why: the posting had already been delivered, it was quarantined, the contract behind it is gone, or the product is misconfigured.

> [!WARNING]
>
> A retry refuses with `LENDER-0405` when the posting it rebuilds differs from the one already enqueued under that key. The product's accounting profile changed after the run, so re-sending would book the month against legs nobody chose for it. Reconcile the enqueued posting first, because repeating the request reproduces the same refusal.

## Journal references

***

Each accrual run records a **journal reference**, the run's own accounting identifier. The reference record also stores the correlation id that Lender derived for the run. The journal reference id identifies one run exactly. A read by correlation id returns the most recent run that shares that mode, business date, and product scope.

A run emits one posting per loan account, per accounting month, per amount kind. Lender therefore records the tie back to the ledger per posting, not per run. Once the ledger acknowledges a posting, Lender stores a receipt under that posting's own key. A read by that key answers with the ledger transaction that booked it. A run-level reference carries no ledger transaction of its own: it names the run, and the receipts name the bookings.

| Operation | Purpose |
| - | - |
| `GET /api/v1/journal-references` | Look up a journal reference by correlation id. |
| `GET /api/v1/journal-references/{id}` | Read a single journal reference. |

## Next steps

***

> **[Jurisdictions](/en/products/lender/jurisdictions)**
>
> See how the active jurisdiction shapes disclosures and endpoints.

> **[Brazil regulatory pack](/en/products/lender/brazil-regulatory-pack)**
>
> Layer CET, IOF, and PDD staging on top of the accounting model.


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