# Fejl 401: manglende eller ugyldig API-nøgle

> Find årsagen til 401 missing_api_key og invalid_api_key med en tjekliste og et lille diagnosescript, og ret nøglen eller den måde, du sender den på.
>
> https://danadresse.dk/guides/fejl-401 · verified 2026-11-02
Status 401 betyder, at API'et ikke ved, hvem du er. Enten kom der ingen nøgle med (`missing_api_key`), eller også genkendes nøglen ikke (`invalid_api_key`). Alle kald kræver en nøgle, også de DAWA-kompatible, så det er den fejl, man oftest møder lige efter et skift fra DAWA.

## Hvad du ser

På DAWA-stierne (`/adresser`, `/autocomplete` osv.):

```json id=missing-dawa run=no
{
  "type": "UnauthorizedError",
  "title": "This API requires an X-Api-Key header. Get a free key in 30 seconds at https://danadresse.dk/dashboard/signup — then add 'X-Api-Key: <your key>' to every request.",
  "details": null,
  "code": "missing_api_key"
}
```

```json id=invalid-dawa run=no
{
  "type": "UnauthorizedError",
  "title": "The provided API key is invalid or revoked.",
  "details": null,
  "code": "invalid_api_key"
}
```

På `/api/v1` står den samme kode i `error.code`. Se [Fejlformatet](/guides/fejlformat).

## Kør diagnosescriptet først

Scriptet tjekker de typiske fejl i selve nøglen og laver derefter ét kald:

```python id=diagnose-401 run=live expect="200"
import os
import re

import requests

raw = os.environ.get("DANADRESSE_API_KEY")
if raw is None:
    raise SystemExit("DANADRESSE_API_KEY er ikke sat i dette miljø")
key = raw.strip().strip('"').strip("'")
if key != raw:
    print("Advarsel: nøglen havde mellemrum, linjeskift eller anførselstegn omkring sig")
if not re.fullmatch(r"dawa_(live|test)_[0-9a-f]{64}", key):
    print(f"Advarsel: nøglen har ikke det forventede format (længde {len(key)})")

r = requests.get(
    "https://api.danadresse.dk/postnumre/8000",
    headers={"X-Api-Key": key},
    timeout=10,
)
try:
    code = r.json().get("code")
except ValueError:
    code = None
print(r.status_code, code or "OK")
```

Får du `200 OK`, er nøglen i orden, og fejlen ligger i den måde, din applikation sender den på. Gå tjeklisten igennem.

## missing_api_key: nøglen kom ikke frem

**Headeren har et forkert navn.**

- Årsag: Nøglen er sendt som `Authorization: Bearer …`, `Api-Key`, `apikey` eller i JSON-body. API'et læser kun headeren `X-Api-Key` og query-parameteren `api_key`. Kun MCP-serveren på `/mcp` tager også `Authorization: Bearer <nøgle>`.
- Løsning: Brug `X-Api-Key: <nøgle>`. Store og små bogstaver i header-navnet er ligegyldige.

**Miljøvariablen er tom i det miljø, der kører koden.**

- Årsag: Nøglen er sat i din terminal, men ikke i systemd, Docker, cron, CI eller hosting-panelet. Headeren bliver sendt som `X-Api-Key: ` uden værdi, og en tom header tæller som manglende.
- Løsning: Log længden af nøglen (aldrig selve nøglen) ved opstart, og stop programmet, hvis den er 0.

**En proxy eller et framework fjerner headeren.**

- Årsag: Nogle reverse proxies, API-gateways og serverless-platforme sender kun kendte headere videre.
- Løsning: Test med curl direkte mod `https://api.danadresse.dk` fra samme maskine. Virker det, så tillad `X-Api-Key` i proxyen, eller send nøglen som `api_key` i URL'en.

**Kaldet går til `http://`.**

- Årsag: `http://api.danadresse.dk` svarer med en omdirigering (301) til `https://`. curl uden `-L` viser bare en HTML-side, og nogle HTTP-klienter taber headere eller body, når de følger en omdirigering.
- Løsning: Brug altid `https://`.

**Nøglen står kun i widget-konfigurationen et sted, der ikke bliver brugt.**

- Årsag: DAWA's gamle widget læser nøglen fra script-URL'en (`?key=…`), fra `data-api-key` på script-tagget eller fra optionerne `apiKey` og `params.api_key`. Står den andre steder, sender widgetten ingen nøgle.
- Løsning: Se [Fra dawa-autocomplete2](/guides/migrer-dawa-autocomplete2).

## invalid_api_key: nøglen blev ikke genkendt

**Nøglen er skrevet forkert eller afkortet.**

- Årsag: Kopieret uden de sidste tegn, eller med et ekstra tegn. En nøgle er `dawa_live_` eller `dawa_test_` efterfulgt af 64 tegn med 0-9 og a-f.
- Løsning: Kør diagnosescriptet. Passer formatet ikke, så lav en ny nøgle under [Nøgler](/dashboard/keys). Nøglen vises kun én gang, så den kan ikke hentes frem igen.

**Anførselstegn eller linjeskift i nøglen.**

- Årsag: `.env`-filer med `KEY="…"` læst af et værktøj, der ikke fjerner anførselstegnene, eller en nøgle med linjeskift fra en fil. Mellemrum omkring en nøgle i headeren bliver fjernet. I `api_key=` i URL'en bliver de ikke.
- Løsning: Fjern anførselstegn og whitespace, når du læser nøglen.

**Nøglen er slettet eller roteret.**

- Årsag: Nogen har slettet nøglen i dashboardet, eller den er skiftet ud, og den gamle står stadig i et miljø.
- Løsning: Se under [Nøgler](/dashboard/keys), hvilke nøgler der er aktive (de sidste fire tegn vises), og opdater konfigurationen.

**Både header og URL har en nøgle.**

- Årsag: Headeren vinder. En gammel nøgle i headeren giver `invalid_api_key`, selv om URL'en har den nye.
- Løsning: Send kun én af dem.

**Nøglen fra et andet produkt.**

- Årsag: En Datafordeler-nøgle eller en nøgle fra en anden tjeneste i den samme variabel.
- Løsning: Brug en nøgle fra [danadresse.dk/dashboard/keys](/dashboard/keys).

## 401 på dashboard-API'et

Endpoints som `/api/v1/keys` og `/api/v1/webhooks` bruger en login-token (JWT) i `Authorization: Bearer …`, ikke en API-nøgle. Uden token får du `error.code` `unauthorized`. Med en udløbet eller forkert token får du `invalid_token`. Hent en ny token med `POST /api/v1/auth/login`.

## Næste skridt

- [Header eller api_key i URL'en](/guides/api-noegle-header-eller-query)
- [Fejl 403: adgang nægtet](/guides/fejl-403), hvis nøglen bliver genkendt, men afvist.
- [Testnøgler og sandbox](/guides/testnoegler-sandbox)
