# Godkendelse og nøgler

Alle data-endpoints kræver en API-nøgle i `Authorization`-headeren (eller som `?token=`, hvor en header ikke kan sættes). Der findes to slags: `gf_live_` til produktion og `gf_test_` til udvikling og CI.

## Send nøglen som Bearer-token

```http
GET /v1/bbr/ejendom/5651067 HTTP/1.1
Host: api.grundfast.dk
Authorization: Bearer gf_live_...
```

Headeren er den form, du skal bruge, når du kan. Den gælder alle data-endpoints og [MCP-serveren](https://grundfast.dk/docs/mcp).

## Nøglen som ?token= — når du ikke kan sætte en header

Nogle systemer kan kun tage en URL: GIS-programmer, regnearks-webforespørgsler, en `<img>`- eller kortflise-URL og visse low-code-forbindelser. Til dem accepterer data-endpoints under `/v1/*` og `/mcp` nøglen som query-parameteret `token`:

```http
GET /v1/adgangsadresser?postnr=8000&token=gf_live_... HTTP/1.1
Host: api.grundfast.dk
```

- Kaldet måles, begrænses og faktureres præcis som med headeren — det er den samme nøgle.
- Sender du både header og `token`, gælder headeren.
- Dashboardet og konto-endpoints (nøgler, betaling, eksport, `/v1/me`) tager aldrig `token` — dér gælder kun din session eller headeren.

> **Brug headeren, hvor du kan** En URL havner steder, en header ikke gør: i proxy- og serverlogs undervejs, i browserhistorik og i links, der deles. Vi logger aldrig query-strenge, og vores svar bærer `Referrer-Policy: no-referrer`, men mellemled, du ikke kontrollerer, kan gemme URL’en. Giv en `token`-URL sin egen nøgle, så du kan tilbagekalde netop den, hvis den slipper ud.

## Live- og testnøgler

|  | `gf_live_` | `gf_test_` |
| --- | --- | --- |
| Data | De rigtige registre | De samme rigtige registre |
| Fakturering | Tæller mod planens kvote; overforbrug faktureres på betalte planer | Faktureres aldrig og tæller ikke mod planens forbrug |
| Månedligt loft | Planens kvote (se [Rate limits](https://grundfast.dk/docs/rate-limits)) | 25.000 kald pr. måned, uanset plan |
| Burst pr. minut | Planens burst-grænse | Samme burst-grænse som planen |
| Header på svaret | `X-Grundfast-Environment: live` | `X-Grundfast-Environment: test` |

Brug en testnøgle i CI, staging og under udvikling. Ved sandbox-loftet svarer API’et `429` med beskeden, at du skal bruge en live-nøgle i produktion; `X-Quota-*`-headerne viser sandbox-loftet og nulstilles den 1. i måneden (UTC).

## Opret en nøgle

1. Log ind i [dashboardet](https://grundfast.dk/dashboard?mode=register) (opret en gratis konto, hvis du ikke har en).
2. Gå til Nøgler, giv nøglen et navn og vælg live eller test.
3. Kopiér nøglen med det samme. Den vises **kun én gang** — vi gemmer kun en hash af den og kan ikke vise den igen.

Nøgler oprettes og tilbagekaldes med din dashboard-session; en API-nøgle kan ikke oprette flere nøgler. Oprettelse af en live-nøgle kan kræve, at din e-mailadresse er bekræftet. Testnøgler kan altid oprettes.

Nøgler fra dashboardet har rettigheden `read_only`. Alle data-endpoints er læsninger, så den dækker hele API’et.

## Tilbagekald en nøgle

Tilbagekald én nøgle ad gangen under Nøgler i dashboardet, eller brug **Tilbagekald alle nøgler**, hvis du har mistanke om, at en nøgle er lækket. En tilbagekaldt nøgle afvises med `401`; ændringen slår igennem inden for få sekunder.

Har du abonneret på [webhooks](https://grundfast.dk/docs/webhooks), udsendes `key.created` og `key.revoked`, når nøgler oprettes og tilbagekaldes.

## Hold nøglen på serveren

> **Aldrig i browserkode** En nøgle i frontend-kode, en mobilapp eller et offentligt repository kan læses af alle. Kald Grundfast fra din egen backend og send kun resultatet videre til klienten. Læg nøglen i en miljøvariabel eller en secret manager.

Et typisk mønster er et lille endpoint i din egen backend, der slår op hos Grundfast og returnerer netop de felter, din frontend skal bruge. Så styrer du samtidig, hvor mange kald brugerne kan udløse.

## 401 og 403

| Status | Betydning | Hvad du gør |
| --- | --- | --- |
| 401 | Nøglen mangler, er ugyldig, udløbet eller tilbagekaldt. Svaret bærer en `WWW-Authenticate`-header, der beskriver det forventede format. | Tjek at headeren er `Authorization: Bearer gf_...` uden ekstra mellemrum eller anførselstegn. |
| 403 | Kontoen er suspenderet, eller nøglen er en administrationsnøgle, som ikke gælder for data-endpoints. | Kontakt support via dashboardet. |
| 429 | For mange forsøg med ugyldige nøgler fra samme IP-adresse. Svaret bærer `Retry-After`. | Ret nøglen og vent det angivne antal sekunder. |

Fejl, der skyldes din plan frem for din nøgle, er `402` (funktionen kræver en højere plan) og `429` (kvote eller burst-grænse). Se [Fejl og statuskoder](https://grundfast.dk/docs/fejl).

## Endpoints uden nøgle

Nogle endpoints kan kaldes uden nøgle. De er begrænset pr. IP-adresse og faktureres ikke:

- `/v1/demo/*` — faste eksempler i samme form som de rigtige endpoints, fx `/v1/demo/ejendom`.
- `/v1/kodeliste/:navn` — BBR-kodelisterne (se [BBR](https://grundfast.dk/docs/bbr)).
- `/v1/dagi` — oversigten over DAGI-temaer.
- `/v1/stats/kommuner` — adresse- og jordstykketal pr. kommune.
- `/openapi.json` — OpenAPI 3.1-specifikationen for hele API’et.

- Åbne endpoints: se https://grundfast.dk/docs/api
