Bundesanzeiger Scraper — German Filings & Financials
Pricing
from $1.50 / 1,000 publication scrapeds
Bundesanzeiger Scraper — German Filings & Financials
Scrape bundesanzeiger.de, Germany's federal gazette: annual reports with parsed financials (revenue, equity, net income), insolvency notices, company announcements and capital-markets filings. Free built-in CAPTCHA solving, full publication text, multi-query runs.
Pricing
from $1.50 / 1,000 publication scrapeds
Rating
0.0
(0)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
0
Bookmarked
17
Total users
16
Monthly active users
13 hours ago
Last modified
Categories
Share
Bundesanzeiger Scraper — German Corporate Filings, Financials & Insolvencies
Turn Germany's federal gazette into structured data. Search the ~1.5M German entities that publish on bundesanzeiger.de and get annual reports with parsed financials, insolvency notices, shareholder announcements, and capital-markets filings — full publication text included, image CAPTCHA solved automatically at no extra cost.
Run any number of search queries in one job, filter by publication area, and export JSON, CSV, or Excel.
How it works

Why use this scraper?
Commercial providers (Northdata, Creditreform) charge EUR 20–50 per document for data German companies are legally required to publish for free. This scraper reads the primary source directly.
- Built-in CAPTCHA solving, free. Financial statements sit behind an image CAPTCHA. This actor solves it locally with an on-device ML model — no CapSolver account, no per-solve fees baked into your price. 100% solve rate (with retry) in live testing.
- Full publication text. The complete filing text on every row — not a 1,000-character excerpt.
- Structured financials. Revenue, total assets, equity, net income, and employee count parsed from annual reports where the text allows it.
- Multiple queries per run. Pass a list of company names, HRB/HRA numbers, or keywords — each is searched in parallel.
- No artificial caps.
maxItemsis yours to set; there is no built-in 100-row ceiling. - No proxy required. Bundesanzeiger serves plain HTTP requests. You pay for data, not infrastructure ceremony.
Overview
Bundesanzeiger (the German Federal Gazette) is the official disclosure platform where German companies publish annual accounts, courts publish insolvency and judicial notices, and issuers publish capital-markets information. This actor searches it like the website does — by full-text query and publication area — then opens every result and returns one dataset row per publication with entity info, publication metadata, the complete text, and (for annual reports) best-effort structured financials.
Typical users: credit-risk teams screening counterparties, M&A analysts tracking corporate changes, B2B lead-gen teams sizing German companies, compliance teams monitoring insolvencies, and researchers citing primary-source disclosures.
Supported inputs
- Company names —
SAP SE,BMW AG,Mittelstand Maschinenbau GmbH - Register numbers —
HRB 12345,HRA 98765 - Any full-text keyword —
Berlin,Photovoltaik,Wirecard - Publication area filter — one of the seven gazette areas, or all of them (see the table below)
Not supported: direct bundesanzeiger.de URLs (the site's URLs are session-bound and expire — they cannot be re-opened), login-gated content, and paid Unternehmensregister documents.
Publication areas
| Value | German | English |
|---|---|---|
| (empty) | Alle Bereiche | All areas |
22 | Rechnungslegung/Finanzberichte | Financial Reports |
5 | Gerichtlicher Teil | Judicial Part (insolvencies, court notices) |
6 | Gesellschaftsbekanntmachungen | Company Announcements |
7 | Kapitalmarkt | Capital Market |
1 | Amtlicher Teil | Official Part |
2 | Nichtamtlicher Teil | Non-official Part |
8 | Verschiedene Bekanntmachungen | Miscellaneous Announcements |
Use cases
| Team | What they build |
|---|---|
| Credit risk | Counterparty screening from balance-sheet equity and net income |
| M&A / PE analysts | Deal sourcing and target monitoring across the DACH market |
| B2B sales | Lead lists of German entities with known financial size |
| Compliance & litigation | Near-real-time insolvency and court-notice monitoring |
| Journalists & academics | Primary-source citations without commercial-database rates |
| Data teams | Bulk refresh of German company registries via API |
How it works
- You provide one or more search queries and (optionally) a publication area.
- The actor submits each search on bundesanzeiger.de in its own session and walks the result pages.
- Every publication in the results is opened in parallel.
- When a financial statement is guarded by the image CAPTCHA, the built-in ONNX model solves it on-device and retries automatically if the first answer is rejected.
- Each publication becomes one dataset row: entity, metadata, full text, and parsed financials.
Input configuration
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
queries | array | yes | – | Search terms — one search per entry (company name, HRB/HRA number, or keyword) |
area | string | no | "" | Publication area filter (see table above); empty searches all areas |
extractFinancials | boolean | no | true | Parse annual-report text for revenue, assets, equity, net income, employees |
onlyWithFinancials | boolean | no | false | Skip publications that carry no extractable figures, so you are not billed for them (see below) |
maxItems | integer | no | 100 | Global cap on dataset rows across all queries — no upper bound |
maxConcurrency | integer | no | 5 | Concurrent publication fetches per search session (1–20) |
proxy | object | no | off | Optional Apify proxy — not needed for normal use |
Example: annual reports for one company
{"queries": ["BMW AG"],"area": "22","extractFinancials": true,"maxItems": 20}
Example: monitor Berlin insolvencies
{"queries": ["Berlin"],"area": "5","extractFinancials": false,"maxItems": 100}
Example: portfolio screen across many companies
{"queries": ["Siemens AG", "SAP SE", "Deutsche Bahn AG", "Volkswagen AG"],"area": "","maxItems": 400}
Output overview
One row per publication. Every row carries the entity name and city, the publication area (German label plus English translation), title, ISO publication date, the complete publication text, and a stable search URL for the entity. Annual-report rows additionally carry the fiscal-year end from the title and — when extractFinancials is on and the report text is parseable — a financials object with the key figures in absolute EUR.
💡 Not every gazette publication is a financial report
A Bundesanzeiger search returns whatever was published, and a good share of it has no figures by its nature — most commonly
Bekanntmachung nach §§ 264 Abs. 3, 264b HGBexemption notices, which run about 750 bytes and exist precisely to say that the company is exempt from publishing accounts. Those rows still carry their full text, and for a compliance or monitoring use case they matter. But billing is per row, so if you are after figures, setonlyWithFinancials: trueand pay only for rows that have them.Measured on a live run (
Sparkasse Aachen+Zalando SE, area 22): 8 rows without the flag, 3 with it — the five dropped were exemption notices, short announcement stubs, and one consolidated report whose figures were deliberately refused (see the segment-reporting note below).
⚠️ Changed behaviour — money figures are now normalised to absolute EUR
German filings print their figures under a unit header (
in Mio. EUR,IN MIO. EUR,in TEUR,in Tsd. EUR, or plainEUR). The actor previously emitted the printed number and ignored that header, so a filer reporting in millions came out a million times too small and could not be compared with a filer reporting in plain euros — in the same column, in the same dataset.As of build 0.0.6,
totalAssets,totalEquity,revenueandnetIncomeare always absolute EUR. Zalando SE's 2021 revenue, printed as10.354,0underUmsatzerlöse (in Mio. EUR), now returns10354000000— it used to return10354.If you already consume these fields, they changed meaning. Every figure now carries its provenance so you can check the conversion yourself:
financials.currency—"EUR", ornullwhen no figure could be resolvedfinancials.reportingUnit/reportingUnitScale— the unit the filing used, e.g."Mio. EUR"/1000000financials.figureAudit.<field>—{ printed, unit, unitScale, unitSource, unitEvidence, lineLabel, columnYears, columnIndex }: the number as printed, the factor applied, where the unit came from, the literal text it was read from, the filing's own wording for the line it was taken from, and — for a multi-year table — the years the header declared plus the column that was read.unitSourceisinline(the unit sits next to the figure),precision(the figure is written to the cent, which only a full-EUR amount ever is), orheader(the nearest governing column header)financials.unresolvedFigures— fields where a number was found but could not be safely attributedAnything listed in
unresolvedFiguresis emitted asnullon purpose, and there are five reasons a field lands there: the unit could not be established; the label appeared only in prose or as a narrower sub-item; several statement lines carry the label and disagree; the row spans several year columns and the header could not say which one is the reporting year; or the document is a consolidated report with segment reporting. Read this array before treating anullas "not disclosed".employeeCountis a head count and is never scaled.Disagreeing lines are refused, not ranked. A large filing often states the same label more than once — group statement, parent balance sheet, a note. One HORNBACH
Konzernabschlussoffers 1.761,3, 14,2 and 380.316 forEigenkapital. Nothing in the text says which one belongs in the row, so picking the first would be picking at random; the field is dropped and flagged instead. A document that simply restates the same printed figure is not a conflict.Figures come from the reporting year's column, not the first one printed. German statements put the comparative year first about as often as they put it last — Sparkasse Aachen's own filings print
2021 | 2020in one year and2018 | 2019in another. The parser therefore reads the table's year header, matches it against the filing'sfiscalYearEnd, and takes THAT column;figureAudit.<field>.columnYearsand.columnIndexrecord which. When a row has several columns and the header cannot place the reporting year among them, the field isnulland listed inunresolvedFiguresrather than guessed. An audit of 53 emitted figures against their source documents found 17 that were the prior year before this existed.
The same label can name different lines — so the filing's own wording is published. A Sparkasse's management report calls the aggregate including the Fonds für allgemeine Bankrisiken "das Eigenkapital", while the audited balance sheet's own
Eigenkapitalline is hundreds of millions smaller. Both are defensible answers to "equity", and a bare number cannot tell you which you got — sofigureAudit.<field>.lineLabelcarries the line exactly as the filing wrote it, e.g.Eigenkapital (inkl. Fonds für allgemeine Bankrisiken).
Figures are read from statement lines, not prose. A number is only emitted when the label owns its own line in a statement —
Umsatzerlöse 10.354,0,A. Eigenkapital 25.000,Summe Eigenkapital 548.870,04. A sentence can be about anybody ("die beteiligte Landesbank weist eine Bilanzsumme von 5,3 Mrd. EUR aus" is another institution's balance sheet), and a narrowed label is a different item —Umsatzerlöse aus Arbeitnehmerüberlassungis one sub-line of revenue, not revenue. Both are skipped and reported throughunresolvedFigures.Consolidated reports with segment reporting return no money figures. A
Konzernabschlussprints every headline label once per segment, once per region and once for the group, in tables that look identical and carry no cue as to which is the primary statement. Telling them apart needs real statement-structure parsing, so until that exists these documents report all four money fields throughunresolvedFigures—fullTextstill carries the complete filing.
Output sample
Real row (shortened fullText), produced by the "annual reports" example above:
{"entityName": "Unfallkrankenhaus Berlin Holding GmbH","entityCity": "Berlin","publicationArea": "Rechnungslegung/Finanzberichte","publicationAreaEn": "Financial Reports","publicationTitle": "Jahresabschluss zum Geschäftsjahr vom 01.01.2019 bis zum 31.12.2019","publicationDate": "2020-10-12","fiscalYearEnd": "31.12.2019","financials": {"totalAssets": null,"totalEquity": null,"revenue": null,"netIncome": 716737.84,"employeeCount": 26,"currency": "EUR","reportingUnit": "EUR","reportingUnitScale": 1,"figureAudit": {"netIncome": { "printed": 716737.84, "unit": "EUR", "unitScale": 1, "unitSource": "header", "unitEvidence": "EUR" }},"unresolvedFigures": []},"fullText": "Unfallkrankenhaus Berlin Holding GmbH\n\nBerlin\n\nJahresabschluss zum Geschäftsjahr vom 01.01.2019 bis zum 31.12.2019\n\nBilanz zum 31. Dezember 2019\n\nAktivseite …","documentUrl": "https://www.bundesanzeiger.de/pub/de/start?fulltext=Unfallkrankenhaus%20Berlin%20Holding%20GmbH","query": "Jahresabschluss GmbH Berlin","scrapedAt": "2026-07-22T21:26:31.530Z"}
Key output fields
Entity — entityName (legal name), entityCity (registered city, or several, e.g. "Berlin und München").
Publication — publicationArea / publicationAreaEn (gazette area, German + English), publicationTitle, publicationDate (ISO YYYY-MM-DD), fiscalYearEnd (annual reports only, German DD.MM.YYYY as printed in the title).
Content — fullText (complete cleaned publication text, uncapped; null only in the rare case the CAPTCHA could not be solved after retries), documentUrl (bundesanzeiger.de search URL pre-filled with the entity name — the free gazette issues no permanent per-document links, so match the filing by publicationTitle + publicationDate).
Financials (financials object, annual reports with extractFinancials: true) — totalAssets (Bilanzsumme), totalEquity (Eigenkapital), revenue (Umsatzerlöse), netIncome (Jahresüberschuss, negative for Jahresfehlbetrag), employeeCount. Money fields are absolute EUR, normalised from whatever unit the filing printed (see the changed-behaviour note above); employeeCount is a head count and never scaled. All best-effort: German reports vary wildly in formatting, so fields that cannot be confidently located — or whose unit cannot be established — stay null rather than guessing.
Financial provenance — currency, reportingUnit, reportingUnitScale, figureAudit (per field: printed, unit, unitScale, unitSource, unitEvidence), unresolvedFigures. Use figureAudit to reproduce any number: printed × unitScale is the value in the matching field.
Bookkeeping — query (which of your search terms found the row), scrapedAt (ISO timestamp).
FAQ
How do I scrape Bundesanzeiger?
Enter one or more search terms, optionally pick a publication area, set maxItems, and run. The actor handles the search, pagination, publication pages, and the CAPTCHA.
Does it really solve the CAPTCHA for free? Yes. Financial statements are guarded by a simple image CAPTCHA. The actor ships the open-source ONNX character-recognition model from the bundesAPI/deutschland project (Apache-2.0, by Nico Duldhardt and Friedrich Eichenroth) and solves it on-device. In live testing it solved 95% of challenges on the first attempt and 100% within one retry. There is no external solver service and no per-solve fee.
Can it parse financials from every annual report?
No — and any tool that claims otherwise is guessing. German filings range from clean HGB balance sheets to ESEF/XBRL viewers with no parseable prose. When figures can be located confidently they are returned; otherwise the field is null and you still get the full text to parse your own way.
I asked for N documents — do I get N? Yes, whenever the search actually holds N usable ones. If a publication page cannot be read, the actor backfills from the remaining rows of the result set instead of returning short, and names the skipped filing in the run log. Large filers' combined "Jahres- und Konzernabschluss" is published as an ESEF/XBRL package with no inline text on bundesanzeiger.de — those are logged with a pointer to the official disclosure files rather than billed as an empty row.
Why is there no direct link to the document?
Bundesanzeiger's free gazette is session-based and issues no permanent per-document URLs. documentUrl is a stable search link pre-filled with the entity name — open it and match the filing by title and date.
Do I need a proxy? No. The site serves plain HTTP requests fine. A proxy option exists in the input for very heavy volume, but normal runs do not need it.
Can I pass bundesanzeiger.de URLs as input? No — the site's URLs are bound to a browsing session and expire within minutes. Searches by query reproduce them reliably.
How fresh is the data? Live. Every run performs a real search against bundesanzeiger.de and reads the current results.
Support
- Found a bug or need a field that isn't there? Open an issue on the actor's Issues tab in Apify Console — issues are answered quickly, usually within 24 hours.
- Feature requests are welcome and often shipped within days.
Additional services
Need bulk entity lists (thousands of register numbers), scheduled insolvency monitoring with deltas only, deeper XBRL/ESEF parsing, or delivery straight to your warehouse? Custom work is available — reach out via the Issues tab or memo23's Apify profile.
Explore more scrapers
More scrapers and actors for job boards, real estate, company data, and social media at memo23's Apify profile.
🤖 For AI Agents & LLM Apps
Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/bundesanzeiger-scraper).
Purpose: searches bundesanzeiger.de (German federal gazette) by query + publication area and returns one row per corporate publication with full text and parsed financials; solves the site's image CAPTCHA locally at no extra cost.
Minimal input:
{ "queries": ["SAP SE"], "maxItems": 10 }
Output: one dataset row per publication — entityName, entityCity, publicationArea, publicationAreaEn, publicationTitle, publicationDate, fiscalYearEnd, financials {totalAssets, totalEquity, revenue, netIncome, employeeCount, currency, reportingUnit, reportingUnitScale, figureAudit, unresolvedFigures}, fullText, documentUrl, query, scrapedAt.
Behaviors an agent should know:
- Always set
maxItems— broad keywords match hundreds of thousands of publications (e.g. "Berlin" ≈ 590k in area 22). areanarrows to one gazette section:"22"financial reports,"5"insolvencies/judicial,"6"company announcements,"7"capital market,""all.financialsmoney fields are absolute EUR (normalised from the filing's ownin Mio. EUR/in TEURheader); checkfigureAuditfor the printed value and the factor applied. Fields listed inunresolvedFiguresarenullbecause the unit was unknown — never treat anullas a zero.financialsfields are best-effort and oftennull;fullTextis always the fallback source of truth.- Direct bundesanzeiger.de URLs are NOT valid input (session-bound); search by name or HRB/HRA number instead.
- Billing is pay-per-event (run start + per dataset row); CAPTCHA solving adds nothing to the price.
⚠️ Disclaimer
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Bundesanzeiger Verlag GmbH, the German Federal Ministry of Justice, or any of their subsidiaries. All trademarks mentioned are the property of their respective owners.
The scraper accesses only publicly available gazette publications — no authenticated endpoints, no paid Unternehmensregister features, and no content behind a login wall. Users are responsible for ensuring their use complies with bundesanzeiger.de's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.
SEO Keywords
bundesanzeiger scraper, bundesanzeiger api, german company data, jahresabschluss scraper, german annual reports, german company financials, insolvency notices germany, insolvenzbekanntmachungen, german federal gazette, hrb number lookup, german company registry, unternehmensregister alternative, credit risk germany, german corporate filings, kapitalmarkt bekanntmachungen, gesellschaftsbekanntmachungen, scrape bundesanzeiger.de, german business intelligence, dach company data, northdata alternative