1. Tjek formatet med modulus 11
Et CVR-nummer har 8 cifre og starter ikke med 0. Gang hvert ciffer med vægtene 2, 7, 6, 5, 4, 3, 2, 1, og læg resultaterne sammen. Summen skal gå op i 11.
Eksempel for 10403782: 1·2 + 0·7 + 4·6 + 0·5 + 3·4 + 7·3 + 8·2 + 2·1 = 77, og 77 / 11 = 7. Nummeret er altså gyldigt.
WEIGHTS = (2, 7, 6, 5, 4, 3, 2, 1)
def is_valid_cvr(cvr: str) -> bool:
cvr = cvr.replace(" ", "")
if len(cvr) != 8 or not cvr.isdigit() or cvr[0] == "0":
return False
return sum(int(d) * w for d, w in zip(cvr, WEIGHTS)) % 11 == 0
is_valid_cvr("10403782") # True (Vestas Wind Systems A/S)
is_valid_cvr("12345678") # False2. Bekræft at virksomheden findes
Et nummer kan have korrekt kontrolciffer uden at være tildelt. Slå det op:
curl https://apicvr.dk/api/v1/10403782{
"vat": 10403782,
"name": "VESTAS WIND SYSTEMS A/S",
"status": "NORMAL",
"startdate": "...",
"enddate": null,
"bankrupt": false,
"companydesc": "Aktieselskab",
...
}Findes nummeret ikke, svarer API'et med HTTP 404:
{"detail": {"error": "NOT_FOUND", "status": 404, "message": null}}3. Tjek at den er aktiv
En virksomhed kan findes i CVR, selvom den er ophørt eller gået konkurs. Kig på enddate (sat, når virksomheden er ophørt), bankrupt og status. Her er hele flowet i JavaScript:
const WEIGHTS = [2, 7, 6, 5, 4, 3, 2, 1];
function isValidCvr(input) {
const cvr = String(input).replace(/\s/g, "");
if (!/^[1-9]\d{7}$/.test(cvr)) return false;
const sum = [...cvr].reduce((acc, d, i) => acc + Number(d) * WEIGHTS[i], 0);
return sum % 11 === 0;
}
async function checkCvr(cvr) {
if (!isValidCvr(cvr)) return { valid: false, reason: "checksum" };
const res = await fetch(`https://apicvr.dk/api/v1/${cvr}`);
if (res.status === 404) return { valid: false, reason: "not_found" };
const company = await res.json();
const active = !company.enddate && !company.bankrupt;
return { valid: true, active, name: company.name };
}Gode råd
- Kør modulus 11-tjekket i browseren, så brugeren får besked med det samme – og spar API-kaldet på oplagte tastefejl.
- Fjern mellemrum og et evt.
DK-præfiks (fra momsnumre) før validering. - Brug
enddateogbankruptfrem for at matche på tekst istatus, som kan have mange forskellige værdier.
Ofte stillede spørgsmål
Er alle CVR-numre, der består modulus 11, tildelt?
Nej. Modulus 11 fanger tastefejl, men kun et opslag i CVR kan bekræfte, at nummeret tilhører en virksomhed.
Er CVR-nummer og momsnummer det samme?
For danske virksomheder er momsnummeret som regel CVR-nummeret med DK foran, fx DK10403782.
Hvad svarer API'et ved et ugyldigt format?
Indeholder nummeret andet end cifre, svarer API'et med HTTP 422. Findes nummeret ikke, svarer det med HTTP 404 og fejlkoden NOT_FOUND.