Limitations
Five things Badlen does not do. They are not of the same kind, and sorting them is the point of this page.
Two are structural. They follow from what a self-hosted program is allowed to do, not from how much of it has been written, and no amount of work on this codebase removes them. Knowing them before you install is what matters most here.
Three are gaps. Nothing in the design stands in the way of any of them; they are simply not built. No version has been promised and no date is announced anywhere: a gap named here is a piece of work that is possible, not one that is scheduled.
Two structural limits
Section titled “Two structural limits”The second follows from the first, which is why they are together: a program that cannot read a bank is a program whose balances someone has to state.
No bank sync
Section titled “No bank sync”Nothing in Badlen synchronises with a bank, because nothing in it signs in to one. There is no aggregator, no screen-scraper and no open-banking connector, so no balance and no operation ever arrives on its own from an account you hold elsewhere.
This is not a gap, and it is not particular to this product. Four facts carry the answer:
- the gate on a European bank’s interface is not a price, it is an identity. A registered entity reaches an account, never a piece of software;
- no self-hosted open-source project holds that registration. Not one;
- the projects that do synchronise hand the compliance to you, and the free door that made this practical in Europe stopped taking new sign-ups;
- and the one thing this product is built not to do is ask you to put your bank access in the hands of a company you have never heard of: your credentials with some providers, and in every case a copy of your accounts on their servers.
One exception, and only one: a crypto wallet is declared by its chain and its public address, and the Synchronise button on that account’s settings tab reads the chain for what the address holds. It needs no credential of yours, because a public address is not one.
The law, the other projects and the choice, with sources
What the law asks
Section titled “What the law asks”Reading somebody’s payment accounts for them is a regulated activity in the European Union. Directive (EU) 2015/2366, better known as PSD2, calls it an account information service (Article 4(16)) and the one who performs it an account information service provider. Article 67 gives you the right to use such a service. It does not give a program the right to be one.
The regime is deliberately light for whoever does only that. Article 33(1) lifts most of the authorisation procedure, and the minimum capital requirement is among the things it lifts: a pure account information provider needs no capital at all. What survives is an insurance obligation (Article 5(3), professional indemnity insurance or a comparable guarantee), a file on governance, security and incident handling, and a registration with the national supervisor, which in France is the ACPR, under article L. 522-11-2 of the monetary and financial code.
So far this reads like paperwork and an insurance premium. The part that closes the door is the next one, and it is technical.
Regulation (EU) 2018/389, the technical standards that go with PSD2, says what a bank checks when something calls its interface. Article 34(1) requires a qualified eIDAS certificate: an electronic seal, or a certificate for website authentication. Article 34(2) says what has to be inside it:
the registration number … shall be the authorisation number of the payment service provider issuing card-based payment instruments, the account information service providers and payment initiation service providers … available in the public register of the home Member State pursuant to Article 14 of Directive (EU) 2015/2366
The certificate carries a registration number, and that number is looked up in a public register of registered entities. No number, no certificate; no certificate, no answer from any bank in the Union, however good the software asking.
The seal goes further than the live calls. Article 30(3) requires a bank to hand the technical documentation of its interface over “upon request by authorised payment initiation service providers, account information service providers … or payment service providers that have applied to their competent authorities for the relevant authorisation”. Even reading how the interface works is reserved to those who are registered or in the process of becoming so.
Banks say the same thing in their own words. OP Financial Group, publishing its PSD2 interface, tells a developer that going to production means applying “for an AISP/PISP license from a financial authority” and obtaining “valid QWAC and QSEAL certificates”; the sandbox is open to anyone, and it is a sandbox (op-developer.fi).
So the barrier is not a wall of money. It is a wall of identity. PSD2 nowhere says that free software may not read an account. It organises access around a named, registered, insured entity, and the technical standards turn that registration into a cryptographic object the bank verifies on every single call.
What that asks of software you install yourself
Section titled “What that asks of software you install yourself”A certificate belongs to somebody. It names an entity, that entity is registered, insured and supervised continuously, and it answers to its supervisor for every access made through it.
Badlen is a program a thousand people install on a thousand machines. There is no entity behind those thousand instances, so there is no registration number, so there is no certificate, so there is no bank on the other end of the line. What fails is not the code: it is the shape of the distribution. Shipping a connector that works out of the box would mean shipping a secret belonging to one registered entity to every reader, which is exactly the thing a certificate exists to prevent.
Putting a real entity in the middle is possible, and it is the other half of the answer. It would mean one operator standing between every reader and their bank, holding the registration, seeing the accesses, carrying the liability. That is a centralised service with a self-hosted front end, and it is the opposite of what installing the software on your own machine was for.
What the other open-source projects do
Section titled “What the other open-source projects do”The useful check is not what Badlen does. It is what everybody comparable does, and the answer is unanimous: no self-hosted open-source finance project holds an account information registration. They fall into three cases.
They do not connect at all. Ghostfolio lists no bank synchronisation; its data comes in by import and export, and its outside sources are quote providers.
You bring your own aggregator. This is what makes a project look like it synchronises when it does not. Firefly III routes its data importer through third-party providers rather than through a bank, and Actual Budget states the rule plainly: “This integration relies on you providing your own API credentials that you will need to get by signing up with the service provider”. The project ships the plumbing; the reader goes and becomes the aggregator’s customer. The registration, the contract and the liability are the reader’s.
They speak a client protocol, where one exists. GnuCash, through AqBanking, supports FinTS/HBCI in Germany, EBICS in Austria, Switzerland, Germany and France (“usually available for business customers”), and OFX Direct Connect in the United States. Firefly III reaches FinTS the same way. These protocols predate PSD2 and authenticate the reader with their own bank credentials rather than a provider with a certificate, which is why they work at all. Germany is the real exception: since 1 August 2019 FinTS access requires a registered product, that registration is granted free of charge by the Deutsche Kreditwirtschaft and processed in ten to fifteen working days (fints.org). It registers the client software, not a provider status. One country, one protocol.
And the bring-your-own-key route has narrowed
Section titled “And the bring-your-own-key route has narrowed”Firefly III and Actual both leaned on GoCardless Bank Account Data, the one European aggregator with a free tier a private individual could sign up to. It stopped taking newcomers. GoCardless says so on its own page: “New signups for Bank Account Data are currently disabled” (bankaccountdata.gocardless.com). Firefly III’s documentation says “GoCardless is sunsetting this free service and registration is unfortunately closed”, and Actual’s provider list carries GoCardless marked “not accepting new accounts”.
What is left asks for a company. Enable Banking, the European aggregator those projects now point at, activates a production application “once you have signed a contract with Enable Banking and completed the KYB process for your company”, and prices by volume with a monthly minimum (enablebanking.com). A restricted mode exists for linking your own accounts only, and it is built for a personal tool or a prototype rather than for a product thousands of people install.
So the route is not merely inconvenient today. For the reader Badlen is written for, a household rather than a business, it is closed.
Why Badlen chose differently
Section titled “Why Badlen chose differently”Everything above would still leave one option: ship the fields, let whoever can sign up with an aggregator paste their credentials in. Firefly III and Actual Budget do exactly that, and they are right to. They sell you control of your budget, and a detour through an aggregator serves that.
Badlen sells something else: that what you record stays on the machine you installed it on. A screen asking for an aggregator’s key would ask you to authorise a company whose name you learned on that screen to reach your bank for you, read every account and pass the contents along. Every figure in this product would then exist twice: once on your server, and once in a database you have no claim on.
That is a choice, not a consolation. The connector is not a feature sitting on a shelf waiting for a free afternoon. It is the one thing this product would have to stop being itself to ship. If that ever changes, it will change in a legal text, and this page will say so.
Sources
Section titled “Sources”Every claim above was read in the source named beside it. The primary texts:
- Directive (EU) 2015/2366 (PSD2), Articles 4(16), 5(3), 14, 33 and 67
- Commission Delegated Regulation (EU) 2018/389, Articles 30 and 34
- Code monétaire et financier, article L. 522-11-2, registration with the ACPR
The projects and the providers, each in its own documentation: Ghostfolio, Firefly III, Actual Budget, GnuCash, FinTS, GoCardless, Enable Banking, OP Financial Group.
Balances are what you type
Section titled “Balances are what you type”The value of a current account, a savings book, a life-insurance contract, a property or a loan is a figure you state, on a date, and correct later if it was wrong. Badlen keeps every stated balance and builds the history from them; it never guesses one.
What it does resolve by itself is the price of a security. One security held inside an account is what Badlen calls a line: you declare it by its ISIN and a quantity, and the quote comes from an outside source without you typing it. So the arithmetic is automatic and the input is declarative. A portfolio left untouched for six months therefore reports six-month-old balances, honestly labelled as such.
Three sources answer, and none of them is an account you open: OpenFIGI turns an ISIN into a listing’s ticker, Yahoo Finance quotes that listing, and CoinGecko quotes crypto in euros, with Binance filling in the long history it has and CoinGecko does not. A free CoinGecko Demo key and an OpenFIGI key raise the rate limits and are both optional, and Configuration lists them. A crypto wallet declared by its public address is read from the chain itself instead.
So what Badlen quotes is what those three can name: ETFs, shares and funds that have an ISIN and a listing, and the coins CoinGecko carries. What they do not quote is everything else you hold: a euro fund, an SCPI (the French unlisted property fund, shares in a landlord rather than in a building), a life-insurance contract, a property, a savings book, a loan. Those have no listing anywhere, so their value is the figure you state.
Three things it does not have yet
Section titled “Three things it does not have yet”One currency, and no conversion
Section titled “One currency, and no conversion”Every total in Badlen is expressed in euros, and nothing anywhere converts money: there is no exchange-rate source. A quote arriving in another currency is stored with the currency it came in and kept out of every figure, because summing a dollar close into a euro total is a wrong figure rather than a missing one.
The consequence is the part to weigh. A line quoted outside the euro is one no total can value. It is counted among the unpriced lines and the currency is named next to it, on each account and in the table of your lines. An account declared in another currency is refused at creation rather than added one for one.
What is missing is a rate source and the reading that would go with it, not a redesign. Every table that carries money already carries its own currency beside it, and the test suite makes each file touching a price state what it does about that currency, forbidding anyone to quietly filter on a hard-coded one. The door was left open on purpose. Walking through it is still real work (every converted figure in the history would have to say which rate it rests on), and it is not started.
No statement import from the interface
Section titled “No statement import from the interface”There is no CSV upload, no bank-statement parser and no import screen in the web
application. Operations get into Badlen one of two ways: typed one at a time from the
operations register, or written in batches through the /api/v1 surface, which is the
path the MCP server uses with an API key carrying the
transactions:write scope.
The route that writes a batch already exists, and Import statements documents it. What is missing is the half in front of it: something that reads a CSV, OFX or QIF file your bank hands you, and a screen to drop it on. That is the one way of getting data in that works for everybody, everywhere, with no third party, which is why most open-source finance tools treat it as the main road.
No mail server
Section titled “No mail server”Badlen sends no email. The one place that would need to, a forgotten password, writes its reset link to the application log instead, where an administrator with server access reads it:
docker compose logs app | grep "reset link"That is a self-hosting consequence rather than a design one, and it is the reason a single-reader instance should keep its password somewhere it can be found. One mail client wired into that one place would settle it; nothing else in the product waits on an email.
What it asks of you each month
Section titled “What it asks of you each month”The part that moves on its own needs nothing: a nightly run refreshes every quote and
records the day’s net worth, and a wallet’s Synchronise button reads the chain. The
part that does not is the hand: one balance per account whose value you state, entered
when it moves, and the operations, typed one at a time from the register or written in
batches through /api/v1.
How long that takes is not a figure this project has measured, and it follows what you hold: an instance of three savings books and an ETF is a few balances a quarter, one that tracks every operation on a current account is the register, every week. Nothing is due on a schedule and nothing breaks if you skip a month. The history holds the last figure you stated, labelled with the day you stated it.