API-nøglen i headeren eller i URL'en (api_key)
Vælg mellem X-Api-Key-headeren og ?api_key= i URL'en, og send nøglen korrekt fra curl, Python, Node og PHP.
Hvert kald til https://api.danadresse.dk skal have en API-nøgle. Du kan sende den på to måder: i headeren X-Api-Key eller som query-parameteren api_key i URL'en. Begge virker på alle endpoints, både de DAWA-kompatible stier og /api/v1.
Brug headeren, når du kan. Denne guide forklarer hvorfor, og hvornår URL-varianten er det rigtige valg.
Sådan læser API'et nøglen
Serveren kigger først efter headeren X-Api-Key. Kun hvis den mangler eller er tom, læses api_key fra URL'en. Det har to konsekvenser:
- Sender du begge, vinder headeren. En forkert nøgle i headeren giver
401 invalid_api_key, selv om URL'en har den rigtige. - En tom header (fx
X-Api-Key:fordi miljøvariablen ikke er sat) tæller som manglende, og så brugesapi_keyfra URL'en, hvis den findes. Ellers får du401 missing_api_key.
Header-navnet er ikke følsomt for store og små bogstaver, så x-api-key og X-API-KEY virker også. Mellemrum før og efter nøglen i headeren fjernes.
Header: anbefalet fra servere og scripts
Med curl:
curl -s "https://api.danadresse.dk/postnumre/8000" \ -H "X-Api-Key: $DANADRESSE_API_KEY"
Med Python og requests:
import os import requests r = requests.get( "https://api.danadresse.dk/postnumre/8000", headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]}, timeout=10, ) r.raise_for_status() print(r.json()["navn"])
Med Node 18 eller nyere:
const res = await fetch("https://api.danadresse.dk/postnumre/8000", { headers: { "X-Api-Key": process.env.DANADRESSE_API_KEY }, }); if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`); const postnummer = await res.json(); console.log(postnummer.navn);
Med PHP og curl-udvidelsen:
<?php $ch = curl_init("https://api.danadresse.dk/postnumre/8000"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_HTTPHEADER => ["X-Api-Key: " . getenv("DANADRESSE_API_KEY")], ]); $body = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($status !== 200) { fwrite(STDERR, "HTTP $status: $body\n"); exit(1); } echo json_decode($body, true)["navn"], "\n";
Query-parameter: når du ikke kan sætte en header
?api_key= findes, fordi nogle steder kun lader dig angive en URL:
- et
<script src="…">-tag, fx DAWA's gamle widget:https://api.danadresse.dk/js/autocomplete/dawa-autocomplete2.min.js?key=dawa_live_…(widgetten sender derefter nøglen somapi_keypå hvert kald) - regneark og værktøjer, der kun kan hente en URL, fx
IMPORTDATAi Google Sheets - en hurtig test i browserens adresselinje
curl -s "https://api.danadresse.dk/postnumre/8000?api_key=$DANADRESSE_API_KEY"I browseren er der en ekstra forskel. En brugerdefineret header som X-Api-Key får browseren til at sende et CORS-preflight (OPTIONS) før det rigtige kald. API'et svarer ja og beder browseren huske svaret i op til et døgn (nogle browsere husker det kortere). Preflightet tæller ikke som et API-kald. Med api_key i URL'en er kaldet en "simple request" uden preflight. Begge dele virker, så vælg ud fra, hvad dit bibliotek gør nemmest.
Hvorfor headeren er det sikre valg
En URL bliver kopieret mange steder, som du ikke styrer:
- access-logs i proxyer, load balancers og firewalls mellem dig og API'et
- fejlrapporteringsværktøjer, der gemmer den fulde request-URL
- shell-historik, CI-logs og skærmbilleder af browserens netværksfane
- HAR-filer, som du sender til support
Vores egne applikationslogs maskerer værdien af api_key= (den bliver til api_key=***, og det samme gælder X-Api-Key-headeren). Du kan ikke regne med, at alle andre led på vejen gør det samme.
En header havner sjældnere i logs. Den er ikke hemmelig over for den, der kører koden. I en browser kan enhver besøgende se nøglen i netværksfanen, uanset om den ligger i header eller URL. Til kode, der kører hos dine besøgende, skal du derfor bruge en domænelåst browsernøgle, se Browsernøgler og tilladte domæner.
Hvilken metode skal jeg bruge?
| Situation | Metode | Nøgletype |
|---|---|---|
| Backend, cron-job, ETL, CI | X-Api-Key-header | Servernøgle fra miljøvariabel |
fetch i browseren, React, Vue | Header eller api_key | Domænelåst browsernøgle |
<script src> til en widget | ?key= / api_key i URL'en | Domænelåst browsernøgle |
Google Sheets IMPORTDATA, simple værktøjer | api_key i URL'en | Separat nøgle, som du kan rotere |
| Udvikling og automatiske tests | Header | Testnøgle (dawa_test_…) |
Masker nøglen i dine egne logs
Logger din applikation udgående URL'er, så fjern nøglen, før linjen skrives. Et logging-filter i Python, der gør det samme som vores:
import logging import re _SECRET = re.compile(r"(?i)((?:api_key|apikey)=|x-api-key\s*[:=]\s*)([^&\s\"']+)") class RedactApiKey(logging.Filter): """Erstat API-nøgler i logbeskeder med ***.""" def filter(self, record: logging.LogRecord) -> bool: record.msg = _SECRET.sub(r"\1***", str(record.msg)) if record.args: record.args = tuple( _SECRET.sub(r"\1***", a) if isinstance(a, str) else a for a in record.args ) return True handler = logging.StreamHandler() handler.addFilter(RedactApiKey()) logging.basicConfig(level=logging.INFO, handlers=[handler]) logging.getLogger("demo").info("GET https://api.danadresse.dk/postnumre?api_key=dawa_live_hemmelig")
Filteret skriver api_key=*** i stedet for nøglen.
Hvis nøglen er lækket
Har en nøgle stået i en URL, der er endt i en offentlig log eller et repository, så opret en ny nøgle under Nøgler, skift den ind i din konfiguration og slet den gamle. En live-nøgle, der bruges fra mange forskellige IP-adresser samme dag, bliver markeret som lækket, og du får en mail. Se Fejl 403 for, hvad der sker, hvis den ikke bliver skiftet.
Næste skridt
- Testnøgler og sandbox til udvikling og CI.
- Browsernøgler og tilladte domæner, før du lægger en nøgle i frontend-kode.
- Fejl 401: manglende eller ugyldig nøgle, hvis kaldet bliver afvist.
Relaterede guides
Markdown-kilde Fejl i guiden? Skriv til os API-reference (Swagger)