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

# Lender in the platform

> See how Lender posts to the Midaz ledger, emits lifecycle events on the streaming backbone, isolates tenants per schema, and reports telemetry data.

export const GDoubleEntry = ({children}) => <Tooltip headline="Double-entry accounting" tip="Every financial movement is recorded as at least two operations: a debit from one account and a credit to another, ensuring the system always balances." cta="See glossary" href="/en/start-here/glossary">
    {children}
  </Tooltip>;

export const GLedger = ({children}) => <Tooltip headline="Ledger" tip="The core financial book that records all transactions, balances, and operations for an organization — the single source of truth for a business unit's finances." cta="See glossary" href="/en/start-here/glossary">
    {children}
  </Tooltip>;

Lender is a Lerian primitive: it runs on the platform, not beside it. Four platform seams matter when you operate it: the ledger posting path, the event stream, multi-tenancy, and observability.

## The Midaz posting path

***

Lender is the source of truth for the credit journey. [Midaz](/en/products/midaz/about-midaz) is the source of truth for balances. A disbursement and each interest accrual become a balanced <GDoubleEntry>double-entry</GDoubleEntry> transaction bound for the <GLedger>ledger</GLedger>. So does a prepayment that settles a Brazilian loan account against a prepayment quote. The path preserves that posting intent and delivers it idempotently. The ledger reaches consistency once the outbox delivery succeeds and the dispatcher posts, which may lag or stay pending while routing is unavailable.

<Steps>
  <Step title="A domain event produces a posting intent">
    Lender persists a durable **posting intent** on a disbursement, an interest accrual, or the settlement of a Brazilian prepayment quote. The intent lands in the same database transaction that changes domain state. Lender writes the intent to a transactional **outbox**, so it survives a crash between "state changed" and "ledger booked."
  </Step>

  <Step title="The relay posts a balanced transaction to Midaz">
    With the Midaz ledger relay configured, an outbox dispatcher posts the balanced double-entry transaction through the official SDK. Otherwise, the durable intent remains in the outbox. The legs come from the product's **accounting profile**.
  </Step>

  <Step title="Idempotency is durable">
    Each posting carries a deterministic idempotency key computed by Lender. A retried post collapses to the same Midaz transaction. Midaz's own idempotency window is a backstop, not the primary guard.
  </Step>

  <Step title="Routing fails closed">
    The transaction books into the ledger organization and ledger the accounting profile resolves. If routing cannot resolve a non-empty target, the post **fails closed**: Lender refuses to book rather than write into an empty or wrong target.
  </Step>
</Steps>

With the ledger relay configured, Lender reaches Midaz through [Access Manager](/en/platform/access-manager). It authenticates with machine-to-machine (M2M) credentials and a short-lived JWT, per tenant.

## Lifecycle events

***

Lender's streaming catalog contains 35 definitions: 33 facts and two commands. With streaming enabled and a broker configured, every event Lender emits is **outbox-backed** and **tenant-scoped**. Runtime emission also depends on the applicable feature gates. Check the deployed manifest and the [Lender event reference](/en/reference/events/lender) before depending on a definition as a live integration.

Lender uses the v3 application-stream contract:

| Wire element       | Value                                     |
| ------------------ | ----------------------------------------- |
| Fact topic         | `lerian.streaming.lender`                 |
| Command topic      | `lerian.streaming.lender.commands`        |
| `ce-source` header | `lender`                                  |
| `ce-type` header   | `studio.lerian.lender.<resource>.<event>` |
| Partition key      | the tenant                                |

All facts share one application topic, and all commands share the command topic. Route by `ce-resourcetype` and `ce-eventtype`. Schema version travels in `ce-schemaversion` and does not change the topic.

The events ride the same outbox as the ledger relay, so they share one durability guarantee. The local state change and the event commit together in a single database transaction. The posting intent joins them when the change produces one. The outbox dispatcher applies the ledger posting afterward, when it relays the intent to Midaz. Lender's state and the Midaz booking therefore reach consistency later, not in the same transaction.

<Info>
  Lender wires 15 payroll-gateway keys from `lerian.streaming.consignado-gw`. The corresponding consumers are configuration-gated. Its Matcher listener consumes `match_run.completed` from `lerian.streaming.matcher`. The contract matches only when Matcher uses `STREAMING_CLOUDEVENTS_SOURCE=matcher` and sends `ce-source: matcher`, `ce-type: studio.lerian.matcher.match_run.completed`, `ce-resourcetype: match_run`, and `ce-eventtype: completed`. See [Lender events](/en/products/lender/lender-events) and [Consignado privado](/en/products/lender/consignado-privado).
</Info>

## Multi-tenancy

***

Like every Lerian product, Lender is built for full tenant isolation from the ground up.

* **Schema-per-tenant** persistence when multi-tenancy is enabled, so tenant data never shares a table.
* **Tenant-scoped** events and ledger postings: every emitted event and every Midaz transaction carries the tenant it belongs to.
* Under multi-tenant mode, the ledger relay resolves a **per-tenant** Midaz client. The accounting profile supplies the per-tenant ledger target. Routing therefore fails closed when the profile supplies no target.

See [Multi-tenancy](/en/platform/multi-tenancy) for the platform-wide model.

## Observability

***

Lender emits structured logs, OpenTelemetry traces, and metrics on the same observability stack as the rest of the platform, including database, assertion, and panic-recovery metrics. See [Observability](/en/platform/observability).

## Next steps

***

<Card title="Accounting and accrual runs" icon="calculator" href="/en/products/lender/accounting-and-accrual-runs" horizontal>
  Go deeper on posting rules, accrual runs, and journal references.
</Card>

<Card title="Configuration and deploy" icon="gear" href="/en/products/lender/configuration-and-deploy" horizontal>
  See the dependencies and configuration the posting path and event stream require.
</Card>
