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.

3 min Niveau: Begynder ✓ Kode testet

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:

Shell#regioner-curl
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#kommuner-python
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>')
FeltIndhold
kodeFire cifre som tekst, f.eks. 0101
navnKommunens navn
regionskode, regionsnavnDen region, kommunen ligger i
regionSamme som objekt med href
udenforkommuneinddelingtrue 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#postnumre-python
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")
FeltIndhold
nrFire cifre som tekst
navnPostdistriktets navn, f.eks. København V
kommunerDe kommuner, postnummeret dækker, som {href, kode, navn}
stormodtagerfalse for geografiske postnumre. Listen viser kun dem, medmindre du tilføjer stormodtagere=true. Se Stormodtagerpostnumre
dagi_idDAGI-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).

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:

Shell#postnr-autocomplete
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.

JavaScript#cache-node
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

Relaterede guides

Markdown-kilde Fejl i guiden? Skriv til os API-reference (Swagger)

Prøv det med en gratis nøgle

2 000 kald/måned på gratisplanen. Intet kreditkort.

Opret konto →