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

# Subledgers overview

> ntro.subledger — typed domain rows in the tenant ledgers schema, opened per entity and workflow task.

A **subledger** is a ledger-shaped table scoped to an entity and workflow run (expenses, journal staging, etc.). Rows live in the tenant **`ledgers`** schema alongside the GL — not in `ingest.*`. Use **`ntro.subledger`** from activities or workflow-adjacent code that already holds a data-plane connection.

## Opening a handle

```python theme={null}
from uuid import UUID
from ntro.subledger import open as subledger_open

handle = subledger_open(
    name="expenses",
    entity_id=UUID("…"),
    task_id=UUID("…"),
    tenant_slug="acme",
)
rows = await handle.query(...)
```

Platform types register via `@register_type` under `ntro.subledger.types`. Mutation helpers for review workflows live alongside the type (e.g. edit/reject rules) so **Temporal-signalled actions** can apply domain logic consistently — see [UI and Temporal signals](/sdk/ui-and-temporal-signals).

## Core concepts

| Symbol            | Purpose                                                                                                    |
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
| `Row`             | Pydantic base for subledger rows — standard columns (`id`, `entity_id`, `period`, `task_id`, `status`, …). |
| `SubledgerStatus` | Default lifecycle enum; types may specialize.                                                              |
| `SubledgerHandle` | Lazy-bound API for query / insert / transitions for one `(subledger name, entity, task)`.                  |
| `register_type`   | Associates a row model with a subledger name at import time.                                               |

Direct **HTTP** mutation endpoints on Ntropii Tenant may still exist for ops or legacy callers; **interactive Tenant UI** edits for HITL tables should go through **workflow signals** so Temporal stays the source of truth — same boundary as described in the signals doc.

## Standard column block

Every `Row` subclass inherits these columns. Type-specific fields are added on top.

| Column                      | Type                   | Purpose                                                                        |
| --------------------------- | ---------------------- | ------------------------------------------------------------------------------ |
| `id`                        | `UUID`                 | Row PK; auto-generated UUID4 if not supplied.                                  |
| `entity_id`                 | `UUID`                 | Canonical, immutable entity identifier (UUID, not slug).                       |
| `period`                    | `Period` (`"YYYY-MM"`) | Accounting period.                                                             |
| `task_id`                   | `UUID`                 | Workflow task that wrote the row (provenance).                                 |
| `status`                    | `SubledgerStatus`      | Lifecycle marker; types may override the enum.                                 |
| `source_ref`                | `str \| None`          | Upstream handle (e.g. `"event:<uuid>"`, `"doc:<uuid>"`).                       |
| `validation_errors`         | `list[dict] \| None`   | Populated on rows that failed strict-type validation (`NEEDS_ATTENTION` flow). |
| `raw_payload`               | `dict \| None`         | The agent's submitted dict, captured before validation.                        |
| `created_at` / `updated_at` | `datetime`             | Insert / update timestamps.                                                    |

## Lifecycle — `SubledgerStatus`

Default lifecycle every platform type uses unless it overrides. Terminal states have no outgoing edges.

```
NEEDS_ATTENTION ─┬─▶ PENDING ─┬─▶ APPROVED ─┬─▶ POSTED   (terminal)
                 │            │             └─▶ REJECTED (terminal)
                 │            ├─▶ REJECTED              (terminal)
                 │            └─▶ EXCLUDED              (terminal)
                 └─▶ REJECTED                           (terminal)
```

`NEEDS_ATTENTION` is the entry point for rows whose payload failed type-level validation (e.g. an extraction missing `vendor`). HITL fixes the typed columns and transitions to `PENDING`. From there the row follows the normal lifecycle.

`transition(from_status, to_status)` raises `IllegalTransitionError` on a disallowed move. Idempotent self-transitions (`X → X`) are also rejected — call sites should check `row.status == target` first if they want a no-op.

## Platform types

Bundled subledger types ship under `ntro.subledger.types` and register at import time. Each carries its own typed columns, validation rules, and `propose_for_gl` handoff (where applicable).

<CardGroup cols={2}>
  <Card title="expenses" icon="receipt" href="/sdk/subledgers/types/expenses">
    `ExpenseRow` — single expense receipt (vendor, amount, category, VAT). Used by `expense-processor`.
  </Card>

  <Card title="journal_proposals" icon="file-spreadsheet" href="/sdk/subledgers/types/journal-proposals">
    `JournalProposalRow` — one HITL-reviewed journal entry awaiting GL commit. Used by `nav-monthly-journals`.
  </Card>
</CardGroup>

## Related

<CardGroup cols={2}>
  <Card title="Ingest outcomes & feedback" icon="database" href="/sdk/ingest">
    Earlier stage: ingest schema and feedback envelopes.
  </Card>

  <Card title="UI and Temporal signals" icon="right-left" href="/sdk/ui-and-temporal-signals">
    How row edits reach `ntro.subledger` via workflows.
  </Card>

  <Card title="Accounting capability" icon="calculator" href="/sdk/capabilities/accounting">
    GL-facing helpers built on subledger proposals where applicable.
  </Card>

  <Card title="General ledgers" icon="landmark" href="/sdk/capabilities/general-ledgers">
    `ntro.capabilities.gl` — post `BillProposal` and other resources to the external GL.
  </Card>
</CardGroup>
