registercheckby openlaw group
Understand the data

Companies

What a company record contains, which fields are reliable, and where they come from.

Where a company record comes from

Two sources, and the difference matters:

  1. The register index — name, court, register number, legal form, status. Present for every company, refreshed as the register changes.
  2. The register extract — address, purpose, capital, representatives, founding date. Only present once the extract has been fetched and successfully parsed for that company.

A company with only source 1 is not an error. It is a company whose extract has not been retrieved. See Data coverage for how often that is the case.

The record

{
  "id": "cmp_63b6n0c6p09pnsrr6nrtd0dzsc",
  "object": "company",
  "name": "Enduro Reise & Training GmbH",
  "status": "active",
  "legal_form": "gmbh",
  "register": {
    "court": { "code": "D2505", "name": "Amtsgericht Memmingen" },
    "type": "HRB",
    "number": "13557",
    "formatted": "Amtsgericht Memmingen HRB 13557",
    "country": "DE"
  },
  "address": {
    "street": "In der Paint 14",
    "postal_code": "87730",
    "city": "Bad Grönenbach",
    "state": "DE-BY",
    "country": "DE",
    "formatted": "In der Paint 14, 87730 Bad Grönenbach",
    "coordinates": { "latitude": 47.87, "longitude": 10.25 }
  },
  "purpose": "Planung und Durchführung von Motorrad-Sicherheitstraining …",
  "capital": { "amount": "25000.00", "currency": "EUR" },
  "representation_rule": "Ist ein Geschäftsführer bestellt, so vertritt er allein.",
  "identifiers": { "euid": "DEM1401.HRB13557", "lei": null },
  "industries": [{ "system": "wz2025", "code": "85.53", "name": "Fahr- und Flugschulen", "level": 4 }],
  "registration_date": null,
  "founding_date": "2008-11-21",
  "termination_date": null,
  "last_register_entry_date": "2025-01-26",
  "counts": { "current_roles": 1, "documents": 4, "financial_statements": 15 }
}

The record is the register entry as it stands today. Roles, documents, statements, ownership and history are separate endpoints, which is why counts is here: it tells you whether calling one is worth a credit before you spend it.

register

The identity of the entry. formatted is the one-line form you would quote to a lawyer. court.name is given as the register writes it (Amtsgericht Berlin (Charlottenburg)), which is not always the court's colloquial name; court.code is the official court code, stable across spellings, and is what you should match on.

number is a string, here and everywhere else. A register number is an identifier, not a quantity — it can carry letter suffixes, and leading zeros are meaningful. GET /courts lists the court codes this API names, with the name the register uses. It is not every court the portal's form mapping includes.

name

The full legal name including the legal form. Former names are not in this object — they are in the register history, as company.name.changed events carrying what the entry replaced.

status

One of active, liquidation, terminated or unknown, always lowercase. One rule derives it for the company record, search results, suggestions and filter hits, so a company has the same status in all of them.

unknown means what it says: the register data does not tell us. It is not a synonym for inactive, and the field will never claim active for a company we cannot confirm is trading — for a KYC decision, a wrong active is the one answer you cannot absorb.

This was wrong in the old API

The retired /api derived this from a comparison that never matched, so nearly every company was reported active, including entries the register had deleted. v1 reads the stored value, and falls back to unknown rather than guessing.

A plain value to branch on — gmbh, gmbh_co_kg, ug, ev and so on. The German name, the usual abbreviation (GmbH) and the ISO 20275 ELF code, where one applies, are in GET /legal-forms: free, the same for every caller, so read it once and look the value up.

The register stores this as free text with more than 20,000 distinct spellings, so legal_form is null for the 7.6% of companies whose wording we cannot classify confidently. A null is "we could not read it", never "it has no legal form".

industries

WZ 2025 codes assigned from the registered business purpose. They are not register data. Each entry on a company is {system, code, name, level}. The classification itself — every code, its German title, its level and its parent — is GET /industries: free, the same for every caller.

address

The registered office as registered, which is the address for service — not necessarily a trading address. formatted is the single-line form, and state, when present, is the federal state as an ISO 3166-2 code (DE-BY). Any component may be null; city is by far the most commonly populated.

capital

Registered share capital (Stammkapital / Grundkapital), in the currency stated in the register. The amount is a decimal string so it never loses precision in a JSON parser that reads numbers as floats. Pre-2002 entries can still be denominated in DEM. This is the capital the register records, which is not the same as equity, and is never updated by trading.

registration_date and founding_date

Two dates, and they are not the same:

  • registration_date is the day of the company's first register entry. It is null while it cannot be read for a company; GET /formations carries it for every new registration.
  • founding_date is the date of the founding contract (the articles of association), as the register extract states it. It usually precedes registration_date by days or weeks.

Neither is wrong. Use registration_date when you mean "since when does the register know this company", and founding_date when you mean "when was it founded".

counts

How much related data exists: current roles, documents on file, financial statements. Counted from the record itself, so it costs nothing extra. A zero means there is nothing to fetch, which is worth checking before spending a credit on the sub-resource.

Roles are their own endpoint

Managing directors, board members and authorised signatories are one list at GET /companies/{company_id}/roles, because to a caller they are the same thing: a person or a company holding a role. Each role names its holder as a party, so a role held by a company reads like one held by a person. Narrow the list with role_type, or add expand=roles to the company request for the first page inline.

An empty list means "no extract parsed", not "nobody is in charge" — check whether address and purpose are also null before concluding anything.

On this page