# 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.

## 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](https://cvrradar.dk/dashboard). Døgnkvoten tælles samlet for alle dine nøgler.

```http
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

| Pakke      | Pris               | Opslag                     | Indhold                                                                                                                            |
| ---------- | ------------------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Uden nøgle | Gratis             | 50 i døgnet pr. IP-adresse | Stamdata                                                                                                                           |
| Gratis     | 0 kr.              | 1.000 i døgnet pr. konto   | Stamdata, søgning, domæner, personer og roller, nye virksomheder. Plus 100 berigede smagsprøver om måneden                         |
| Start      | 99 kr. om måneden  | 50.000 om måneden          | Alt i Gratis plus regnskab, kreditvurdering, ejergraf, digital profil, historik, benchmark, sammenligning, overvågning og SEO-data |
| Pro        | 399 kr. om måneden | 500.000 om måneden         | Det samme som Start til systemer, der slår mange virksomheder op                                                                   |
| Fuld               | 1.999 kr. om måneden       | 500.000 om måneden                                                                                                                 | Alt 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](https://cvrradar.dk/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:

| Header               | Betydning                                     |
| -------------------- | --------------------------------------------- |
| `X-Kvote-Graense`    | Antal opslag i perioden                       |
| `X-Kvote-Resterende` | Opslag tilbage i perioden                     |
| `X-Kvote-Nulstilles` | Tidspunkt (ISO 8601), hvor kvoten nulstilles  |
| `Retry-After`        | Kun 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.

```js 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.

```bash 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"]}'
```
```js 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 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 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()
```
