Bundesanzeiger: fetch annual accounts with a workflow template
A counterparty's published accounts are public, but they sit behind a search form, a result list and sometimes a security check. This template runs the search, opens the newest Jahresabschluss and returns balance sheet total, equity and result as JSON.
How a person does it on bundesanzeiger.de
From the portal's public pages. The Bundesanzeiger needs no account for reading; what slows people down is the sequence, not the access.
-
Search in the right section
On the start page, restrict the search to Rechnungslegung/Finanzberichte and enter the company name. A name-only search across all sections returns register announcements and calls to creditors as well.
-
Pick the right publication
The result list shows one row per publication: company, title (typically Jahresabschluss zum Geschäftsjahr vom ... bis ...), publication date. Several entities can share a name; the seat in the title is how you tell them apart.
-
Pass the security check when it appears
Opening a document sometimes shows a Sicherheitsabfrage, a captcha, before the text is displayed. The public pages do not say when it appears; in practice it is intermittent.
-
Read or save the document
The accounts are displayed as text on the page. Balance sheet, income statement and notes follow one another; small companies publish less, and the smallest only deposit their balance sheet.
-
Check the Unternehmensregister for newer years
Accounts for financial years beginning after 31 December 2021 are published in the Unternehmensregister rather than the Bundesanzeiger. Older years remain where they were.
Who looks companies up here, and how often
Every job below is the same eight clicks, repeated for a list of names.
- KYC and onboarding
- A compliance analyst opens the accounts of every new supplier or customer above a threshold, notes equity and result and files the source. Twenty names a week means the same search twenty times.
- Credit control
- Before extending payment terms, finance checks the last published year of a customer. The interesting number is usually the ratio of equity to balance sheet total, which is two figures from one page.
- Portfolio monitoring
- Someone re-checks a fixed list of counterparties each quarter for a newly published year. Nothing changed for most of them, which is exactly the kind of check people stop doing.
- What breaks
- The captcha, the near-identical company names and the split between Bundesanzeiger and Unternehmensregister since 2022. An analyst who opened the wrong Musterbau GmbH has filed a wrong number with a correct-looking source.
Template and publish call
Six blocks, no credential. The validation block is what stops a security check from being read as a set of figures.
{
"title": "Bundesanzeiger: fetch a company's published annual accounts",
"parameters": [
{
"key": "company",
"description": "Company name as registered, e.g. Musterbau GmbH",
"required": true
}
],
"blocks": [
{
"blockType": "navigation",
"label": "Start",
"url": "https://www.bundesanzeiger.de/"
},
{
"blockType": "action",
"label": "Search",
"instruction": "In the search on the start page restrict the area to Rechnungslegung/Finanzberichte, enter {{ company }} as the search term and run the search"
},
{
"blockType": "extraction",
"label": "Publications",
"instruction": "Every result for {{ company }}: publishing company, document title, financial year, publication date",
"schema": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"company": {
"type": "string"
},
"title": {
"type": "string"
},
"financialYear": {
"type": "string"
},
"publishedOn": {
"type": "string"
}
},
"required": [
"company",
"title"
]
}
}
},
"required": [
"results"
]
}
},
{
"blockType": "action",
"label": "Open_newest",
"instruction": "Open the most recent Jahresabschluss (annual accounts) of {{ company }} from the result list"
},
{
"blockType": "validation",
"label": "Document_shown",
"criterion": "The full text of an annual financial statement is displayed on the page, not a security check (Sicherheitsabfrage), a search form or an error"
},
{
"blockType": "extraction",
"label": "Key_figures",
"instruction": "From the displayed annual accounts of {{ company }}: financial year, balance sheet total, equity, net income or loss for the year, average number of employees if stated, auditor if stated",
"schema": {
"type": "object",
"properties": {
"financialYear": {
"type": "string"
},
"balanceSheetTotal": {
"type": "number"
},
"equity": {
"type": "number"
},
"netResult": {
"type": "number"
},
"employees": {
"type": "integer"
},
"auditor": {
"type": "string"
}
},
"required": [
"financialYear"
]
}
}
]
}
import { Browserberg } from '@browserberg/sdk';
import template from './bundesanzeiger-financials.json' with { type: 'json' };
const bb = new Browserberg({
apiKey: process.env.BROWSERBERG_API_KEY,
baseUrl: 'https://browserberg.com',
});
const wf = await bb.workflows.publish(template);
// No login: any fresh session will do.
await using session = await bb.sessions.create();
const run = await bb.workflows.run(wf.workflowId, {
sessionId: session.id,
inputs: { company: 'Musterbau GmbH' },
});
if (run.status === 'completed') {
console.log(run.outputs.Key_figures_output);
} else {
// A security check stops the run at Document_shown; the block is named.
console.log(run.status, run.blocks.find((b) => b.status === 'failed'));
}
Note · Written from the public site, not verified against it
The search area label, the result columns and the security check are described as the Bundesanzeiger's public pages present them today. The template has not been run against the live portal as part of writing this page. Adjust the search instruction if the start page changes its layout.
No login, one captcha, and where the run stops
Browserberg has no connection to the Bundesanzeiger Verlag, which operates the portal; this page is about reading a public site with a browser you control.
There is no sign-in, so there is nothing to vault
Reading the Bundesanzeiger needs no account, which makes this the simplest portal template on the site: navigation, an action, two extractions and a validation. There is no login block, no takeover and nothing to expire beyond the Browserberg session itself.
The security check is the end of the run, not something to get around
The portal sometimes shows a captcha before a document. Browserberg does not solve captchas and does not try to look like something it is not; the session is an ordinary Chromium and the portal may treat it as one. The validation block Document_shown is there so that a run which hits the check fails at that block, with that reason, instead of extracting figures from a page that has none. If you want a person to pass the check, watch the run in the live view, take over when it stops, and start it again; the same session keeps whatever the portal remembers.
What the effect gates do here
There is nothing to submit on the Bundesanzeiger, so the gates have little to refuse. They still run: every click is classified by the element it lands on. A control offering to order a document against a fee would be a payment effect and refused under the default policy. Searching is a submit effect, the harmless kind, and runs.
Two portals since 2022
Accounts for financial years starting after 31 December 2021 are filed with the Unternehmensregister. The template as published searches the Bundesanzeiger; for a counterparty's most recent year, point the navigation block at the register portal and adjust the search instruction, keeping the extraction blocks. The figures you want are the same in both.
Facts about the portal this template relies on
| Access | Reading publications needs no account Bundesanzeiger public pages |
|---|---|
| Search sections | Rechnungslegung/Finanzberichte is a separate search area from register announcements and other notices Bundesanzeiger public pages |
| Security check | A captcha can appear before a document is displayed; the run stops there rather than solving it Bundesanzeiger public pages |
| Newer financial years | Financial years beginning after 31 December 2021 are published in the Unternehmensregister Unternehmensregister |
| Legal basis of publication | § 325 HGB obliges corporations to disclose their annual accounts § 325 HGB |
As of 2026-09-08
Questions from compliance teams
Does the template solve the captcha?
No. When the security check appears the validation block fails and names itself. A person can pass the check through the live view and restart the run on the same session; nothing in the product is built to bypass it.
How does it avoid picking the wrong company?
It cannot know which of two identically named companies you meant. The Publications extraction returns every result with title and year, so your system can check the seat before trusting the Key_figures output. Pass a more specific name, seat included, when you have one.
Are the figures reliable?
The extraction reads numbers as printed in the published accounts and reports what it could not find rather than guessing. Where a small company only deposits a balance sheet, equity and total are present and the result is not.
Why does a 2024 financial year not appear?
Because it was published in the Unternehmensregister, where filings for financial years beginning after 31 December 2021 go. Point the template's navigation block there for recent years.
Can I run it for a list of counterparties?
Yes: start one run per name, or wrap the blocks in a loop over a parameter holding the list. One run per name keeps a failure local, which matters when the captcha appears on the seventh of forty.
Read next
- Handelsregister extract The other half of a KYC file, from the register portal
- Building workflows Blocks, labels and how one block reads another's output
- Website to text Turn a public page into text before writing an extraction schema
- JSON schema generator Draft the extraction schema from an example
Run it on a counterparty you already checked
Five browser hours, no card. Compare the JSON with the file your analyst produced by hand.