Skip to content
LedgerDock

Close the books.
Close them right.

A close tool for accountants. The model proposes, you approve, and the period locks as a signed record.

No language model sits between a statement and your ledger. Nothing reaches the ledger until a person commits it.

Before the period will lock Four assertions
Cash ties Every bank and card account agrees with its statement. ties
Nothing unfiled No fact is still sitting in staging. clear
Clearing is empty Every clearing account nets to zero. 0.00
Schedules posted Loan and depreciation entries are in the ledger. 1 open

Written explanation required. Depreciation on one asset is not posted; the invoice has not arrived. It will be recorded next period.

signed by you · hashed into the close commit
Illustrative. The four assertions are computed from the books every time you open the close. A failing one is fixed, or explained in writing, and the explanation is sealed in beside your name.

It refuses
on purpose.

The list of things LedgerDock will not have is deliberate, and it is not going to shrink.

  • invoicing
  • bill pay
  • payment application
  • open items
  • agings
  • an item master
  • quantities or costing
  • check printing
  • payroll calculation or filings
  • a matcher that composes transactions
  • anything real-time

And it refuses to send your clients anywhere.

The models are self-hosted. No client data goes to a third-party AI provider. Payroll arrives as an import through a clearing account; it is not calculated and it is not filed.

You stop typing transactions.
You start approving them.

The old way puts the human first: someone types the entry, and the bank feed arrives later to put a checkmark next to it. LedgerDock runs the other way.

How a transaction gets recorded: the old way compared with LedgerDock.
The old way LedgerDock
Who goes first The human. Someone types the entry. The feed. It is the starting point.
How a line arrives The bank feed arrives later to put a checkmark next to it. Lines arrive already coded, with the reason stated.
Who decides A person. A person still decides.

The whole argument, in a minute.

What the tool does, why it refuses to post on its own, and what the lock is actually certifying.

Seventy six seconds. Every figure in it is illustrative, and every claim in it is on this page.

How a month moves.

Six stages, from a PDF that nobody has read to a period that is locked. The model does the reading. A person does the deciding, and only a person can close.

  1. 1Drop or feed

    Bank and card feeds arrive through Plaid, read only. Everything else you drop as a file. Both end up in front of a person before anything can post.

  2. 2Skill

    A skill is the how to read this for one source. The model builds it on the first read and foots it. Next month the same statement reads itself.

  3. 3Staging

    Read rows land in staging, not in the ledger. The app calls one of these rows a fact. Nothing has been asserted yet.

  4. 4Review

    Decisions shows what needs a person: the vendor, the amount, the account it proposes, and in plain English why it is asking.

  5. 5Commit

    Approved work is sealed into a commit, hashed and chained to the one before it. One commit covers exactly one account.

  6. 6Lock

    Four assertions run against the books. Anything still failing must be fixed, or explained in writing.

If it does not tie,
it does not land.

The model never invents an amount. Rows are pulled by deterministic code, and the extraction has to foot against the totals printed on the statement itself before it is accepted.

The model builds the reader for a statement, repairs it when the bank changes its layout, and then gets out of the way. Deterministic code produces every figure, and the footing is the only gate.

Every failing line needs a reason before the lock.
One statement, footed
Operator Line Amount
Opening balance 12,480.15
plus Deposits and credits (21) 41,206.88
less Withdrawals and debits (127) 38,914.73
equals Closing balance, computed from the rows 14,772.30
Closing balance, printed on the statement 14,772.30
Difference 0.00

Foots Accepted

148 rows accepted.

Totals are read from the document at run time. Nothing is stored as an answer key.

Illustrative figures. The check is arithmetic, and it runs on every statement, every month.

Watch it refuse.

Everything above is drawn from the product's own structures. This is the product itself: one assertion failing, the lock refusing, a reason typed, and the period sealed.

The close screen, running, in one unedited take. A demonstration company with seeded books. One assertion is failing, so Lock is refusing. The reason is typed, and then the period locks.

Every engagement, twelve months, one board.

One row per company, the last twelve months as columns. Each cell is open, in review, or locked, computed from the books rather than from a status somebody remembered to set.

Close board. One row per engagement, the last twelve months as columns. Every cell states whether that month is locked, in review, or open.
Engagement SepOctNovDecJanFebMarAprMayJunJulAug
Freight carrierS-corp Sep: locked Oct: locked Nov: locked Dec: locked Jan: locked Feb: locked Mar: locked Apr: locked May: locked Jun: locked Jul: in review Aug: open
Tile contractorLLC Sep: locked Oct: locked Nov: locked Dec: locked Jan: locked Feb: locked Mar: locked Apr: locked May: locked Jun: locked Jul: locked Aug: in review
Home care agencyS-corp Sep: locked Oct: locked Nov: locked Dec: locked Jan: locked Feb: locked Mar: locked Apr: locked May: locked Jun: in review Jul: in review Aug: open
Boutique retailSole prop Sep: locked Oct: locked Nov: locked Dec: locked Jan: locked Feb: locked Mar: locked Apr: locked May: locked Jun: locked Jul: in review Aug: open
TransportPartnership Sep: locked Oct: locked Nov: locked Dec: locked Jan: locked Feb: locked Mar: locked Apr: locked May: locked Jun: locked Jul: locked Aug: in review
ConstructionS-corp Sep: locked Oct: locked Nov: locked Dec: locked Jan: locked Feb: locked Mar: locked Apr: open May: open Jun: in review Jul: in review Aug: open
  • Locked
  • In review
  • Open
  • Illustrative. Cell state is computed, never set by hand.

Open a number. The work is underneath it.

Trust comes from being able to follow a figure down, not from an accuracy claim. Every ledger row carries the id of the commit that approved it.

commit c-1042
prev   c-1041
hash   9f4c…a71e Each commit is hashed and chained to the one before it, so the record of what happened cannot be quietly rewritten.

Account Expenses, period to date Amount
60000 Advertising 1,250.00
61000 Insurance 3,600.00
62100 Repairs and maintenance 9,412.60
03-31 Operating account statement, 2026-03 · 2 rows · commit c-1042 7,070.60
04-09 Operating account statement, 2026-04 · 1 row · commit c-1047 1,342.00
04-12 Card statement, 2026-04 · 3 rows · commit c-1051 1,410.00
04-18 Vendor credit note, 2026-04 · 1 row · commit c-1054 410.00
Four commits, footed to the line 9,412.60
63400 Fuel 22,180.45
64100 Office and software 2,940.15
65200 Professional fees 5,600.00
Total expenses 44,983.20

Illustrative figures, and the disclosure is the real behaviour: the number expands in place, into the commits that recorded it. A credit is shown in parentheses.

Two things that fall out of the ledger.

1099 and W-9, computed

Not a separate module. It is a query over work you have already recorded, and it is recomputed rather than stored.

Built from
The payments you already recorded
Recomputed
Every time you open it
Filing line
$600 through 2025 · $2,000 from 2026
Where it shows
The missing W-9 list sits beside the close checklist every December

Your books leave in one click

Export everything gives you one zip of CSVs. There is no ticket to raise and nothing to negotiate.

Nine files
Chart of accounts, transactions, the ledger, every commit, loans, fixed assets, vendors, the decision log, the audit log
Never in it
Encrypted identifiers
To leave
No export ticket · no exit fee

Questions a sceptic asks first.

Does the model post entries by itself?

No. An entry reaches the ledger only after a person commits it. The model builds the reader for a statement, repairs it when a bank changes its layout, and reads images.

It does not run your month. Once the reader exists, next month is read by deterministic code and checked by arithmetic.

Where is the AR and AP aging?

There is not one, on purpose. An aging is a tool for chasing money, not for tying a balance.

AR and AP are accounts here, not modules: the balance is asserted against the figure you were given, with the source recorded, and it ties or it does not. The chase list belongs in the software the client already runs.

Does it replace my general ledger?

For the close, LedgerDock is the ledger. It keeps exactly two subsidiary ledgers, loans and fixed assets, because both generate their own schedules from a few inputs and nothing outside the system holds them.

The rule behind that: a table exists only when a close assertion has to tie to detail that lives nowhere else. A bank balance does not, it ties to a statement. Balances that verify externally get an assertion, not machinery.

Is this daily bookkeeping software?

No. LedgerDock is built for the close, month-end and year-end. Payroll arrives as an import through a clearing account; it is not calculated and it is not filed.

If LedgerDock ever became company-management software, that would be a different product decision, not a feature request.

See a close
from the inside.

Six stages, and a checklist that will not let you lock quietly.

Free for one set of books. $29 a month for one company, $79 for a practice of five. One subscription covers the client companies you close under it.

The same four, at the end Locked
Cash tiesties
Nothing unfiledclear
Clearing is empty0.00
Schedules postedexplained in writing
locked byyou
period2026-08
Illustrative. Nothing here is typed by hand: the states are computed, and the explanation is the one you wrote.
Depreciation on one asset is not posted; the invoice has not arrived. It will be recorded next period.
the reason you wrote, sealed into the close commit
close hash
a10d…77b2
chained to
3b90…c412