Bundesanzeiger Scraper — German Filings & Financials avatar

Bundesanzeiger Scraper — German Filings & Financials

Pricing

from $1.50 / 1,000 publication scrapeds

Go to Apify Store
Bundesanzeiger Scraper — German Filings & Financials

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

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

17

Total users

16

Monthly active users

13 hours ago

Last modified

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

How Bundesanzeiger Scraper 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. maxItems is 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 namesSAP SE, BMW AG, Mittelstand Maschinenbau GmbH
  • Register numbersHRB 12345, HRA 98765
  • Any full-text keywordBerlin, 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

ValueGermanEnglish
(empty)Alle BereicheAll areas
22Rechnungslegung/FinanzberichteFinancial Reports
5Gerichtlicher TeilJudicial Part (insolvencies, court notices)
6GesellschaftsbekanntmachungenCompany Announcements
7KapitalmarktCapital Market
1Amtlicher TeilOfficial Part
2Nichtamtlicher TeilNon-official Part
8Verschiedene BekanntmachungenMiscellaneous Announcements

Use cases

TeamWhat they build
Credit riskCounterparty screening from balance-sheet equity and net income
M&A / PE analystsDeal sourcing and target monitoring across the DACH market
B2B salesLead lists of German entities with known financial size
Compliance & litigationNear-real-time insolvency and court-notice monitoring
Journalists & academicsPrimary-source citations without commercial-database rates
Data teamsBulk refresh of German company registries via API

How it works

  1. You provide one or more search queries and (optionally) a publication area.
  2. The actor submits each search on bundesanzeiger.de in its own session and walks the result pages.
  3. Every publication in the results is opened in parallel.
  4. 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.
  5. Each publication becomes one dataset row: entity, metadata, full text, and parsed financials.

Input configuration

FieldTypeRequiredDefaultDescription
queriesarrayyesSearch terms — one search per entry (company name, HRB/HRA number, or keyword)
areastringno""Publication area filter (see table above); empty searches all areas
extractFinancialsbooleannotrueParse annual-report text for revenue, assets, equity, net income, employees
onlyWithFinancialsbooleannofalseSkip publications that carry no extractable figures, so you are not billed for them (see below)
maxItemsintegerno100Global cap on dataset rows across all queries — no upper bound
maxConcurrencyintegerno5Concurrent publication fetches per search session (1–20)
proxyobjectnooffOptional 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 HGB exemption 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, set onlyWithFinancials: true and 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 plain EUR). 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, revenue and netIncome are always absolute EUR. Zalando SE's 2021 revenue, printed as 10.354,0 under Umsatzerlöse (in Mio. EUR), now returns 10354000000 — it used to return 10354.

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", or null when no figure could be resolved
  • financials.reportingUnit / reportingUnitScale — the unit the filing used, e.g. "Mio. EUR" / 1000000
  • financials.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. unitSource is inline (the unit sits next to the figure), precision (the figure is written to the cent, which only a full-EUR amount ever is), or header (the nearest governing column header)
  • financials.unresolvedFigures — fields where a number was found but could not be safely attributed

Anything listed in unresolvedFigures is emitted as null on 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 a null as "not disclosed". employeeCount is 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 Konzernabschluss offers 1.761,3, 14,2 and 380.316 for Eigenkapital. 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 | 2020 in one year and 2018 | 2019 in another. The parser therefore reads the table's year header, matches it against the filing's fiscalYearEnd, and takes THAT column; figureAudit.<field>.columnYears and .columnIndex record which. When a row has several columns and the header cannot place the reporting year among them, the field is null and listed in unresolvedFigures rather 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 Eigenkapital line is hundreds of millions smaller. Both are defensible answers to "equity", and a bare number cannot tell you which you got — so figureAudit.<field>.lineLabel carries 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überlassung is one sub-line of revenue, not revenue. Both are skipped and reported through unresolvedFigures.

Consolidated reports with segment reporting return no money figures. A Konzernabschluss prints 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 through unresolvedFiguresfullText still 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

EntityentityName (legal name), entityCity (registered city, or several, e.g. "Berlin und München").

PublicationpublicationArea / publicationAreaEn (gazette area, German + English), publicationTitle, publicationDate (ISO YYYY-MM-DD), fiscalYearEnd (annual reports only, German DD.MM.YYYY as printed in the title).

ContentfullText (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 provenancecurrency, 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.

Bookkeepingquery (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).
  • area narrows to one gazette section: "22" financial reports, "5" insolvencies/judicial, "6" company announcements, "7" capital market, "" all.
  • financials money fields are absolute EUR (normalised from the filing's own in Mio. EUR / in TEUR header); check figureAudit for the printed value and the factor applied. Fields listed in unresolvedFigures are null because the unit was unknown — never treat a null as a zero.
  • financials fields are best-effort and often null; fullText is 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