Two ways to get them
The full lookup /api/v1/{cvr} includes the direktion, fuldt_ansvarlige and ejere fields. If you only need the people, the slim endpoint is faster because it skips production units and company details:
curl https://apicvr.dk/api/v1/24256790/direktion-og-ansvarligExample response
{
"vat": 24256790,
"direktion": [
{
"name": "Karsten Munk Knudsen",
"role": "DIREKTØR",
"type": "PERSON",
"cvr": null,
"startdate": "2018-02-15",
...
}
],
"fuldt_ansvarlige": [],
"ejere": [
{
"name": "Novo Holdings A/S",
"type": "VIRKSOMHED",
"cvr": 24257630,
"country": "DK",
"ownership_percent": 0.25,
"ownership_range": "25-33,32%",
"voting_rights_percent": 0.6667,
"voting_rights_range": "66,67-89,99%",
"startdate": "2000-11-13"
}
]
}Reading the fields
| Field | Meaning |
|---|---|
direktion | Current executives (e.g. DIREKTØR or ADM. DIR.). |
fuldt_ansvarlige | Participants with personal liability, e.g. partners in an I/S. |
ejere | Legal owners from the ownership register, with share and voting rights. |
ownership_percent | Ownership as a decimal: 0.25 means 25%. |
ownership_range | The band CVR records the share in, e.g. 25-33,32%. |
type | PERSON, VIRKSOMHED (with cvr) or ANDEN_DELTAGER, e.g. a foreign owner. |
Walk the ownership chain
When an owner is a company, it has its own CVR number, so you can walk up one level at a time:
import requests
def owner_chain(cvr: int, depth: int = 0, max_depth: int = 5):
url = f"https://apicvr.dk/api/v1/{cvr}/direktion-og-ansvarlig"
data = requests.get(url, timeout=10).json()
for owner in data["ejere"]:
share = owner["ownership_percent"] or 0
print(" " * depth + f"{owner['name']} ({share:.0%})")
if owner["type"] == "VIRKSOMHED" and owner["cvr"] and depth < max_depth:
owner_chain(owner["cvr"], depth + 1, max_depth)
owner_chain(24256790)Good to know
- Only owners with at least 5% of the capital or votes must be registered as legal owners. The list can be empty for listed companies with dispersed ownership.
- Shares are recorded in bands. Use
ownership_rangewhen showing the share to users. - The response only contains current roles – former executives and owners are filtered out.
- Names of people are personal data. Only use them for purposes you have a lawful basis for.
Frequently asked questions
Do I also get the beneficial owners?
The API returns the legal owners from CVR. Beneficial owners (UBOs) are registered separately and aren't part of the response.
Why is ownership_percent 0.25 and not 25?
The share is a decimal between 0 and 1. Multiply by 100 to get a percentage.
What's the difference between management and fully liable participants?
Management runs the company. Fully liable participants are personally liable for its debts, such as partners in an I/S or general partners in a K/S.