Basic concepts
What you need to understand once to handle every response with confidence.
Eight concepts carry the whole API. Once you know them, you read every response correctly and know in advance what a request costs.
Find companies unambiguously
The parameter q of fetch-organization takes three kinds of input. The examples on this page are requests for Hetzner Online GmbH, Ansbach HRB 6089:
| Input | Example | When it fits |
|---|---|---|
| Company name |
Hetzner Online GmbH |
For getting started. Write the name as completely as it appears in the register. |
| Register court and register number |
Ansbach HRB 6089 |
Unique for every registered company. Court, register type and number belong together. |
| entity_id |
94eb910fef13f94585c48c263fa446d4 |
For follow-up requests. You get it in every response. |
The register number alone is not enough, because each register court assigns its own numbers. The order, on the other hand, is free: in the example, HRB 6089 Ansbach finds the same company.
curl -G "https://handelsregister.ai/api/v1/fetch-organization" \ -H "x-api-key: YOUR_API_KEY" \ --data-urlencode 'q=Ansbach HRB 6089'
import requests response = requests.get( "https://handelsregister.ai/api/v1/fetch-organization", headers={"x-api-key": "YOUR_API_KEY"}, params={ "q": "Ansbach HRB 6089", }, ) data = response.json()
const url = new URL("https://handelsregister.ai/api/v1/fetch-organization"); url.searchParams.append("q", "Ansbach HRB 6089"); const response = await fetch(url, { headers: { "x-api-key": "YOUR_API_KEY" }, }); const data = await response.json();
entity_id.
If the API finds no company, it responds with 404 and charges nothing. For fuzzy input, there is AI Mode (ai_search=on-default): it also finds the company from parts of the name and researches it on the web. It costs 20 extra credits, even if it finds no company. To get several candidates at once, use Search & Export.
Features
Every company profile contains the basic data, including name, legal form, status, register entry, address, purpose, industry, capital and representation rules. You request everything else as a feature, for example related_persons for the managing directors or financial_kpi for the Financial KPIs.
You pass several features with a repeated feature or as a list: features=related_persons,financial_kpi. Each feature appears in the response under its own key. Only publications is called history there.
curl -G "https://handelsregister.ai/api/v1/fetch-organization" \ -H "x-api-key: YOUR_API_KEY" \ --data-urlencode 'q=Hetzner Online GmbH' \ --data-urlencode 'feature=related_persons' \ --data-urlencode 'feature=financial_kpi'
import requests response = requests.get( "https://handelsregister.ai/api/v1/fetch-organization", headers={"x-api-key": "YOUR_API_KEY"}, params={ "q": "Hetzner Online GmbH", "feature": ["related_persons", "financial_kpi"], }, ) data = response.json()
const url = new URL("https://handelsregister.ai/api/v1/fetch-organization"); url.searchParams.append("q", "Hetzner Online GmbH"); url.searchParams.append("feature", "related_persons"); url.searchParams.append("feature", "financial_kpi"); const response = await fetch(url, { headers: { "x-api-key": "YOUR_API_KEY" }, }); const data = await response.json();
The API ignores unknown names without an error message, so check the spelling. Features that your plan does not include are left out and not charged.
All features with their prices are listed in fetch-organization, every field in the Data catalog.
Credits
Data requests cost credits. For a company profile, these rules apply:
- The base price of 5 credits applies when the API returns a company.
- A feature costs credits only when it returns data in the response. An empty feature is free, including
insolvency_publicationswithout entries. - Realtime and AI Mode are not features but surcharges with their own rules:
- Realtime costs 10 extra credits as soon as the live fetch succeeds. This also applies when it shows nothing new.
- AI Mode costs 20 extra credits, even if it finds no company. The surcharge is waived only when the API aborts the request with 408 because it takes too long.
- All other errors cost nothing.
The rule for each individual feature is in Billing, the prices in fetch-organization.
An example: the basic data with related_persons and financial_kpi costs 5 + 2 + 1 = 8 credits if both features return data.
Before each request, the API checks whether your balance covers the highest possible price. If it does not, the API responds with 402 and charges nothing. What was actually charged is in meta.request_credit_cost, your balance afterwards in meta.credits_remaining.
1{2 "meta": {3 "request_credit_cost": 5,4 "credits_remaining": 1455 }6}
You get credits as start credits, every month with a credit subscription, or once as top-up credits. Without a credit subscription, start credits and top-up credits are valid for 30 days; with an active subscription, they do not expire. Everything else is in Billing.
Current data and Realtime
By default, the company profile comes from our database. How current a piece of information is depends on its source.
Handelsregister
We keep basic data, people and register notices up to date in our database from the register. This is fast and enough for most purposes.
With Realtime (realtime_mode=handelsregister-default), the API fetches the Aktueller Abdruck (AD, current printout) live from the Handelsregister (commercial register) at the moment of your request and returns it as JSON. You also get the currently registered people in related_persons.current, without paying for the feature.
Whether the live fetch worked is shown in _realtime_mode.status. We charge the 10 credits for Realtime only on success.
curl -G "https://handelsregister.ai/api/v1/fetch-organization" \ -H "x-api-key: YOUR_API_KEY" \ --data-urlencode 'q=Hetzner Online GmbH' \ --data-urlencode 'realtime_mode=handelsregister-default'
import requests response = requests.get( "https://handelsregister.ai/api/v1/fetch-organization", headers={"x-api-key": "YOUR_API_KEY"}, params={ "q": "Hetzner Online GmbH", "realtime_mode": "handelsregister-default", }, ) data = response.json()
const url = new URL("https://handelsregister.ai/api/v1/fetch-organization"); url.searchParams.append("q", "Hetzner Online GmbH"); url.searchParams.append("realtime_mode", "handelsregister-default"); const response = await fetch(url, { headers: { "x-api-key": "YOUR_API_KEY" }, }); const data = await response.json();
1{2 "name": "Hetzner Online GmbH",3 "_realtime_mode": {4 "mode": "handelsregister-default",5 "status": "success"6 },7 "related_persons": {8 "current": [9 {10 "entity_id": "78ad32e16ff779f589a9e88d23356f74",11 "label": "MANAGING_DIRECTOR",12 "role": {13 "en": {14 "long": "Managing Director",15 "short": "MD"16 },17 "de": {18 "long": "Geschäftsführer",19 "short": "GF"20 }21 },22 "name": "Max Mustermann",23 "name_parts": {24 "given": "Max",25 "family": "Mustermann",26 "maiden": null,27 "canonical_name": "Mustermann, Max",28 "aliases": [29 "Mustermann, Max"30 ],31 "previous_names": null32 },33 "start_date": null,34 "end_date": null,35 "birth_date": "1976-01-15",36 "location": {37 "home": {38 "city": "Musterheim"39 }40 },41 "organization_representation_scheme": {42 "current": [43 "Ist nur ein Geschäftsführer bestellt, so vertritt er die Gesellschaft allein. Sind mehrere Geschäftsführer bestellt, so wird die Gesellschaft durch zwei Geschäftsführer oder durch einen Geschäftsführer gemeinsam mit einem Prokuristen vertreten."44 ],45 "history": []46 },47 "role_representation_scheme": {48 "current": [49 "einzelvertretungsberechtigt",50 "mit der Befugnis, im Namen der Gesellschaft mit sich im eigenen Namen oder als Vertreter eines Dritten Rechtsgeschäfte abzuschließen"51 ],52 "history": []53 }54 },55 {56 "entity_id": "73549375ff7d709b9e7e2941ad1ffaa3",57 "label": "MANAGING_DIRECTOR",58 "role": {59 "en": {60 "long": "Managing Director",61 "short": "MD"62 },63 "de": {64 "long": "Geschäftsführer",65 "short": "GF"66 }67 },68 "name": "Paul Musterwald",69 "name_parts": {70 "given": "Paul",71 "family": "Musterwald",72 "maiden": null,73 "canonical_name": "Musterwald, Paul",74 "aliases": [75 "Musterwald, Paul"76 ],77 "previous_names": null78 },79 "start_date": null,80 "end_date": null,81 "birth_date": "1989-07-18",82 "location": {83 "home": {84 "city": "Probebrück"85 }86 },87 "organization_representation_scheme": {88 "current": [89 "Ist nur ein Geschäftsführer bestellt, so vertritt er die Gesellschaft allein. Sind mehrere Geschäftsführer bestellt, so wird die Gesellschaft durch zwei Geschäftsführer oder durch einen Geschäftsführer gemeinsam mit einem Prokuristen vertreten."90 ],91 "history": []92 },93 "role_representation_scheme": {94 "current": [95 "einzelvertretungsberechtigt"96 ],97 "history": []98 }99 },100 {101 "entity_id": "cfecded2c1d17946c8ab0379aa786eed",102 "label": "MANAGING_DIRECTOR",103 "role": {104 "en": {105 "long": "Managing Director",106 "short": "MD"107 },108 "de": {109 "long": "Geschäftsführer",110 "short": "GF"111 }112 },113 "name": "Jan Musterhuber",114 "name_parts": {115 "given": "Jan",116 "family": "Musterhuber",117 "maiden": null,118 "canonical_name": "Musterhuber, Jan",119 "aliases": [120 "Musterhuber, Jan"121 ],122 "previous_names": null123 },124 "start_date": null,125 "end_date": null,126 "birth_date": "1955-11-06",127 "location": {128 "home": {129 "city": "Probeingen"130 }131 },132 "organization_representation_scheme": {133 "current": [134 "Ist nur ein Geschäftsführer bestellt, so vertritt er die Gesellschaft allein. Sind mehrere Geschäftsführer bestellt, so wird die Gesellschaft durch zwei Geschäftsführer oder durch einen Geschäftsführer gemeinsam mit einem Prokuristen vertreten."135 ],136 "history": []137 },138 "role_representation_scheme": {139 "current": [140 "einzelvertretungsberechtigt"141 ],142 "history": []143 }144 }145 ]146 },147 "meta": {148 "request_credit_cost": 15,149 "credits_remaining": 145150 }151}
If the live fetch fails, the API returns the stored data from our database. You can tell by _realtime_mode.status, which is then not success. Realtime is then not charged, as meta.request_credit_cost also shows.
Realtime is worth it when today’s state matters. For example, you check new business partners before signing, or see who may represent the company right now.
Annual financial statements
We look for newly published annual financial statements every day. Companies, however, have up to twelve months after the end of the financial year to publish them (§ 325 HGB), and many use the full deadline. Some companies deliberately miss the legal deadline and publish even later.
The latest statement therefore often covers the year before last. More in Freshness.
Insolvency notices
The insolvency courts usually publish their notices on the day of the decision or shortly after. You get them through the feature insolvency_publications, each with court, case number and date.
News
The feature news returns news about the company from the web, with title, source, date and link. How current it is depends on when the company was last reported on. For small companies, there are often only a few matching reports.
History and validity
Many details change over time. The API therefore returns the current state and the history side by side:
currentis the state as of today.historylists every registered state witheffective_fromandeffective_to. Ifeffective_toisnull, the state is still valid today.- People are in
related_persons.currentandrelated_persons.past, each withstart_dateandend_date.
Every detail with a history comes from the registers and publications, for example from the Chronologischer Abdruck (CD, chronological printout) of the Handelsregister or from all published annual financial statements.
This is how it looks in our example for the representation rules of Hetzner Online GmbH. In the example response, they name the management board until July 28, 2015, and the managing directors since then:
1{2 "representation_scheme": {3 "current": [4 "Ist nur ein Geschäftsführer bestellt, so vertritt er die Gesellschaft allein. Sind mehrere Geschäftsführer bestellt, so wird die Gesellschaft durch zwei Geschäftsführer oder durch einen Geschäftsführer gemeinsam mit einem Prokuristen vertreten."5 ],6 "history": [7 {8 "value": [9 "Ist nur ein Vorstandsmitglied bestellt, so vertritt es die Gesellschaft allein. Sind mehrere Vorstandsmitglieder bestellt, so wird die Gesellschaft durch zwei Vorstandsmitglieder oder durch ein Vorstandsmitglied gemeinsam mit einem Prokuristen vertreten."10 ],11 "effective_from": "2002-10-15",12 "effective_to": "2015-07-28"13 },14 {15 "value": [16 "Ist nur ein Geschäftsführer bestellt, so vertritt er die Gesellschaft allein. Sind mehrere Geschäftsführer bestellt, so wird die Gesellschaft durch zwei Geschäftsführer oder durch einen Geschäftsführer gemeinsam mit einem Prokuristen vertreten."17 ],18 "effective_from": "2015-07-28",19 "effective_to": null20 }21 ]22 }23}
Most dates come in the format YYYY-MM-DD. How far back the history goes is described in Age and history.
Empty values
Not every company has a value for every field. The API shows this in two ways:
null: there is no value for this field.[]: the list has no entries, for example no insolvency notices.
A requested feature without data comes as null or [] and costs nothing.
1{2 "name": "dm-drogerie markt GmbH + Co. KG",3 "legal_form": "GmbH & Co. KG",4 "contact_data": {5 "website": "https://www.dm.de",6 "phone_number": "+49 721 55920",7 "email": null8 },9 "capital": {10 "current": null,11 "history": []12 },13 "mergers_and_acquisitions": null,14 "insolvency_publications": []15}
In your code, treat a missing key, null and [] the same, because some empty objects come as []. Also read fields by their names, because the order of the keys is not fixed.
If a value is missing, the company usually does not have to publish it at all. What the law requires depending on legal form and size is described in Data availability. We deliberately withhold some details; they then carry redacted: true.
Stability and versions
The API grows additively. New data and features arrive as new fields. We never remove existing fields, we do not rename them, and we change neither their type nor their meaning. This keeps every version backward compatible.
Changes that would break existing code only come in a new API version, for example under /v2. The current version runs under /v1.
So let your client ignore unknown fields and treat unknown values as a general case. New fields and features are listed in the Changelog.
Plans
You can use Company profile, Documents, Search & Export and Signals with every account, even without a credit subscription. A credit subscription brings new credits every month and unlocks more data:
| What you get in addition | Plus | Pro | Max |
|---|---|---|---|
| Person profile: Roles and holdings of people | included | included | included |
| Search & Export: Filters for ownership, management & insolvency | not included | included | included |
| Company profile: Over 90 extended financial KPIs | not included | included | included |
| Company profile: Activity statements of energy utilities (section 6b EnWG) | not included | not included | included |
Company profile: Deep Shareholders (shareholders_deep) |
not included | not included | included |
Company network (network) |
not included | included | included |
| Signals: Insolvencies | not included | included | included |
| Signals: Transformations & M&A | not included | not included | included |
The API leaves out features outside your plan without an error and does not charge them. It rejects person profiles and search filters outside your plan with 403, also at no cost. For Signals, this applies to topics you request explicitly; without that, you simply get all topics of your plan.
You find the prices and credits of the plans on the pricing page.