For the complete documentation index, see llms.txt. This page is also available as Markdown.

Ledger API

This page is optional for headless integrations.

Query the deterministic structured records the RobotMoney protocol produces from Raw evidence. The Ledger is the single source of financial truth. Every row carries provenance, evidence references, and a confidence score.

Operation
Endpoint

List accounts

GET /v1/ledger/accounts

Account detail (+ latest balance)

GET /v1/ledger/accounts/{account_id}

List balances (point-in-time)

GET /v1/ledger/balances

List counterparties

GET /v1/ledger/counterparties

Create a manual counterparty

POST /v1/ledger/counterparties

Update counterparty identity

PATCH /v1/ledger/counterparties/{counterparty_id}

Grant counterparty trust

POST /v1/ledger/counterparties/{counterparty_id}/trust/grant

Pause counterparty trust

POST /v1/ledger/counterparties/{counterparty_id}/trust/pause

Restore counterparty trust

POST /v1/ledger/counterparties/{counterparty_id}/trust/restore

Acknowledge counterparty review

POST /v1/ledger/counterparties/{counterparty_id}/trust/acknowledge

List invoices

GET /v1/ledger/invoices

Invoice detail

GET /v1/ledger/invoices/{invoice_id}

List obligations

GET /v1/ledger/obligations

Governed resolved views

GET /v1/ledger/{obligations,counterparties,accounts}/{id}/resolved

List transactions

GET /v1/ledger/transactions

Transaction detail

GET /v1/ledger/transactions/{transaction_id}

Promote Raw → Ledger

POST /v1/ledger/normalize

Trigger reconciliation

POST /v1/ledger/reconcile

List reconciliation matches

GET /v1/ledger/reconciliation-matches

List Transactions

Filters: account_id, counterparty_id, direction (inflow | outflow | transfer | adjustment), status (pending | posted | cleared | failed | reversed | disputed), since, until, limit (default 100, max 1000), cursor. amount is a signed decimal string.

Get a Single Transaction

Returns the same Transaction shape. 404 if unknown.

List Accounts

account_type enum: bank_checking | bank_savings | card | loan | line_of_credit | onchain | payment_processor. Filters: status (active | closed | frozen | pending), account_type, limit (default 50, max 500), cursor.

For one account plus its latest balance:

List Balances (Point-in-Time)

Returns the balance row(s) effective at as_of (or the latest if omitted).

List Counterparties

type enum: merchant | vendor | customer | employer | employee | bank | wallet | exchange | tax_authority | agent | other. verified_status: unverified | self_attested | document_verified | sanctions_cleared. trust_status: unreviewed | trusted | paused | acknowledged. Each counterparty carries risk_level (low | medium | high | sanctioned), aliases[], and linked_accounts[]. Filter list results with trust_status when needed.

Create or Update a Counterparty

Create a manual counterparty with ledger:write:

name and type are required. Optional identity fields are display_name, category, contact_email, country, tax_id, and aliases. The route returns 201 for a new record or 200 when its idempotent create result already exists.

Update editable identity fields with a user principal and ledger:write:

The patch cannot modify payment or trust fields. It returns { "counterparty": { ... } }.

Counterparty Trust

Trust transitions apply uniformly to every counterparty type, including vendors and customers. Each route requires a user bearer JWT with ledger:write. Platform shared-secret callers and API keys cannot use these routes.

Transition
Endpoint
Allowed prior state
Result

Grant

POST /v1/ledger/counterparties/{counterparty_id}/trust/grant

unreviewed, acknowledged

trusted

Pause

POST /v1/ledger/counterparties/{counterparty_id}/trust/pause

unreviewed, trusted, acknowledged

paused

Restore

POST /v1/ledger/counterparties/{counterparty_id}/trust/restore

paused

trusted

Acknowledge

POST /v1/ledger/counterparties/{counterparty_id}/trust/acknowledge

unreviewed, paused

acknowledged

Every transition accepts an optional audit-only reason:

Invalid transitions return 409 with ledger_status_invalid. Successful responses return the updated counterparty and previous_trust_status.

Trust state is informational today: payment execution is enforced through verified_status, sanctions screening, and policy checks. Trust state does not gate payment execution.

List Invoices and Obligations

Invoice.status: draft | sent | partial | paid | overdue | cancelled | disputed. Obligation.type: bill | invoice | subscription | loan | rent | payroll | tax | card_statement | other.

Both endpoints use opaque cursor pagination. Pass limit (default 50, max 500) and the preceding response's next_cursor as cursor; a final page returns next_cursor: null. Use direction=receivable on obligations when listing receivable obligations, or scenario=ar to select explicitly AR-marked rows. AR-sourced invoice and receivable-obligation rows carry metadata.scenario: "ar". Clients should use that positive marker for classification rather than treating every non-AP row as receivable.

GET /v1/ledger/invoices is the complete Ledger source for a receivables inventory. GET /v1/ledger/obligations?direction=receivable contains only receivables that have an obligation projection, so it is not an interchangeably complete AR list.

Invoices can include payment_instruction when bank details were extracted from invoice evidence. The object contains display-safe bank_name, routing_last4, swift_last4, account_last4, the comparison status against the latest on-file counterparty payment instruction, and the compared history row id. Full routing, SWIFT, and account values are stored only as hashes and are never returned.

Fetch an individual invoice with:

It returns the tenant-scoped invoice row or 404.

Governed Resolved Views

The resolved views retain all source observations and present the current governed value, field-level authority, and conflicts for one record. Each route requires ledger:read and returns 404 when the record is absent or belongs to another tenant.

Record
Endpoint

Obligation

GET /v1/ledger/obligations/{obligation_id}/resolved

Counterparty

GET /v1/ledger/counterparties/{counterparty_id}/resolved

Account

GET /v1/ledger/accounts/{account_id}/resolved

Promote Raw → Ledger

Normalize a Raw-parsed row into typed Ledger entities. Idempotent. Re-running with the same input returns the same Ledger row ids.

Normalization derives every entity implied by the parsed row. The route accepts an optional target_entities field for forward compatibility, but the current handler ignores it: it reads only raw_parsed_id and produces the full entity set the parsed row supports.

Reconciliation

Trigger an async reconciliation pass:

202 Accepted → { "job_id": "rec_4711" }.

List matches:

match_type enum: transaction_receipt | invoice_payment | statement_balance | wallet_transfer | payroll_bank_debit | subscription_charge | card_charge | onchain_settlement | obligation_duplicate. status: unmatched | matched | partially_matched | duplicate_possible | disputed | cleared | failed | reversed.

Provenance on Every Row

Every Ledger row carries:

| Field | Description | | --------------------------- | ------------------------------------------ | -------- | --------- | --------------- | ------------------ | | source_ids | Raw artifact ids that produced it | | evidence_ids | Raw-parsed row ids the extractor consulted | | provenance | extracted | inferred | ambiguous | human_confirmed | agent_contributed | | confidence | Calibrated 0 to 1 score | | created_at / updated_at | Bitemporal timestamps |

Records are immutable. Corrections are written as superseding records that reference what they correct (supersedes field). The history is preserved end-to-end. Query GET /v1/audit/entity/{entityType}/{entityId} for the full causal trail.

What's Next

🧠 Wiki API

Reason over the Ledger in natural language.

📥 Raw and Ledger

The conceptual model.

Last updated