Fejl 400 og 404 – forkerte parametre og ukendte id'er

Læs details i en 400-fejl, find stavefejl i parametre, der bliver ignoreret uden fejl, og skeln mellem not_found, route_not_found og unknown_entity.

4 min Niveau: Begynder ✓ Kode testet

En 400 betyder, at en parameter har en værdi, API'et ikke kan bruge. En 404 betyder, at stien eller det id, du spørger efter, ikke findes. Begge tæller som et kald på din kvote, så det betaler sig at fange dem i koden. Nøglen bliver tjekket før parametrene, så har du også en nøglefejl, ser du 401 eller 403 først.

400 invalid_query_parameter

På DAWA-stierne giver en forkert parameter altid status 400 med code invalid_query_parameter. details er en liste med én post pr. fejl:

JSON#bad-param-body
{
  "type": "QueryParameterFormatError",
  "title": "Invalid query parameter",
  "details": [
    {
      "type": "literal_error",
      "loc": ["query", "format"],
      "msg": "Input should be 'json', 'csv', 'geojson', 'geojsonz' or 'ndjson'",
      "input": "xml",
      "ctx": {"expected": "'json', 'csv', 'geojson', 'geojsonz' or 'ndjson'"}
    }
  ],
  "code": "invalid_query_parameter"
}

loc[1] er parameterens navn, msg er grunden, og input er den værdi, du sendte. Skriv dem i din log:

Python#read-400
import os

import requests

r = requests.get(
    "https://api.danadresse.dk/adresser",
    params={"postnr": "8000", "per_side": 5000},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
if r.status_code == 400:
    body = r.json()
    print(r.status_code, body["code"])
    for fejl in body["details"]:
        print(f"  {fejl['loc'][-1]} = {fejl['input']!r}: {fejl['msg']}")

De almindelige årsager:

Symptom i detailsÅrsagLøsning
per_side, less_than_equalper_side over grænsenHøjst 1000 på de fleste lister, 100 på /autocomplete. Se Paginering
side, greater_than_equalside=0Sider starter ved 1
format eller struktur, literal_errorVærdi, der ikke findesSe Formater
srid, x, y, int_parsing eller float_parsingTekst i stedet for tal, fx komma som decimaltegnBrug punktum: x=12.5683
srid, value_error, "srid skal være 4326 (WGS84) eller 25832 (ETRS89/UTM32)"Et andet koordinatsystem, fx srid=3857Brug 4326 (standard) eller 25832. Se Koordinater og srid
x eller y, missingReverse uden koordinaterSend både x og y
entitet, missing/replikering/udtraek uden entitet?entitet=adresse

På /api/v1 hedder den tilsvarende fejl 422 validation_error, og listen står i error.details.

Andre 400-koder

codeÅrsagLøsning
invalid_kvhkvh er ikke præcis 12 tegnFyld husnummeret op med _ foran: 03301407___1
invalid_kvhxkvhx er ikke præcis 19 tegnkvh + etage (3) + dør (4), fyldt op med _
invalid_cirkelcirkel er ikke tre tal, eller radius er uden for 1-50.000 mcirkel=længde,bredde,radius
invalid_polygonpolygon er ikke gyldig GeoJSON, eller har færre end tre punkterpolygon=[[[længde,bredde],…]], URL-kodet
invalid_parametermatrikelnr uden ejerlavkode, eller husnrfra/husnrtil, der ikke er et husnummerdetails.parameter nævner parameteren. Send også ejerlavkode, eller et husnummer som 5 eller 5A

Stavefejl i parameternavne giver ingen fejl

Et parameternavn, API'et ikke kender, bliver ignoreret, som i DAWA. Kendte filtre filtrerer, også på /autocomplete (postnr, kommunekode, adgangsadresseid) og sammen med cirkel, polygon og medtagnedlagte. Men ?postnummer=8000 giver ikke en fejl. Det giver de første 100 adresser i hele landet, fordi filteret aldrig blev brugt. Det samme sker med ?kommune=0101 i stedet for kommunekode, ?pr_side= i stedet for per_side, og format=csv på endpoints, der kun giver JSON.

Er resultatet for bredt, så tjek navnene mod API-beskrivelsen på /openapi.json. Funktionen her gør det automatisk, før den sender kaldet:

Python#check-params
import os

import requests

API = "https://api.danadresse.dk"
_spec = requests.get(f"{API}/openapi.json", timeout=10).json()


def unknown_params(path: str, params: dict) -> list[str]:
    """Parameternavne, som endpointet ikke kender (og derfor ville ignorere)."""
    known = {p["name"] for p in _spec["paths"][path]["get"].get("parameters", [])}
    return sorted(set(params) - known - {"api_key"})


def checked_get(path: str, params: dict) -> requests.Response:
    bad = unknown_params(path, params)
    if bad:
        raise ValueError(f"Ukendte parametre på {path}: {bad}")
    return requests.get(API + path, params=params, timeout=10,
                        headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]})


print("Ukendte:", unknown_params("/adresser", {"postnummer": "8000", "per_side": 10}))
r = checked_get("/adresser", {"postnr": "8000", "per_side": 1})
print(r.status_code, r.json()[0]["adressebetegnelse"])

Hent specifikationen én gang ved opstart, ikke ved hvert kald.

404 not_found: id'et eller koden findes ikke

JSON#not-found-body
{
  "type": "ResourceNotFoundError",
  "title": "Adresse 0a3f507a-ec01-32b8-e044-0003ba298018 not found",
  "details": null,
  "code": "not_found"
}

Gå listen igennem:

  1. Adgangsadresse-id på et adresse-endpoint. Id'erne er forskellige. Eksemplet ovenfor er et adgangsadresse-id sendt til /adresser/{id}. Brug /adgangsadresser/{id}, eller /adresser?adgangsadresseid=… for enhederne bag døren. Den anden vej virker: /adgangsadresser/{id} med et adresse-id svarer med den adgangsadresse, enheden hører til. Se Adresse eller adgangsadresse?
  2. Id fra et andet system. Et id, der ikke kommer fra adresseregistret (fx et internt kunde-id eller et id fra et testsystem), findes ikke her.
  3. Reverse uden adresse i nærheden. /adgangsadresser/reverse giver 404 med "title": "No address within range", når der ikke er nogen adresse i nærheden af punktet. Typisk er x og y byttet om, eller UTM-koordinater er sendt uden srid=25832. Se Koordinater og srid.
  4. Mellemrum eller linjeskift i id'et. Fjern whitespace, før du sætter id'et ind i URL'en.

Koder uden foranstillede nuller er ikke en årsag: /kommuner/101 og kommunekode=101 virker og svarer med 0101. Berigelser under /api/v1/enrich/adresser/{id}/… tager både et adgangsadresse-id og et adresse-id.

Prøv det selv med et adgangsadresse-id på adresse-endpointet:

Shell#wrong-id-curl
curl -s "https://api.danadresse.dk/adresser/0a3f507a-ec01-32b8-e044-0003ba298018" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"

404 route_not_found: stien findes ikke

route_not_found betyder, at URL'en ikke passer til noget endpoint:

  • /api/v1 foran en DAWA-sti. DAWA-stierne ligger i roden: https://api.danadresse.dk/adresser, ikke /api/v1/adresser.
  • Gammel sti fra DAWA's dokumentation, som ikke findes her. Se Kompatibilitet for listen over understøttede stier.
  • Stavefejl: /adresse i stedet for /adresser, /postnummer i stedet for /postnumre.

Formatet afhænger af stien. Starter den med en DAWA-sti (/adresser…), får du DAWA-formatet. Ellers får du /api/v1-formatet:

JSON#route-not-found
{
  "detail": {"error": {"code": "route_not_found", "message": "Not Found"}},
  "error": {"code": "route_not_found", "message": "Not Found"}
}

404 unknown_entity: forkert replikeringsentitet

/replikering/udtraek?entitet=… og /replikering/{entitet}/haendelser kender et fast sæt entiteter. Et forkert navn giver unknown_entity, og details.supported lister dem, der virker:

JSON#unknown-entity
{
  "type": "ResourceNotFoundError",
  "title": "Unknown replication entity 'adressen'",
  "details": {"supported": ["adgangsadresse", "adresse", "…"], "legacy_names": ["adgangsadresser", "adresser", "…"]},
  "code": "unknown_entity"
}

Entiteter står i ental: adresse, adgangsadresse, postnummer. De gamle flertalsnavne som adgangsadresser accepteres også og står i details.legacy_names. Se Replikering: hændelser.

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 →