# Postnumre, kommuner og regioner til dropdowns

> Hent de fulde lister over postnumre, kommuner og regioner, cache dem rigtigt, og undgå de typiske fejl med kommunekoder.
>
> https://danadresse.dk/guides/postnumre-og-kommuner · verified 2026-11-02
En dropdown med kommuner, et filter på region eller et postnummerfelt, der udfylder bynavnet: listerne ændrer sig sjældent, så de skal hentes én gang og gemmes. Denne guide viser de tre endpoints, og hvordan du cacher dem.

## Regioner

`GET /regioner` returnerer de fem regioner i én liste:

```bash id=regioner-curl run=live expect="nuts2"
curl -s "https://api.danadresse.dk/regioner" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
```

Hver region har `kode` (1081-1085), `navn` og `nuts2`. Listen er sorteret efter kode.

## Kommuner

`GET /kommuner` returnerer kommunerne sorteret efter navn. Hele listen kommer i ét kald:

```python id=kommuner-python run=live expect="kommuner"
import os
import requests

r = requests.get(
    "https://api.danadresse.dk/kommuner",
    params={"per_side": 500},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=15,
)
r.raise_for_status()
kommuner = r.json()

options = [(k["kode"], k["navn"]) for k in kommuner if not k["udenforkommuneinddeling"]]
print(f"{len(options)} kommuner til dropdown")
for kode, navn in options[:5]:
    print(f'  <option value="{kode}">{navn}</option>')
```

| Felt | Indhold |
|---|---|
| `kode` | Fire cifre som tekst, f.eks. `0101` |
| `navn` | Kommunens navn |
| `regionskode`, `regionsnavn` | Den region, kommunen ligger i |
| `region` | Samme som objekt med `href` |
| `udenforkommuneinddeling` | `true` kun for Christiansø (`0411`), som ikke hører til en kommune |

Listen indeholder de 98 kommuner plus Christiansø. Filtrer Christiansø fra med `udenforkommuneinddeling`, hvis du kun vil vise rigtige kommuner. `GET /kommuner?regionskode=1084` giver kommunerne i én region.

## Postnumre

Der er omkring 1 100 postnumre, og `GET /postnumre` returnerer dem alle i ét svar, sorteret efter nummer, ligesom DAWA. Vil du hellere hente dem i bidder, så brug `side` og `per_side` (op til 1000).

```python id=postnumre-python run=syntax
import json
import os
import requests

s = requests.Session()
s.headers["X-Api-Key"] = os.environ["DANADRESSE_API_KEY"]

r = s.get("https://api.danadresse.dk/postnumre", timeout=60)   # hele listen
r.raise_for_status()
postnumre = [{"nr": p["nr"], "navn": p["navn"],
              "kommuner": [k["kode"] for k in p["kommuner"]]} for p in r.json()]

with open("postnumre.json", "w", encoding="utf-8") as f:
    json.dump(postnumre, f, ensure_ascii=False)
print(len(postnumre), "postnumre gemt")
```

| Felt | Indhold |
|---|---|
| `nr` | Fire cifre som tekst |
| `navn` | Postdistriktets navn, f.eks. `København V` |
| `kommuner` | De kommuner, postnummeret dækker, som `{href, kode, navn}` |
| `stormodtager` | `false` for geografiske postnumre. Listen viser kun dem, medmindre du tilføjer `stormodtagere=true`. Se [Stormodtagerpostnumre](/guides/stormodtagere) |
| `dagi_id` | DAGI-id'et for postnummerområdet |

Et postnummer kan dække flere kommuner. Brug derfor aldrig postnummeret til at udlede kommunen. Brug adressen (se [Find kommune, region og sogn for en adresse](/guides/kommune-sogn-politikreds)).

## Postnummerfelt, der udfylder bynavnet

Til et enkelt felt behøver du ikke hele listen. `GET /postnumre/{nr}` slår ét postnummer op, og `GET /postnumre/autocomplete?q=` foreslår postnumre ud fra begyndelsen af nummeret eller navnet:

```bash id=postnr-autocomplete run=live expect="tekst"
curl -s "https://api.danadresse.dk/postnumre/autocomplete?q=Hel&per_side=5" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
```

Svaret er en liste af `{"tekst": "2900 Hellerup", "postnummer": {…}}`. `GET /kommuner/autocomplete?q=` virker på samme måde for kommuner.

## Cache listerne

Postnumre og kommuner ændrer sig nogle få gange om året. Hent dem én gang i døgnet på serveren, gem dem i en fil, Redis eller din database, og server dropdownen derfra. Det sparer kald og gør formularen hurtigere.

Svarene fra `/kommuner`, `/regioner` og `/postnumre` har `Cache-Control: private, max-age=86400, stale-while-revalidate=604800`. En browser cacher dem derfor et døgn. Svar under 256 KB har også en `ETag`: sender du `If-None-Match` med den, svarer API'et `304 Not Modified` uden indhold, når listen ikke er ændret. Den fulde postnummerliste er større og har ingen `ETag`.

```js id=cache-node run=syntax
import { readFile, writeFile } from "node:fs/promises";

const FIL = "./kommuner.json";
const MAKS_ALDER_MS = 24 * 60 * 60 * 1000;

export async function kommuner() {
  try {
    const cache = JSON.parse(await readFile(FIL, "utf8"));
    if (Date.now() - cache.hentet < MAKS_ALDER_MS) return cache.data;
  } catch {
    // ingen cache endnu
  }
  try {
    const res = await fetch("https://api.danadresse.dk/kommuner?per_side=500", {
      headers: { "X-Api-Key": process.env.DANADRESSE_API_KEY },
    });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = (await res.json()).map((k) => ({ kode: k.kode, navn: k.navn }));
    await writeFile(FIL, JSON.stringify({ hentet: Date.now(), data }));
    return data;
  } catch (err) {
    // API'et svarer ikke: brug den gamle cache, hvis der er en
    const gammel = JSON.parse(await readFile(FIL, "utf8").catch(() => "null"));
    if (gammel) return gammel.data;
    throw err;
  }
}
```

Hvis du henter listen fra browseren, så brug en browsernøgle låst til dit domæne, og gem resultatet i `localStorage` med et tidsstempel.

## Kommunekoder: de typiske fejl

- **Foranstillet nul.** Koden er `0101`, ikke `101`. API'et returnerer altid fire cifre, men Excel og mange JSON-parsere laver koden om til et tal, hvis du lader dem. Gem den som tekst.
- **Input uden nul virker.** Filtre og opslag accepterer koden uden nul og fylder selv op: `kommunekode=101`, `kommunekode=101|147` og `/kommuner/101` giver det samme som med `0101`. Det gælder også postnumre som `/postnumre/800`.
- **Regionskode er ikke kommunekode.** Regionerne har koderne 1081-1085. Kommunekoder ligger fra `0101` til `0860`.

## Næste skridt

- [Find kommune, region og sogn for en adresse](/guides/kommune-sogn-politikreds)
- [Stormodtagerpostnumre i formularer](/guides/stormodtagere)
- [Caching](/guides/caching)
