# Fejl 403: adgang nægtet

> Find ud af, hvorfor en gyldig nøgle bliver afvist, ud fra koden i 403-svaret, og ret domæner, nøgletype, IP-liste eller en spærret nøgle.
>
> https://danadresse.dk/guides/fejl-403 · verified 2026-11-02
Status 403 betyder, at API'et kender din nøgle, men ikke vil udføre netop dette kald med den. Der er flere grunde, og koden i svaret fortæller hvilken. Find koden, og gå direkte til det afsnit, der passer.

| `code` | Kort sagt |
|---|---|
| `origin_not_allowed` | Browsernøgle brugt fra et domæne, der ikke er på listen, eller fra en server |
| `browser_key_scope` | Browsernøgle brugt på et endpoint, den ikke må kalde |
| `sandbox_scope` | Testnøgle brugt på et endpoint, den ikke må kalde |
| `key_blocked` | Nøglen er spærret, fordi den ser lækket ud |
| `ip_not_allowed` | IP-låst nøgle brugt fra en anden IP-adresse |
| `account_suspended` | Kontoen er spærret |
| `forbidden` | Din IP er blokeret af misbrugsfilteret |

På DAWA-stierne står koden i `code`, og `type` er `ForbiddenError`. På `/api/v1` står den i `error.code`. Se [Fejlformatet](/guides/fejlformat).

Dette script viser status, kode og besked for et kald med din nøgle, og om nøglen er markeret som mulig lækket:

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

import requests

r = requests.get(
    "https://api.danadresse.dk/postnumre/8000",
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
try:
    body = r.json()
except ValueError:
    body = {}
err = body.get("error") if isinstance(body.get("error"), dict) else body
print(r.status_code, err.get("code") or "OK", err.get("title") or err.get("message") or "")
status = r.headers.get("X-Danadresse-Key-Status")
if status:
    print("Nøglestatus:", status)
```

## origin_not_allowed

```json id=origin-body run=no
{
  "type": "ForbiddenError",
  "title": "This API key is locked to shop.firma.dk, *.firma.dk and this request came from firma.dk. Add the domain under API-nøgler → Tilladte domæner, or use a server-side key.",
  "details": null,
  "code": "origin_not_allowed"
}
```

Nøglen har *Tilladte domæner*, og værten i kaldets `Origin`-header (eller `Referer`, hvis `Origin` mangler) står ikke på listen. Beskeden viser både listen og den vært, der blev set.

**Kaldet kommer fra din server.**

- Årsag: En server sender hverken `Origin` eller `Referer`, så beskeden siger `came from no Origin/Referer`. En domænelåst nøgle virker kun fra en browser.
- Løsning: Lav en separat nøgle uden domæner til serveren.

**Domænet mangler en variant.**

- Årsag: Listen har `www.firma.dk`, men siden kører på `firma.dk`, eller omvendt. `*.firma.dk` dækker kun underdomæner, ikke `firma.dk` selv.
- Løsning: Tilføj begge, fx `firma.dk` og `*.firma.dk`. Porten er ligegyldig, kun værtsnavnet tæller.

**Udvikling på din egen maskine.**

- Årsag: `localhost` er ikke tilladt af sig selv.
- Løsning: Tilføj `localhost` på listen, eller brug en testnøgle til udvikling.

**Siden sender ingen Origin eller Referer.**

- Årsag: Sider åbnet som `file://`, sandboxede iframes (Origin `null`) og `<script>`-tags på sider med `Referrer-Policy: no-referrer` giver ingen vært at sammenligne med.
- Løsning: Kør siden fra en rigtig webadresse, og brug `strict-origin-when-cross-origin` eller lempeligere som Referrer-Policy.

Domæner sætter du under [Nøgler](/dashboard/keys). Se [Browsernøgler og tilladte domæner](/guides/browser-noegler-domaener).

## browser_key_scope

- Årsag: En domænelåst nøgle må kun lave adresseopslag. `/api/v1/enrich/…`, `/api/v1/datavask/parse` og `/api/v1/stats/national` bliver afvist, fordi de henter data fra offentlige registre med en delt nøgle.
- Løsning: Lav kaldet fra din egen server med en nøgle uden domæner, og send kun det, siden har brug for, videre til browseren.

## sandbox_scope

- Årsag: En testnøgle (`dawa_test_…`) er brugt på `/api/v1/enrich/…`, `/api/v1/datavask/parse` eller `/api/v1/stats/national`.
- Løsning: Brug en live-nøgle til de endpoints. Se [Testnøgler og sandbox](/guides/testnoegler-sandbox).

## key_blocked

En live-nøgle, der bliver brugt fra mange forskellige IP-adresser på én dag, ligner en lækket nøgle: den står i en offentlig app, i frontend-kode eller i et repository. Forløbet er:

1. Første dag får svarene headeren `X-Danadresse-Key-Status: warn`, og du får en mail. Kaldene virker stadig.
2. Fortsætter mønsteret efter 72 timer, bliver nøglen spærret. Svarene får `X-Danadresse-Key-Status: blocked` og status 403 med `key_blocked`.

```json id=blocked-body run=no
{
  "type": "ForbiddenError",
  "title": "This API key is blocked: it was used from … or more different IP addresses in one day — the pattern of a leaked key. …",
  "details": {
    "fix": "https://danadresse.dk/dashboard/keys",
    "page_host": "shop.firma.dk"
  },
  "code": "key_blocked"
}
```

`details.page_host` er med, når kaldene kommer fra en webside. Så er nøglen typisk lagt i frontend-kode.

Løsning:

- Bruges nøglen i en browser, så sæt *Tilladte domæner* på den. Domænelåste nøgler er ikke omfattet af lækkontrollen, fordi hver besøgende har sin egen IP.
- Er nøglen lækket, så lav en ny under [Nøgler](/dashboard/keys), skift den ind, og slet den gamle. Se [Rotér nøgler uden nedetid](/guides/roter-noegler).
- Kører du mange servere bag skiftende IP'er, så skriv til os via [support](/support).

Testnøgler er ikke omfattet af lækkontrollen.

## ip_not_allowed

```json id=ip-body run=no
{
  "type": "ForbiddenError",
  "title": "This API key is locked to specific IP addresses and this request came from 203.0.113.7. Add the address under API-nøgler → Tilladte IP-adresser.",
  "details": {"ip": "203.0.113.7"},
  "code": "ip_not_allowed"
}
```

IP-lås findes på Enterprise. `details.ip` er den adresse, API'et så.

- Serveren går ud på internettet gennem en anden adresse end den, du har skrevet på listen (NAT, en ny load balancer, et nyt cloud-område).
- Serveren bruger IPv6, og listen har kun IPv4, eller omvendt.
- Udgående IP'er i serverless og PaaS skifter ofte. Brug et netværk med fast udgående IP.

Tilføj adressen eller netværket under [Nøgler](/dashboard/keys).

## account_suspended

- Årsag: Hele kontoen er spærret, fx på grund af manglende betaling eller misbrug. Alle nøgler får den samme fejl, og det samme gør login i dashboardet.
- Løsning: Skriv til os via [support](/support).

## forbidden

```json id=forbidden-body run=no
{
  "type": "ForbiddenError",
  "title": "Blocked: abuse detected. Contact support if this is an error.",
  "details": null,
  "code": "forbidden"
}
```

- Årsag: Vores misbrugsfilter har blokeret IP-adressen, fx efter forsøg på at hente filer som `/.env` eller angrebsmønstre i URL'en. Blokeringen gælder alle kald fra den IP, uanset nøgle. På DAWA-stierne har svaret DAWA-formatet ovenfor, på `/api/v1` er det `{"error": {"code": "forbidden", …}}`. Det har `Access-Control-Allow-Origin: *`, så browserkode kan læse 403'en.
- Løsning: Skriv til os via [support](/support) med IP-adressen og tidspunktet.

## Næste skridt

- [Browsernøgler og tilladte domæner](/guides/browser-noegler-domaener)
- [Rotér nøgler uden nedetid](/guides/roter-noegler)
- [CORS-fejl i browseren](/guides/cors-fejl)
