Neu: Satzung & Gesellschaftervertrag per API abrufen – und mit LLMs automatisiert analysieren
Der neue document_type articles_of_association macht Satzungen und Gesellschafterverträge per API abrufbar. So baust du eine LLM-Pipeline, die aus Register-PDFs strukturierte Daten extrahiert – für Due Diligence, Compliance und LegalTech.
Satzungen und Gesellschafterverträge sind die Dokumente, an denen Legal-, M&A- und Compliance-Teams am Ende wirklich hängenbleiben: Da steht drin, wie eine Gesellschaft funktioniert, nicht nur, dass sie existiert. Und genau diese Dokumente waren bisher der größte Medienbruch in vielen Automatisierungsprojekten. Du klickst dich durchs Registerportal, lädst PDFs manuell herunter, speicherst sie irgendwo ab, und ab da ist „Automation" erstmal vorbei.
Ab sofort gibt es dafür eine Lösung: Im fetch-document-Endpoint der handelsregister.ai API steht ein neuer document_type bereit: articles_of_association. Damit kannst du programmatisch die Satzung (AG) bzw. den Gesellschaftervertrag (GmbH/UG) als Original-PDF aus dem Handelsregister abrufen. Ein einziger API-Call.
Kurz zur Klarstellung, weil die Begriffe gerne durcheinandergeworfen werden: Es gibt nur einen neuen Parameterwert, articles_of_association, und der deckt beides ab. Im Handelsregister werden Satzung und Gesellschaftervertrag unter demselben Dokumenttyp geführt.
In diesem Artikel schauen wir uns an, wie du das Feature nutzt, welche Informationen in diesen Dokumenten stecken und vor allem: wie du mit LLMs eine robuste Analyse-Pipeline baust, die aus PDFs echte, strukturierte Daten macht.
Warum Satzungen bisher ein Automations-Bottleneck waren
Rein rechtlich ist die Lage klar: Die Einsicht in das Handelsregister und die dort eingereichten Dokumente ist jedem zu Informationszwecken gestattet. In der Praxis läuft der Zugriff aber über Web-Portale, die PDFs ausliefern, nicht über eine stabile, entwicklerfreundliche Schnittstelle.
Das Problem wird größer, sobald du skalierst. Ein einzelner Deal ist per Hand machbar. Aber wenn du 50 Targets, 300 Lieferanten oder das gesamte Portfolio eines VCs prüfen willst, ist „PDF klicken" keine Strategie mehr. Du brauchst eine Pipeline, die reproduzierbar, fehlertolerant und versionierbar ist.
Hinzu kommt: Viele Register-Dokumente sind nicht ohne weiteres „LLM-ready". Teilweise sind es textbasierte PDFs, teilweise Scans oder Mischformen, bei denen ohne OCR kein verwertbarer Text herauskommt. Dass gescannte PDF/A-Dokumente trotz ihrer weiten Verbreitung im Notar-Umfeld nicht automatisch maschinenlesbar sind, ist ein bekanntes Thema in der Register-Digitalisierung.
Was in einer Satzung oder einem Gesellschaftervertrag typischerweise drinsteht
Bevor wir in Code gehen, kurz der juristische Kontext, damit du weißt, wonach du später mit LLMs überhaupt sinnvoll suchen kannst.
Bei der GmbH schreibt das GmbHG Mindestinhalte für den Gesellschaftsvertrag vor (§§ 2, 3 GmbHG): Firma und Sitz, Unternehmensgegenstand, Stammkapital sowie die Geschäftsanteile, die jeder Gesellschafter übernimmt. Der Vertrag bedarf notarieller Form. Für Standardfälle gibt es das vereinfachte Verfahren über das Musterprotokoll. Das ist praktisch relevant, weil solche Dokumente oft sehr standardisiert sind und sich gut automatisiert auslesen lassen.
Bei der AG ist die Satzung ebenfalls formgebunden (§ 23 AktG), mit ähnlichen Pflichtangaben zu Gründern, Kapital und Unternehmensgegenstand.
In der Praxis geht der Inhalt aber weit über die gesetzlichen Mindestangaben hinaus, und genau das macht diese Dokumente für Due Diligence und Automatisierung so spannend. Die folgenden Klausel-Cluster tauchen regelmäßig auf und lassen sich gut automatisiert screenen:
- Geschäftsführung & Vertretung: Einzel- oder Gesamtvertretung, Zustimmungskataloge, ggf. Verweis auf Geschäftsordnungen.
- Gewinnverteilung: Standardverteilung nach Anteilen oder abweichende Regeln.
- Anteilsübertragung (Vinkulierung): Zustimmungserfordernisse für Abtretungen, oft als Schutz vor unerwünschten Gesellschaftern.
- Vorkaufsrechte: Mitgesellschafter bekommen das Erstangebot, bevor Anteile an Dritte gehen.
- Drag-/Tag-Along: Exit-Mechaniken, die Transaktionen erleichtern oder Minderheiten schützen.
Gerade Drag-/Tag-Along sind ein gutes Beispiel, warum reine Registerauszüge (AD/CD) oft nicht reichen: Die Existenz der Gesellschaft ist dort klar dokumentiert, aber die Exit-Fähigkeit steckt in den Vertragsdetails.
Satzung per API abrufen: document_type=articles_of_association
Das neue Feature ist bewusst simpel gehalten. Du nutzt den bestehenden fetch-document-Endpoint, nur eben mit einem zusätzlichen document_type. Aktuell sind damit genau diese Werte möglich: AD, CD, shareholders_list und neu articles_of_association.
Der Call erwartet eine company_id (die Entity-ID aus den Suchergebnissen) und den document_type. Bei Erfolg bekommst du direkt ein PDF zurück.
Minimalbeispiel mit curl
# Satzung / Gesellschaftervertrag abrufen
curl 'https://handelsregister.ai/api/v1/fetch-document?api_key=YOUR_API_KEY&company_id=COMPANY_ID&document_type=articles_of_association' \
-o satzung.pdf
Minimalbeispiel mit Python requests
import requests
url = "https://handelsregister.ai/api/v1/fetch-document"
params = {
"api_key": "YOUR_API_KEY",
"company_id": "COMPANY_ID",
"document_type": "articles_of_association"
}
response = requests.get(url, params=params)
with open("satzung.pdf", "wb") as f:
f.write(response.content)
Python mit dem offiziellen SDK
Wenn du lieber nicht selbst Requests zusammensteckst: Das offizielle Python-SDK (pip install handelsregister) bietet eine fetch_document-Methode. Du kannst den neuen Typ einfach als String durchreichen.
from handelsregister import Handelsregister
client = Handelsregister(api_key="YOUR_API_KEY")
# 1) Company ID via Suche holen
company = client.fetch_organization(q="Konux GmbH München")
company_id = company["entity_id"]
# 2) Satzung / Gesellschaftervertrag als PDF abrufen
client.fetch_document(
company_id=company_id,
document_type="articles_of_association",
output_file="konux_articles_of_association.pdf",
)
Praxisdetails, die dir später Zeit sparen
Rate Limits. Dokument-Downloads sind auf 5 Requests pro Minute begrenzt (allgemeine Requests: 60/min). Für Batch-Jobs heißt das: Queue, Backoff und Resumability einplanen.
Verfügbarkeit. Nicht jedes Unternehmen hat diese Dokumente digital verfügbar. Das ist kein Bug, sondern Datenrealität: Die Verfügbarkeit hängt davon ab, ob und wann das jeweilige Registergericht die Dokumente digitalisiert und eingereicht hat.
Fehlerbehandlung. Bei Erfolg kommt ein PDF, bei Fehler JSON mit Details. Prüfe also immer HTTP-Status und Content-Type, bevor du Bytes in eine .pdf-Datei schreibst:
import requests
url = "https://handelsregister.ai/api/v1/fetch-document"
params = {
"api_key": "YOUR_API_KEY",
"company_id": "COMPANY_ID",
"document_type": "articles_of_association",
}
resp = requests.get(url, params=params, timeout=60)
content_type = resp.headers.get("content-type", "")
if resp.status_code == 200 and "application/pdf" in content_type:
with open("satzung.pdf", "wb") as f:
f.write(resp.content)
else:
try:
err = resp.json()
except Exception:
err = {"raw": resp.text[:500]}
raise RuntimeError(f"fetch-document failed: {resp.status_code} {err}")
Technischer Deep Dive: Satzungen mit LLMs robust analysieren
Das PDF herunterladen ist der einfache Teil. Die eigentliche Frage ist: Wie machst du daraus Daten? Und zwar so, dass du das Ergebnis automatisiert weiterverarbeiten kannst und bei Audits nicht sofort wieder manuell nachprüfen musst.
Eine Pipeline, die sich in der Praxis bei Register-PDFs bewährt hat: Download → Text/OCR → Strukturierung → LLM-Extraktion → JSON → Persistenz und QA.
PDF → Text: erst messen, dann OCR
Schritt 1: Prüfe, ob das PDF eine Textschicht hat. PyMuPDF (pymupdf/fitz) ist dafür schnell und flexibel. Mit page.get_text("text", sort=True) bekommst du Plain Text in natürlicher Lesereihenfolge.
Schritt 2: Wenn kein Text da ist, OCR. OCRmyPDF ist der pragmatische Standard: Es fügt gescannten PDFs eine OCR-Textschicht hinzu und nutzt dafür die Tesseract-Engine. Im Register- und Notar-Umfeld, wo PDF/A verbreitet ist, brauchst du das häufiger als man denkt.
Ein Minimal-Snippet, das beides kombiniert:
import subprocess
import pymupdf
def extract_text_with_fallback(pdf_path: str) -> str:
doc = pymupdf.open(pdf_path)
chunks = []
for page in doc:
chunks.append(page.get_text("text", sort=True))
text = "\n".join(chunks).strip()
# Heuristik: Wenn kaum Text vorhanden, OCR-Variante erzeugen
if len(text) < 1000:
ocr_path = pdf_path.replace(".pdf", ".ocr.pdf")
subprocess.run(
["ocrmypdf", "-l", "deu", "--deskew", pdf_path, ocr_path],
check=True,
)
doc = pymupdf.open(ocr_path)
chunks = [p.get_text("text", sort=True) for p in doc]
text = "\n".join(chunks).strip()
return text
Text → Struktur: Paragraphen statt Token-Suppe
LLMs sind gut, aber nicht magisch. Wenn du ihnen 40 Seiten unstrukturierten OCR-Text gibst, bekommst du oft auch eine unstrukturierte Antwort zurück. Zwei einfache Regeln helfen:
- Gliedere nach typischen Markern wie „§", „Abs.", Ziffern und Überschriften (z.B. „Gegenstand", „Stammkapital", „Geschäftsführung"). Das passt gut zu Satzungstexten im deutschen Stil und erleichtert späteres Chunking.
- Behalte den Seitenbezug. Wenn du später Red Flags automatisch flaggst, willst du immer zurückspringen können: Auf welcher Seite steht das? Genau diese Nachvollziehbarkeit ist auch im RAG-Setup der wichtigste Hebel gegen Halluzinationen.
Prompt Engineering für juristische PDFs
Bei der Extraktion aus Satzungen und Gesellschafterverträgen funktionieren Prompts am besten, die vier Dinge gleichzeitig tun:
Erstens: Klar definieren, was extrahiert werden soll. Offene Fragen wie „Fasse den Vertrag zusammen" liefern in der Regel unbrauchbare Ergebnisse. Besser: eine geschlossene Liste konkreter Felder (Stammkapital, Vertretungsregelung, Übertragungsbeschränkungen usw.).
Zweitens: Eine Null-Strategie haben. Wenn eine Klausel nicht im Dokument steht, soll das Modell null zurückgeben, statt zu raten. Gerade bei Drag-Along oder Vinkulierung ist „nicht vorhanden" eine valide und wichtige Information.
Drittens: Evidence mitschreiben lassen. Zu jedem extrahierten Feld ein kurzes Belegzitat (max. 25 Wörter) und die Seitenzahl. Damit kannst du automatisiert QA machen, ohne jedes Dokument manuell lesen zu müssen.
Viertens: Structured Output erzwingen. Freitext-Antworten sind für Menschen lesbar, aber für Pipelines Gift. Du willst JSON, das direkt in eine Datenbank oder einen Vergleichs-Report fließen kann.
Ein Beispiel-Prompt, vendor-agnostisch und auf deutsche Gesellschafterverträge zugeschnitten:
System-Instruktion: Du bist ein Legal-Analyst für deutsche Gesellschaftsverträge. Nutze ausschließlich den gegebenen Text. Wenn eine Information nicht eindeutig im Text steht, setze das Feld auf
nullund schreibe keine Vermutungen.Aufgabe: Extrahiere (1) Stamm-/Grundkapital, (2) Vertretungsregelung, (3) Anteilsübertragungsbeschränkungen (Zustimmung/Vorkaufsrecht/Vinkulierung), (4) Drag-Along/Tag-Along (falls vorhanden).
Output: Gib nur JSON zurück, nach dem unten stehenden Schema. Füge zu jedem gefundenen Feld mindestens ein kurzes Belegzitat (max. 25 Wörter) und die Seitenzahl hinzu.
Das „nur aus dem Text, keine externen Quellen"-Prinzip ist zentral, weil Halluzinationen in juristischen Kontexten besonders teuer werden.
Structured Output: JSON, das du in eine Datenbank schreiben kannst
„LLM gibt JSON zurück" klingt banal, ist es in der Praxis aber nicht. Pipelines scheitern oft an Details: fehlende Keys, plötzlich Strings statt Zahlen, Freitext in Enum-Feldern. Nutze deshalb schema-constrained Output (JSON Schema, Tools oder Structured Outputs), damit die Antwort an ein definiertes Schema gebunden ist.
Ein sinnvolles Schema für Satzungs-Screening:
{
"capital": {
"amount_eur": null,
"type": null
},
"representation": {
"rule": null,
"evidence": []
},
"transfer_restrictions": {
"requires_consent": null,
"pre_emption_right": null,
"vinkulierung": null,
"evidence": []
},
"exit_clauses": {
"drag_along": { "present": null, "threshold": null, "evidence": [] },
"tag_along": { "present": null, "threshold": null, "evidence": [] }
}
}
Warum threshold? Weil Drag-/Tag-Along in der Praxis oft an Schwellen hängen (Mehrheitsquoten, Mindestangebote, Anteilsklassen). Genau das will ein Investor wissen.
Batch-Analyse: Portfolio-Scan statt Einzelfall
Sobald du articles_of_association als PDF abrufen kannst, ist der nächste logische Schritt: Batch-Screening. Ein typisches VC-Szenario: „Analysiere die Satzungen aller Portfolio-Unternehmen auf einheitliche Transfer- und Exit-Klauseln und flagge Abweichungen."
Die Pipeline dafür:
- Liste der
company_ids aus CRM oder Portfolio-Datenbank laden. - Für jede ID:
fetch-documentmitdocument_type=articles_of_association. - PDF → Text/OCR mit Qualitätschecks (Seitenzahl, Textlänge).
- LLM-Extraktion → JSON (schema-constrained).
- Speichern, QA laufen lassen (Belege, Seiten, Versionierung, Timestamp).
Denk dabei an das Dokument-Rate-Limit (5/min) und baue Idempotenz ein: Wenn der Job abbricht, soll er nicht von vorne anfangen.
RAG-Ansatz: Satzungen als Wissensbasis
Wenn du nicht nur Fakten extrahieren, sondern auch Fragen beantworten willst ("Darf Gesellschafter X ohne Zustimmung verkaufen?"), ist RAG oft der bessere Ansatz als reine Extraktion. Du indexierst dann nicht nur ein JSON, sondern auch den Text (chunked), zusammen mit Metadaten wie company_id, Abrufdatum, Dokumenttyp und Seitenzahlen.
Genau diese Metadaten-Disziplin und Pipeline-Checks (PDF nicht leer? Parser liefert Text?) sind der Unterschied zwischen einem Demo-Chatbot und einem System, das du intern vertreten kannst.
Wenn du den RAG-Teil tiefer bauen willst: Der Artikel Handelsregisterauszüge in RAG-Projekten zeigt eine praxistaugliche Herangehensweise für Register-PDFs. Und wenn du eher „LLM-native" arbeiten willst, lohnt sich auch ein Blick auf den MCP Server von handelsregister.ai.
Anwendungsfälle: wo articles_of_association sofort Mehrwert bringt
VC Due Diligence. Schon früh in der Prüfung wird geschaut, ob Sonderrechte, Vorkaufsrechte oder Exit-Klauseln existieren und ob sie die nächste Runde oder den Exit blockieren können. Mit articles_of_association kannst du das Screening automatisieren und nur die auffälligen Fälle an Legal eskalieren.
Compliance und KYB. Für KYC-/Onboarding-Workflows sind Registerdaten die Primärquelle für Existenz, Rechtsform und Vertretungsregeln. Die Satzung kann zusätzliche Regeln enthalten, die über den reinen Auszug (AD) hinausgehen, etwa besondere Zustimmungserfordernisse.
M&A. Drag-/Tag-Along, Vinkulierung und Vorkaufsrechte beeinflussen unmittelbar die Transaktionsmechanik und Closing-Risiken. Wenn du 20 Targets vergleichen willst, brauchst du strukturierte Daten, keine 20 offene PDF-Tabs.
LegalTech-Produkte. Wenn du Tools baust (Deal Desk, Investor Relations, Governance Dashboards), kannst du articles_of_association als Datenquelle für Features wie einen Klausel-Finder, Abweichungs-Scanner oder Investor-Readiness Score nutzen. Immer mit Rücklink auf das Original-PDF und Belegstellen, denn „Evidence first" ist hier kein Nice-to-have, sondern Produkt-Requirement.
Fazit: weniger PDF-Hölle, mehr Automatisierung
Mit document_type=articles_of_association kannst du Satzungen und Gesellschafterverträge jetzt programmatisch als Original-PDF aus dem Handelsregister ziehen, direkt über den bestehenden fetch-document-Endpoint. Der Rest ist Engineering: PDF-Qualität prüfen, OCR bei Bedarf einschieben, strukturieren, mit LLMs schema-konform extrahieren und idealerweise mit Evidence absichern, damit du Ergebnisse später prüfen und in Workflows übernehmen kannst.
Wenn du den Kontext zu den bestehenden Dokumenttypen nochmal kompakt brauchst: Der Artikel Handelsregister-Dokumente per API abrufen erklärt den generellen Dokumentabruf (AD, CD, shareholders_list) und wie du daraus reproduzierbare Prozesse baust. Für den Einstieg in strukturierte Company-Daten, IDs und Python-Beispiele ist Firmendaten per API die passende Grundlage.
Loslegen: API-Key registrieren, fetch-document aufrufen, erste Satzung runterladen, LLM-Pipeline bauen. Ob du mit einem einzelnen Dokument anfängst oder direkt einen Batch-Scan über dein Portfolio laufen lässt, bleibt dir überlassen. Die API ist da, die Tools sind Open Source, und die Dokumente warten darauf, gelesen zu werden. Viel Spaß beim Automatisieren.