cvrradar
Menu i dokumentationen

Kom i gang

Godkendelse og kvoter

Sådan sender du nøglen, hvad der tæller som et opslag, pakkernes kvoter, og hvad du gør, når API'et svarer 429.

På denne side

Nøglen

Alle kald sendes med headeren Authorization: Bearer cvr_…. En nøgle hører til din konto, og du kan have flere (fx én pr. system), rotere dem og slette dem i dashboardet. Døgnkvoten tælles samlet for alle dine nøgler.

GET /v1/virksomhed/10203040 HTTP/1.1
Host: cvrradar.dk
Authorization: Bearer cvr_DIN_NOEGLE

Mangler nøglen, eller er den forkert, svarer API'et 401.

Pakker

PakkePrisOpslagIndhold
Uden nøgleGratis50 i døgnet pr. IP-adresseStamdata
Gratis0 kr.1.000 i døgnet pr. kontoStamdata, søgning, domæner, personer og roller, nye virksomheder. Plus 100 berigede smagsprøver om måneden
Start99 kr. om måneden50.000 om månedenAlt i Gratis plus regnskab, kreditvurdering, ejergraf, digital profil, historik, benchmark, sammenligning, overvågning og SEO-data
Pro399 kr. om måneden500.000 om månedenDet samme som Start til systemer, der slår mange virksomheder op
Fuld1.999 kr. om måneden500.000 om månedenAlt i Pro plus fuld rapport om enhver virksomhed (op til 200 forskellige om dagen) og overvågning af op til 5.000 virksomheder

Priserne er ekskl. moms. Du betaler med kort, får en dansk faktura med CVR og moms, og der er ingen binding. Se også priser.

Smagsprøver

Den gratis nøgle kan hente regnskab, kreditvurdering, ejergraf og digital profil 100 gange om måneden. Det er nok til at bygge og teste en integration, før du vælger en pakke. Når smagsprøverne er brugt, svarer de berigede endpoints 402 til næste måned.

Hvad tæller som et opslag

  • Ét kald er ét opslag, uanset hvor mange felter svaret har.
  • POST /v1/virksomheder tæller ét opslag pr. unikt CVR-nummer i kaldet (højst 500).
  • Kald, der fejler med 400 (ugyldigt input), 401 eller 402, tæller ikke.
  • GET /v1/openapi.json tæller ikke og kræver ingen nøgle.

Den gratis kvote nulstilles ved midnat dansk tid. Månedskvoterne nulstilles den første i måneden.

Headere med forbrug

Hvert svar fortæller, hvor meget du har tilbage:

HeaderBetydning
X-Kvote-GraenseAntal opslag i perioden
X-Kvote-ResterendeOpslag tilbage i perioden
X-Kvote-NulstillesTidspunkt (ISO 8601), hvor kvoten nulstilles
Retry-AfterKun ved 429: sekunder, til du må prøve igen

Når kvoten er brugt: 429

Er kvoten brugt, svarer API'et 429 Too Many Requests med en forklaring og headeren Retry-After:

json
{
  "fejl": "Dagens kvote på 1.000 opslag er brugt. Den nulstilles ved midnat. Se priser på https://cvrradar.dk/priser.",
  "kvote": { "graense": 1000, "brugt": 1000, "nulstilles": "2026-11-14T00:00:00+01:00" }
}

Der er også en grænse for kald i minuttet (120 på Gratis, 600 på Start og 1.800 på Pro), som også giver 429. Sådan håndterer du det:

  1. Læs Retry-After, og vent mindst så mange sekunder.
  2. Prøv igen med eksponentiel backoff (fx 1, 2, 4 og 8 sekunder plus lidt tilfældighed).
  3. Gem svarene i din egen cache. Stamdata ændrer sig sjældent, og CVR synkroniseres én gang i døgnet.
JavaScript
async function hentMedVent(url, noegle, forsoeg = 4) {
  for (let i = 0; i < forsoeg; i++) {
    const svar = await fetch(url, { headers: { Authorization: `Bearer ${noegle}` } });
    if (svar.status !== 429) return svar;
    const vent = Number(svar.headers.get('Retry-After') ?? 2 ** i);
    await new Promise((r) => setTimeout(r, (vent + Math.random()) * 1000));
  }
  throw new Error('cvrradar: kvoten er stadig brugt');
}

Mange opslag på én gang

Skal du berige en kundeliste, så brug POST /v1/virksomheder med op til 500 CVR-numre pr. kald i stedet for 500 enkeltkald. Det er hurtigere for dig og belaster grænsen for kald i minuttet mindre.

curl
curl -X POST "https://cvrradar.dk/v1/virksomheder" \
  -H "Authorization: Bearer cvr_DIN_NOEGLE" \
  -H "Content-Type: application/json" \
  -d '{"cvr": ["10203040", "20304050", "30405060"]}'
JavaScript
const svar = await fetch("https://cvrradar.dk/v1/virksomheder", {
  method: "POST",
  headers: {
    Authorization: "Bearer cvr_DIN_NOEGLE",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"cvr": ["10203040", "20304050", "30405060"]}),
});
if (!svar.ok) throw new Error(`cvrradar svarede ${svar.status}`);
const data = await svar.json();
PHP
$ch = curl_init("https://cvrradar.dk/v1/virksomheder");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => '{"cvr": ["10203040", "20304050", "30405060"]}',
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer cvr_DIN_NOEGLE",
        "Content-Type: application/json",
    ],
]);
$data = json_decode(curl_exec($ch), true);
Python
import requests

svar = requests.post(
    "https://cvrradar.dk/v1/virksomheder",
    headers={"Authorization": "Bearer cvr_DIN_NOEGLE"},
    json={"cvr": ["10203040", "20304050", "30405060"]},
    timeout=10,
)
svar.raise_for_status()
data = svar.json()

Er noget forkert eller uklart? Skriv til mig.