CVR-opslag i din app på 10 minutter (Node, Python & C#)

Trin-for-trin CVR API-eksempel: få en API-nøgle, hent CVR-data med curl, og byg opslaget ind i Node.js, Python og C# — med fejlhåndtering.

Skal du bruge virksomhedsdata i din egen app — til kunde-onboarding, KYB-tjek eller fakturering — er et CVR-opslag via API den hurtigste vej. I denne guide sætter vi det op fra bunden: du får en API-nøgle, laver dit første opslag med curl og ender med færdige eksempler i Node.js, Python og C#. Realistisk tidsforbrug: ti minutter.

Trin 1: Få en API-nøgle

Opret en konto — det giver dig 14 dages gratis prøve på Basic-planen, uden kreditkort. Derefter opretter du en nøgle under Dashboard → API-nøgler. Nøglen har præfiks cvr_ og vises kun én gang, så gem den i din secrets-manager eller en .env-fil med det samme.

Nøglen sendes som Bearer-token i Authorization-headeren på alle kald til /api/v1. Behandl den som en adgangskode: den giver fuld adgang til din kvote, og kompromitterede nøgler bør tilbagekaldes fra dashboardet med det samme.

Trin 2: Første opslag med curl

Endpointet GET /api/v1/company/{cvr} returnerer fulde detaljer for én virksomhed ud fra det 8-cifrede CVR-nummer:

curl
curl -H "Authorization: Bearer cvr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://cvrlookup.dk/api/v1/company/43269070"

Svaret er JSON med en fast konvolut — her forkortet, og med eksempeldata i adressefelterne:

json
{
  "success": true,
  "data": {
    "cvr": "43269070",
    "companyName": "codepilots ApS",
    "status": "ACTIVE",
    "isActive": true,
    "companyType": {
      "code": 80,
      "shortDescription": "APS",
      "longDescription": "Anpartsselskab"
    },
    "address": {
      "street": "Kochsgade",
      "houseNumber": "31B",
      "postalCode": "5000",
      "city": "Odense C",
      "country": "Danmark",
      "fullAddress": "Kochsgade 31B, 5000 Odense C"
    },
    "industry": {
      "code": "622000",
      "description": "Computerkonsulentbistand og forvaltning af computerfaciliteter"
    },
    "foundedDate": "2022-05-17"
  }
}

Alle succes-svar har formen { "success": true, "data": { ... } }. Kender du ikke CVR-nummeret på forhånd, kan du søge på navn med GET /api/v1/search?name=codepilots — navnesøgninger tæller mod din månedlige kvote ligesom opslag.

Trin 3: Byg det ind i din app

Opslaget hører hjemme på serveren. Kald aldrig API’et direkte fra browseren eller en mobil-app: så ligger din API-nøgle i klientens kode, og alle kan bruge din kvote. Har du en frontend, så lav et lille endpoint i din egen backend, der laver opslaget og kun sender de felter videre, som klienten skal bruge — nøglen forlader aldrig serveren.

Vælg dit sprog herunder. Alle tre eksempler gør det samme: validér CVR-nummeret, slå op med Bearer-headeren, tjek success og håndtér de mest almindelige fejl. Hverken Node- eller C#-eksemplet kræver eksterne pakker.

javascript
// cvr.mjs — kræver Node 18+ (indbygget fetch)
// Kør: node --env-file=.env cvr.mjs  (Node 20+; brug dotenv på ældre versioner)
const API_BASE = "https://cvrlookup.dk/api/v1";
const API_KEY = process.env.CVRLOOKUP_API_KEY;

export async function hentCvrData(cvr) {
  if (!/^\d{8}$/.test(cvr)) {
    throw new Error("CVR-nummer skal være præcis 8 cifre");
  }

  const res = await fetch(`${API_BASE}/company/${cvr}`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
  const body = await res.json();

  if (!body.success) {
    const { code, message } = body.error;
    if (code === "COMPANY_NOT_FOUND") return null; // findes ikke
    throw new Error(`${code}: ${message}`);
  }
  return body.data;
}

const firma = await hentCvrData("43269070");
console.log(firma.companyName, "-", firma.address.fullAddress);

Hvilke data får du tilbage?

data-objektet fra et virksomhedsopslag indeholder alt det centrale fra CVR-registret. De vigtigste felter:

  • companyName, cvr og tradeNames — officielt navn og eventuelle binavne.
  • status / isActive — normaliseret status (ACTIVE, DISSOLVED, BANKRUPTCY m.fl.) plus et hurtigt boolean-flag.
  • companyType — selskabsform, fx ApS eller A/S.
  • address — adressefelter enkeltvis samt en færdigflettet fullAddress.
  • industry og secondaryIndustries — branchekode (NACE) og branchetekst.
  • owners, boardMembers og founders — reelle ejere med ejerandele, ledelse og stiftere. Nyttigt til KYB.
  • employeeInfo, shareCapital, foundedDate og contact — ansatte, selskabskapital, stiftelsesdato og kontaktoplysninger.

Felter kan være null eller udeladt, når CVR-registret ikke har data for dem — skriv din kode defensivt. Den fulde feltliste med typer står i dokumentationen, og hele API’et findes som OpenAPI 3.1-spec på /openapi.json, hvis du vil generere en klient.

Fejlhåndtering

Alle fejl returneres med samme JSON-skema:

json
{
  "success": false,
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Månedlig kvote overskredet. Opgradér din plan for flere opslag."
  }
}

Feltet code er stabilt og beregnet til logik — undgå at parse message. De koder, du oftest møder:

HTTPKodeHvad gør du?
400INVALID_CVRCVR-nummeret er ikke præcis 8 cifre. Validér input før du kalder.
401UNAUTHORIZED / INVALID_API_KEYManglende, ugyldig eller tilbagekaldt API-nøgle. Tjek Authorization-headeren.
404COMPANY_NOT_FOUNDIngen virksomhed med det CVR-nummer. Tæller ikke mod din månedlige kvote, men mod minutgrænsen.
429RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDEDMinutgrænsen eller den månedlige kvote er ramt. Vent, eller opgradér plan.

Autoriserede kald returnerer desuden headerne X-RateLimit-Limit, X-RateLimit-Remaining og X-RateLimit-Reset (Unix-tidsstempel for næste midnatsreset), så din kode kan bremse i god tid. To detaljer, der er værd at kende: samme CVR slået op flere gange samme dag tæller kun én gang mod kvoten, og GET /api/v1/usage viser dit aktuelle forbrug uden selv at koste noget.

Videre herfra

Det var hele integrationen: nøgle, ét endpoint, lidt fejlhåndtering. Den fulde API-dokumentation dækker også personopslag, navnesøgning med pagination og watchlists med webhooks. Kvoter og priser for Basic og Pro står på prissiden — og prøveperioden er som nævnt gratis i 14 dage, så du kan nå at bygge integrationen færdig, før du beslutter dig.