Search the German commercial register (Handelsregister) and download all registry documents — including the Gesellschafterliste (shareholder list) and Gesellschaftsvertrag (articles of association) — from the command line or from Python.
The official portal handelsregister.de has been free of charge since August 2022, but offers no API: every document sits behind a JavaServer-Faces UI that wants you to click through a search form and a document tree, per company, per document. This tool automates exactly those clicks.
The well-known bundesAPI/handelsregister
project automates the search; document download has been an open TODO there since
2022. handelsregister-cli is an independent implementation that does both.
Suchbegriffe / keywords: Handelsregisterauszug herunterladen, Gesellschafterliste download, Gesellschaftsvertrag PDF, Handelsregister API, Registerportal automation, German commercial register, company registry Germany.
For any company registered in Germany (GmbH, UG, AG, KG, e.K., …):
- Search the register by keywords or exact company name (court, register number, state, status per result).
- Download the directly served documents of a result:
Code Document ADAktueller Ausdruck — current registry printout (PDF) CDChronologischer Ausdruck — chronological printout (PDF) HDHistorischer Ausdruck — historical printout, older companies only (PDF) SIStrukturierter Registerinhalt — structured register content (XML) - Walk the DK document folder ("Dokumentenansicht") — the tree that holds the substantive filings — and download every document in it: Gesellschafterlisten (shareholder lists), Gesellschaftsverträge / Satzungen (articles of association), Gründungsprotokolle, Handelsregisteranmeldungen, Listen der Übernehmer, Einwilligungen, and whatever else the court filed.
- Deduplicate and name files sensibly. The portal lists the same physical PDF
under up to three folders; downloads are deduplicated by SHA-256, name
collisions between different documents get a
(2)suffix, and amanifest.jsonrecords every file with its checksum, size and origin.
No accounts, no API keys, no fees — the register is free by law (DiRUG).
uv tool install git+https://github.com/DespotB/handelsregister-cli
# or: pipx install git+https://github.com/DespotB/handelsregister-cli
# or: pip install git+https://github.com/DespotB/handelsregister-cliPython ≥ 3.9. Dependencies: mechanize, beautifulsoup4.
AI agents / coding assistants: see AGENTS.md for a self-contained install-and-use recipe (Claude Code users can install the plugin instead).
# 1. Find the company
hreg search "arcneo"
# [0] arcneo GmbH
# Berlin District court Berlin (Charlottenburg) HRB 261478 | Berlin | currently registered
# documents: AD, CD, DK, SI, UT, VÖ
# 2. See what's in its document folder (no downloads yet)
hreg tree "arcneo" --register "HRB 261478"
# 3. Download everything into ./arcneo GmbH/
hreg fetch "arcneo" --register "HRB 261478"
# Only the current printout and the shareholder-list folder:
hreg fetch "arcneo" --docs AD,DK -o ./arcneo-docs
# Machine-readable output for scripting:
hreg search "arcneo" --json
hreg fetch "arcneo" --json > result.jsonUseful flags: --mode exact|all|any (keyword matching), --select N /
--register "HRB …" (pick a result row), --delay SECONDS (default 3, see
Rate limits).
The portal's only date-based feed is its Registerbekanntmachungen section.
Note what it is — and what it is not: since the DiRUG reform (Aug 2022) new
company registrations are no longer published as announcements anywhere;
the feed carries five categories: Löschungsankündigungen, announcements under
the Umwandlungsgesetz (mergers etc.), new document filings, and two "other"
buckets. hreg automates that search plus a diff-based watch mode:
# Everything announced today in Berlin
hreg announcements --land BE
# Last 7 days, nationwide, only mergers/conversions, machine-readable
hreg announcements --days 7 --category umwandlung --json
# Keyword filter (OR-matched against name, seat, category, court, register no.)
# --details additionally fetches the full announcement text (1 extra request each)
hreg announcements --days 3 --keyword holding --keyword immobilien --details
# Cron-friendly watcher: prints only items not seen on a previous run.
# Also watches a normal register search — new register numbers matching a
# name keyword are the closest free approximation of "newly registered
# companies named/branded X". First run only seeds the state file.
hreg watch --days 3 --land BE --keyword holding \
--search "fintech" --search "holding" \
--state ~/.hreg-watch.json \
--notify-cmd 'jq -r .name | xargs -I{} notify-send "Handelsregister" {}'--notify-cmd runs once per new item with the item's JSON on stdin — pipe it
into mail, Slack, ntfy, or whatever you like. A crontab line makes it a
notification service:
0 9 * * * hreg watch --days 3 --land BE --search "solar" --notify-cmd '...'from handelsregister_cli import Portal
from handelsregister_cli.files import FileSink, looks_like_document
portal = Portal("arcneo GmbH", mode="all")
hits = portal.search()
company = hits[0]
# Direct downloads (AD / CD / HD / SI)
pdf = portal.fetch_direct(company.index, "AD")
# The DK document folder
dk = portal.open_dk(company.index)
sink = FileSink("out/")
for node in dk.walk_tree().values():
if node.leaf and "Gesellschafter" in node.label:
data = dk.download_leaf(node.rowkey)
if looks_like_document(data):
sink.write(node.label, data, source=f"dk:{node.rowkey}")The portal is a JSF/PrimeFaces application. The tool replays the exact form
submissions a browser performs: the advanced-search form, the PrimeFaces command
links behind each document code, and the partial-AJAX tree expansion of the
document view (Faces-Request: partial/ajax, ViewState tracking, CDATA-wrapped
tree updates). docs/DESIGN.md documents the wire format and
all known quirks — read it before filing a "layout changed" issue.
This is screen-scraping. It is inherently fragile: any portal redesign can break it. Offline tests run against recorded responses; if the portal changes, please open an issue with the failing command and Python version.
- The portal historically throttles at roughly 60 requests/hour per client.
A full
fetchof a young GmbH is ~50 requests. The default--delay 3keeps you polite; don't lower it to loop over company lists. - This tool is built for targeted, occasional lookups (due diligence on a counterparty, pulling your own company's filings, KYC on a handful of entities). It deliberately has no bulk/crawl mode. For bulk or SLA-bound needs use a commercial provider (e.g. handelsregister.ai, North Data, OpenCorporates).
- You are responsible for complying with the portal's terms of use and, when re-using the data, with GDPR — registry documents contain personal data (names, birth dates, addresses of directors and shareholders).
- No captcha solving; if the portal ever gates a request, the tool fails loudly instead of working around it.
UT(Unternehmensträgerdaten) andVÖ(Veröffentlichungen) are HTML views, not files, and are currently not fetched.- One company per invocation, by design.
- There is no feed of new company registrations: the advanced search has no
date filter, and since DiRUG (Aug 2022) Neueintragungen are not announced
anywhere.
hreg watch --search(diffing a keyword search) is the closest free approximation; for a real feed use a commercial provider.
The repo doubles as a Claude Code plugin marketplace. Inside Claude Code:
/plugin marketplace add DespotB/handelsregister-cli
/plugin install handelsregister@handelsregister-cli
Then ask for e.g. /handelsregister arcneo GmbH — the skill installs the CLI on
first use (uv/pipx/pip, whichever is available), runs the fetch and reports the
downloaded files.
Codex supports the same open Agent Skills
format (SKILL.md), so the bundled skill works there too — copy it into your
skills directory:
git clone https://github.com/DespotB/handelsregister-cli /tmp/hrcli
mkdir -p ~/.codex/skills
cp -r /tmp/hrcli/skills/handelsregister ~/.codex/skills/Then ask Codex for registry documents in natural language (skills support is experimental in Codex; enable it in your Codex config if needed).
The repo is also a Gemini CLI extension (gemini-extension.json + a
/handelsregister command):
gemini extensions install https://github.com/DespotB/handelsregister-cligit clone https://github.com/DespotB/handelsregister-cli
cd handelsregister-cli
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest # offline tests against recorded fixtures
.venv/bin/ruff check src tests- bundesAPI/handelsregister — pioneered the search automation; this project started as an attempt to close its document-download TODO and became an independent implementation.
- Lilith Wittmann: "Wir befreien das Handelsregister" — background on why the register is free but still hard to use programmatically.
MIT