A standalone bookkeeping data platform for small and medium businesses. Designed for two deployment modes from a single codebase:
- Single-tenant — one business running locally (CLI + web dashboard)
- Multi-tenant SaaS — operating bookkeeping for 100–20,000+ clients
BookKeeper ingests financial data from bank feeds, OCR, accounting APIs, and manual entry, and produces categorized transactions, financial statements, tax exports, and dashboards.
Status: reference architecture — not a certified accounting system.
Pre-1.0, feature-complete through v0.13.0 (web dashboard), 507 tests passing locally. Schema and APIs may still change before 1.0.
Read that claim narrowly. Those tests exercise this implementation; they do not establish accounting correctness against authoritative fixtures. There is currently no CI, no security policy, no property-based ledger invariants, no live-PostgreSQL tenant-isolation/RLS testing, and no review by anyone with accounting-domain authority.
What this repository is good for is the architecture:
Decimalmoney handling throughout, double-entry invariants, audit trails, rules-before-ML categorization, local-first operation, and two tenancy strategies from one codebase. Do not run a real business's books on it.
- Bank import — OFX/QFX/CSV parsing with vendor-specific profiles (Chase, Capital One, etc.) and duplicate detection
- OCR ingestion — invoice/receipt extraction via local Ollama vision models (LLaVA) or cloud providers, with confidence-based human review
- Auto-categorization — deterministic rules first, scikit-learn TF-IDF + LogReg as fallback once 50+ corrections are collected
- Reports — P&L, balance sheet, cash flow statement (PDF + XLSX)
- Tax exports — Schedule C, 1099 tracking ($600 W-9 threshold), quarterly summaries
- Accounting sync — Xero API v2.0 (pull accounts/invoices/ transactions, push journal entries) with OAuth2 token refresh
- Reconciliation — fuzzy match by amount + date window
- Audit trail — immutable log of every mutation with before/after state
- Web dashboard — Flask-based UI with auth (JWT), ledger views, reconciliation, custom graph views
- Multi-tenancy — single | SQLite-per-tenant | PostgreSQL schema-per-tenant | PostgreSQL row-level security; same business code runs in all modes
- Privacy-first — all data local by default; cloud APIs are opt-in
- Money is
Decimal, neverfloat— DB stores 4 decimal places as TEXT - Double-entry enforced at the application level
- Rules before ML — deterministic categorization first
- PostgreSQL migration path baked in from day one
- SQLite WAL by default — zero-config single-file storage
Requires Python 3.11+.
git clone https://github.com/mbachaud/BookKeeper.git
cd BookKeeper
pip install -e .
python -m bookkeeper.cli init # create DB + default chart of accounts
python -m bookkeeper.cli import file.ofx # import bank transactions
python -m bookkeeper.cli categorize # auto-categorize transactions
python -m bookkeeper.cli report pl # generate P&L
python -m bookkeeper.cli backup # manual backupTo launch the web dashboard:
./run_dashboard.sh # macOS / Linux
run_dashboard.bat # WindowsDefault URL: http://127.0.0.1:8080.
All runtime configuration lives in bookkeeper.toml. See the
full configuration reference for every option. Key
sections:
[tenancy]—single|sqlite_per_tenant|postgres_schema|postgres_rls[database]— SQLite path, WAL mode, PostgreSQL URL[ingestion.ocr]— local Ollama vs. cloud provider, confidence threshold[processing]— categorization method, reconciliation tolerances[reporting.tax]— jurisdiction (US only for v1), 1099 tracking
Never hardcode values in source — always read from bookkeeper.toml via
bookkeeper.config.
pip install -e ".[ocr]" # Ollama vision integration
pip install -e ".[postgres]" # PostgreSQL backend
pip install -e ".[dev]" # pytest, ruffbookkeeper/
ingestion/ Data source connectors
bank/ OFX/QFX/CSV parsing
ocr/ Invoice/receipt vision extraction
sync/ Accounting software API sync (Xero)
manual/ Journal entry interface
processing/ Normalization, categorization, reconciliation
storage/ Database layer, migrations, audit, backup
reports/ Financial statements
exports/ Tax exports (Schedule C, 1099)
api/ REST endpoints
dashboard/ Flask web UI
tenancy/ Multi-tenant context, auth, RBAC
cli.py Command-line interface
config.py TOML config loader
Further reading lives under docs/:
docs/planning/GOALS.md— project goals and success criteriadocs/planning/MULTI_TENANT_ARCHITECTURE.md— SaaS scaling strategydocs/decisions/LANGUAGE_CHOICE.md— why Pythondocs/specs/CHART_OF_ACCOUNTS.md— preset chart definitionsdocs/MULTI_TENANT_GUIDE.md— operating multi-tenant deploymentsdocs/TENANCY_API_REFERENCE.md— tenancy API
pytest # full suite (507 tests)
pytest --cov=bookkeeper # with coverageTest fixtures under tests/fixtures/ are entirely synthetic.
Issues and pull requests are welcome. By contributing, you agree that your contributions will be licensed under the Apache License, Version 2.0, in line with the project's LICENSE.
BookKeeper is licensed under the Apache License, Version 2.0. See LICENSE and NOTICE for details.
Copyright 2026 Michael Bachaud
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0