Kundendaten anreichern
Deine Kundenliste mit Firmendaten ergänzen.
Du hast eine Liste mit Firmennamen, Orten oder Registernummern und willst sie um amtliche Firmendaten ergänzen. Dafür brauchst du nur fetch-organization, eine Suche vorab ist nicht nötig.
Firmen zuordnen
Schick pro Kunde eine Anfrage mit dem besten Merkmal, das du hast. Am besten sind Registergericht und Registernummer, denn sie sind eindeutig. Hast du sie nicht, nimm den Firmennamen mit Rechtsform und Ort. Unsere Beispielanfrage sucht die Hetzner Online GmbH, Ansbach HRB 6089, über Name und Ort.
curl -G "https://handelsregister.ai/api/v1/fetch-organization" \ -H "x-api-key: DEIN_API_SCHLUESSEL" \ --data-urlencode 'q=Hetzner Online GmbH Gunzenhausen'
import requests response = requests.get( "https://handelsregister.ai/api/v1/fetch-organization", headers={"x-api-key": "DEIN_API_SCHLUESSEL"}, params={ "q": "Hetzner Online GmbH Gunzenhausen", }, ) data = response.json()
const url = new URL("https://handelsregister.ai/api/v1/fetch-organization"); url.searchParams.append("q", "Hetzner Online GmbH Gunzenhausen"); const response = await fetch(url, { headers: { "x-api-key": "DEIN_API_SCHLUESSEL" }, }); const data = await response.json();
1{2 "entity_id": "94eb910fef13f94585c48c263fa446d4",3 "name": "Hetzner Online GmbH",4 "status": "ACTIVE",5 "registration": {6 "court": "Ansbach",7 "register_type": "HRB",8 "register_number": "6089"9 },10 "address": {11 "house_number": "25",12 "street": "Industriestraße",13 "postal_code": "91710",14 "city": "Gunzenhausen",15 "county": "Weißenburg-Gunzenhausen",16 "state": "Bayern",17 "country": "DEU",18 "coordinates": {19 "latitude": 49.12483,20 "longitude": 10.7805221 }22 },23 "meta": {24 "request_credit_cost": 5,25 "credits_remaining": 14526 }27}
Prüf die Antwort gegen deine Daten, etwa Postleitzahl oder Ort in address. Bei häufigen Namen kann sonst eine gleichnamige Firma kommen.
Speichere die entity_id zu deinem Kunden. Alle späteren Abrufe, Dokumente, Signals und Monitore laufen dann über diese Kennung.
ai_search=on-default) setzt du gezielt für unscharfe Einträge ein; er kostet 20 Credits zusätzlich, auch ohne Treffer.
Viele Firmen abrufen
fetch-organization erlaubt 60 Anfragen pro Minute. Schick die Anfragen gleichmäßig nacheinander. Bei HTTP 429 wartest du die Sekunden aus Retry-After ab. Brauchst du mehr, bieten wir mit Enterprise höhere Limits, siehe Preise.
Gib jeder Anfrage einen Idempotency-Key, etwa die Kundennummer. Wiederholst du sie mit demselben Key und denselben Parametern innerhalb von 24 Stunden, kostet sie nichts.
Bei HTTP 408 (die Anfrage hat zu lange gedauert) berechnet die API nichts, auch keinen AI-Mode. Bei einem Fehler ab 500 fällt nur ein gewählter AI-Mode an. Versuch es später mit demselben Idempotency-Key erneut.
Das Skript liest kunden.csv mit den Spalten id, name, city und register. In register steht die Registernummer mit Gericht, etwa Ansbach HRB 6089, oder nichts. Das Skript schreibt eine Kopie mit entity_id, Registergericht und Registernummer und zählt die verbrauchten Credits.
import csv import time import requests API = "https://handelsregister.ai/api/v1/fetch-organization" HEADERS = {"x-api-key": "DEIN_API_SCHLUESSEL", "Accept": "application/json"} PER_MINUTE = 60 # Limit von fetch-organization def lookup(row): # Registergericht mit Registernummer ist eindeutig, sonst Name und Ort q = row["register"] or f'{row["name"]} {row["city"]}' headers = {**HEADERS, "Idempotency-Key": f'kunde-{row["id"]}'} for attempt in range(5): response = requests.get(API, params={"q": q}, headers=headers, timeout=120) if response.status_code == 429: time.sleep(int(response.headers.get("Retry-After", "10"))) elif response.status_code in (408, 500, 502, 503, 504): time.sleep(30 * (attempt + 1)) else: break return response spent = 0 with open("kunden.csv", newline="") as source, open("kunden_angereichert.csv", "w", newline="") as target: reader = csv.DictReader(source) writer = csv.DictWriter(target, fieldnames=reader.fieldnames + ["entity_id", "registergericht", "registernummer"]) writer.writeheader() for row in reader: response = lookup(row) if response.status_code == 402: print("Guthaben reicht nicht, Lauf angehalten") break data = response.json() spent += data.get("meta", {}).get("request_credit_cost", 0) if response.status_code == 200: registration = data.get("registration") or {} row["entity_id"] = data["entity_id"] row["registergericht"] = registration.get("court") row["registernummer"] = f'{registration.get("register_type")} {registration.get("register_number")}' writer.writerow(row) time.sleep(60 / PER_MINUTE) print(f"Verbraucht: {spent} Credits")
Ein zweiter Lauf innerhalb von 24 Stunden kostet nichts. Die Antwort trägt dann Idempotency-Status: replayed und request_credit_cost 0.
1{2 "entity_id": "94eb910fef13f94585c48c263fa446d4",3 "name": "Hetzner Online GmbH",4 "meta": {5 "request_credit_cost": 0,6 "credits_remaining": 1457 }8}
enrich eine fertige Anreicherung für CSV-, JSON- und Excel-Dateien mit.
Kosten im Blick behalten
Vorab rechnest du mit der Preisliste: 5 Credits pro Firma für die Basisdaten, dazu der Preis jedes Features. Die Basisdaten kosten bei jedem Treffer. Features ohne Daten kosten nichts, die tatsächlichen Kosten liegen also oft darunter. Die Aufschläge sind keine Features: AI-Mode kostet auch ohne Treffer, Echtzeit bei jedem gelungenen Abruf.
| Was | Credits |
|---|---|
| Firmenprofil mit den Basisdaten | 5 |
| Jedes Feature, nur wenn es Daten liefert | 1 bis 80 |
| AI-Mode, auch ohne Treffer | +20 |
| Echtzeit, bei jedem erfolgreichen Live-Abruf | +10 |
Limit: 60 Anfragen pro Minute.
Was eine Anfrage tatsächlich gekostet hat, steht in jeder Antwort unter meta.request_credit_cost.
Was eine Anfrage gekostet hat, steht in meta.request_credit_cost, das restliche Guthaben in meta.credits_remaining. Summiere die Kosten mit, wie im Skript oben.
Vor jeder Anfrage prüft die API, ob dein Guthaben für den höchstmöglichen Preis reicht. Reicht es nicht, antwortet sie mit HTTP 402 und berechnet nichts. Das Skript hält dann an.
Guthaben und Verbrauch fragst du jederzeit kostenlos über account ab.
Typische Stolpersteine
- Registernummer ohne Gericht: Steht in deinen Daten nur „HRB 6089“, findet die API keine Firma. Ergänze das Registergericht oder nimm Name und Ort.
- Ein Key, eine Anfrage: Derselbe
Idempotency-Keymit anderen Parametern ergibt HTTP 422. Für eine geänderte Anfrage nimmst du einen neuen Key. - Format des Keys: Erlaubt sind bis zu 128 Zeichen aus Buchstaben, Ziffern und
. _ : -, am Anfang ein Buchstabe oder eine Ziffer. Einen Key in anderem Format ignoriert die API. Die Anfrage läuft dann ohne diesen Schutz. - Timeout: Mit Echtzeit oder vielen Features dauert eine Anfrage länger. Stell den Timeout deines Clients auf mindestens 120 Sekunden.