registercheckby openlaw group
Understand the data

Ownership

Shareholders, shareholdings and what the register can and cannot tell you.

What the register holds

Germany has no public register of beneficial ownership you can simply read. Ownership comes from the shareholder list (Gesellschafterliste), which a GmbH must file whenever its shareholders change.

This has three consequences you must design around:

  1. It is a document, not a field. The list is a PDF. What the API returns is what was extracted from it.
  2. It is only as fresh as the last filing. A company whose shareholders last changed in 2014 has a 2014 list, and that is correct.
  3. Not every legal form has one. An AG files no shareholder list; a sole trader (e.K.) has no shareholders. An empty response is frequently the right answer.

Reading ownership

GET /companies/{company_id}/shareholders returns who holds an interest in the company: shareholders, and for partnerships the general and limited partners. Each one is a shareholding:

{
  "object": "page",
  "data": [
    {
      "object": "shareholding",
      "id": "shr_01h455vb4pex5vsknk084sn02q",
      "company": { "object": "company", "id": "cmp_01h455vb4pex5vsknk084sn02r", "name": "Beispiel Analytics GmbH" },
      "holder": { "object": "company", "id": "cmp_01h455vb4pex5vsknk084sn02s", "name": "Beispiel Beteiligungs GmbH" },
      "type": "shareholder",
      "percentage": 40,
      "nominal_amount": { "amount": "10000.00", "currency": "EUR" },
      "liability_amount": null,
      "match_confidence": 1,
      "source": { "object": "document", "id": "doc_01h455vb4pex5vsknk084sn02t", "date": "2025-06-03", "type": "shareholder_list" }
    }
  ],
  "next_cursor": null,
  "extract": { "status": "parsed", "fetched_at": "2025-06-10T08:12:44Z", "document_id": "doc_01h455vb4pex5vsknk084sn02t" }
}

type says what the interest is: shareholder, general_partner (Komplementär) or limited_partner (Kommanditist). source is the filing it was read from, and source.date is the date of that filing. Always show it. A percentage without its as-of date is a claim you cannot support.

holder is a party: object says whether the holder is a company or a person, and id leads to its record. id is null when the register names a holder we could not match to a record, such as a company registered abroad; name is then the name as filed.

Holders that are companies

Where a holder is itself a company, GET /companies/{company_id}/ownership-tree follows linked companies for the depth you ask, from 1 to 3. Each node is a shareholding with its depth, its effective_percentage of the company you asked about (the product of the percentages along the path), and via_shareholding_id, the holding one level down.

The chain stops, and says why, when it reaches a company we have not linked (foreign_entity when that company is registered abroad, entity_not_linked when the country is Germany or not stated), an AG, SE or KGaA (stock_corporation; those forms file no shareholder list — a partnership worded "AG & Co. KG", "AG & Co. OHG", "AG & Co. Kommanditgesellschaft" or "SE & Co. Offene Handelsgesellschaft" is not one of them), a company whose list is not stored yet (no_shareholder_list or extraction_pending), a percentage that cannot be published (percentage_withheld), the depth you asked for (depth_limit), a cycle (cycle) or a company that holds itself (self_holding). Those holdings are listed in unresolved, once per reason when the same holding is reached by several paths. complete is true only when that list is empty, the walk was not cut short, and list_reason is null. truncated is true when depth or the cap of 250 nodes stopped it.

At depth 1, effective_percentage is the holding's own percentage. Further down it is the product of the percentages along the path, rounded half up to four decimal places.

An empty nodes does not by itself say whether no shareholder list is on file or whether it is not extracted yet. list_reason is no_shareholder_list or extraction_pending when that list is missing or still being read, including when partners are listed, and complete is false. The shareholder list still says which (extract.status).

Asking starts at most one shareholder extraction, for the company you asked about. Companies further up are read from ownership already on file. A person with a Sperrung is left out at every level. The call costs 10 credits whatever depth you ask. The percentages are computed from filed shareholder lists. They are not an extract from the Transparenzregister and not a determination under § 3 GwG.

Computed beneficial owners

GET /companies/{company_id}/beneficial-owners is a separate read. It follows the same filings for five levels and lists each natural person the computation qualifies. A company is never a beneficial owner. Each person carries percentage, gwg_above_25, amlr_at_least_25, basis and paths: the shareholdings from this company out to that person, and the percentage multiplied along each path.

Two holdings are the same person when exactly one person record is linked (matched_by is person_id), or, failing that, when both give the same full name and the same birth date (matched_by is name_birth_date). Otherwise the holding stays on its own (matched_by is unidentified), and its direct and indirect stakes are not combined with another row. unresolved includes unlinked_person when that unidentified person's largest possible stake is still at least 25% of the capital, or their control stake is 25% or more, or when the row has the same name as an identified holder and the two stakes together could reach that line. Those rows are not combined into one person. A smaller unidentified stake, which could not reach the line even together with such a holder, does not make the status partial.

gwg_above_25 is the GwG capital test: the paths sum to more than 25%. amlr_at_least_25 is the AMLR test: the paths sum to 25% or more. Exactly 25% sets the AMLR flag and not the GwG flag. basis repeats those tests and adds control:

ValueMeaning
capital_over_25The paths sum to more than 25% of the capital. Same test as gwg_above_25.
control_chainThe person's own stake in this company, plus the stakes of companies they control, is more than 25%. Control of another company is a majority, more than half, and stakes of several controlled companies in one company are added.
amlr_25_or_moreThe paths sum to 25% or more. Same test as amlr_at_least_25. It does not by itself clear the fictitious rule.

status is complete, partial or none_found. unresolved always includes voting_rights_unknown, because a shareholder list does not state votes; that reason alone does not make the status partial. Other reasons do: a missing percentage, a holder withheld by a Sperrung (withheld_person), an unidentified person who could still reach 25% (unlinked_person), a holder abroad or not linked, an AG, SE or KGaA, no shareholder list, a list still being read, a partnership whose figure is only a Haftsumme proxy, the five-level limit, the cap of 250 nodes, a cycle, or a company that holds itself.

fictitious_rule_applies follows the GwG test. It is true when the look is complete and nobody has capital_over_25 or control_chain, including when the only qualification is the AMLR test. It is false when the status is partial, so a withheld person is not reported as nobody. The managing directors are not copied into beneficial_owners; they stay on GET /companies/{company_id}/roles.

notice is the same sentence on every answer: computed from register filings (shareholder lists and register entries); may be incomplete. It is not an extract from the Transparenzregister, not the beneficial owners reported under §§ 19–20 GwG, and no substitute for the due diligence a Verpflichteter must do. In German: rechnerisch aus Gesellschafterlisten und Registereinträgen ermittelt; kann unvollständig sein. Kein Auszug aus dem Transparenzregister, nicht die nach §§ 19–20 GwG gemeldeten wirtschaftlich Berechtigten und kein Ersatz für die eigenen Sorgfaltspflichten eines Verpflichteten. A person with a Sperrung is left out. The call costs 25 credits.

The reverse direction — GET /companies/{company_id}/holdings and GET /persons/{person_id}/holdings — returns the shareholdings a company or a person holds in other companies. They are the same shareholding objects, seen from the holder's side.

German group structures contain cycles, including a company that holds itself. The tree flags the holding that would close one and does not follow it. If you walk the chain yourself, cap the depth and keep a visited set per path, so a company reached two ways is counted twice.

When we hold no list yet

Asking for shareholders starts the work by itself. If we hold no shareholder list for this company, the page says extract.status: "processing" with no holders, and the same request a little later returns them. One call starts at most one extraction, for the company you asked about.

That is why extract matters more than an empty data array:

extract.statusMeaning
parsedWhat you see is what is on file, as of fetched_at.
processingA list is being read now. Ask again in a few minutes.
not_filedNo list exists to read. The empty page is the answer.
not_fetchedWe have not fetched the list from the register.
failedWe fetched the list and could not read it.

Re-reading the history of past lists is planned (see the roadmap). Either way, a rebuild re-reads filed documents; it cannot invent a list that was never filed.

What you cannot get

  • The Transparenzregister, or an official determination. Neither is in this API. The ownership tree's effective percentages, and GET /companies/{company_id}/beneficial-owners, are computed from filed shareholder lists and register entries. They may be incomplete.
  • Share transfers between filings. Only the filed snapshots exist.
  • Shareholdings in an AG. Not filed, therefore not available.

On this page