Ledger Mind reconciles on-chain treasury movement against your accounting ledger, watches multisig configuration for signer and threshold drift, and produces a period-close pack with the transaction evidence already attached.
GET /v1/treasury/reconciliation?period=2026-06
→ 200 OK
{
"period": "2026-06",
"matched": { "count": 1841, "value_usd": "48219004.11" },
"unmatched": [
{ "kind": "on_chain_only", "tx": "0x4c1a…",
"value_usd": "12500.00", "chain": "solana",
"suggestion": "fee rebate — no ledger entry" },
{ "kind": "ledger_only", "entry": "JE-20614",
"value_usd": "3400.00",
"suggestion": "posted to wrong wallet" }
],
"policy_events": [
{ "kind": "SIGNER_ADDED", "safe": "0x9f…", "at": "2026-06-14T08:11Z",
"approved_by": null }
]
}
An unmatched item comes with a suggested cause rather than a bare discrepancy. The signer change with approved_by: null is the kind of finding that matters most and is easiest to miss.
movements auto-matched in the sample period
chains and every multisig on them, in one close
typical unmatched rate after the first month of mapping
of matches carry a linked on-chain transaction
Figures describe the current production deployment and are restated each quarter. Ask for the latest measurement report before you cite them.
A treasury spread across three chains, several multisigs and a handful of exchange accounts is reconciled by exporting CSVs and matching by hand. It works at fifty movements a month. At two thousand it silently stops working, and the failure mode is a close that balances because someone forced it to.
The higher-stakes gap is configuration. A signer added to a Safe, a threshold lowered from 3-of-5 to 2-of-5, a module enabled — each is a governance event with real loss potential, and none of them appear in an accounting system at all.
Wallets, multisigs, exchange accounts and internal transfer pairs are mapped to your chart of accounts once. Internal movement between your own addresses stops appearing as revenue, which is where most of the first month's noise comes from.
Movement is matched to ledger entries continuously, not at period end, using amount, timing, counterparty and your own reference conventions. Unmatched items surface with a suggested cause while the context is still fresh.
The period-close pack contains matched totals, remaining exceptions with owners, and every policy event in the window with whether it was approved. It exports as a document your auditor can accept without re-deriving anything.
| Field | Type | Meaning |
|---|---|---|
| matched | object | Count and value auto-matched in the period, with a link to each pair. |
| unmatched[].kind | string | on_chain_only · ledger_only · amount_mismatch · timing_mismatch. |
| unmatched[].suggestion | string | Most likely cause, with confidence. A suggestion, never an auto-posting. |
| policy_events[] | array | Signer, threshold and module changes on watched multisigs, with approval state. |
| approved_by | string | null | Null means the change happened with no recorded approval. Alert on this. |
| close_pack_url | string | Signed link to the period document, regenerated whenever an exception is resolved. |
Ledger Mind removes the manual matching and the blind spots. It does not sign off on your accounts, and it cannot see what never touched a chain you gave us.
Run a closed period through Ledger Mind and compare. Teams usually find between two and ten movements the manual close never saw.