Skip to content
Help center

Code example: look up soil contamination

2 min read

Soil contamination for a cadastral plot

Mapped soil contamination belongs to the plot — not to the individual address. Lookups therefore use owner-district code + cadastral number, exactly like /v1/jordstykker:

Bash
curl -H "Authorization: Bearer <key>" \
  "https://api.danskadresseapi.dk/v1/jordforurening/2000151/639"

The response

JSON
{
  "ejerlavskode": 2000151,
  "matrikelnr": "639",
  "kortlagt": true,
  "count": 1,
  "results": [
    {
      "lokalitetsnr": "101-00001",
      "status": "V2 kortlagt",
      "v1_kortlagt": false,
      "v2_kortlagt": true,
      "lokalitetsnavn": "Søfortvej 5, m.fl., Prøvestenen",
      "regionsnavn": "Region Hovedstaden",
      "attest_url": "https://jord.miljoeportal.dk/report/?elav=2000151&matrnr=639",
      "kilde_opdateret": "2026-04-27"
    }
  ]
}

V1 versus V2

LevelMeaning
V1The region knows of activities that may have contaminated the plot. Not yet investigated.
V2Contamination has been documented by investigation.

A locality can be both; then status reads V1 og V2 kortlagt and both v1_kortlagt and v2_kortlagt are true. Prefer the two booleans over parsing the status string — you avoid parsing Danish, and your code will not break if the regions add a new wording.

A clean plot returns 200, not 404

If the plot has no mapped contamination you still get a response:

JSON
{ "ejerlavskode": 2000151, "matrikelnr": "999x", "kortlagt": false, "count": 0, "results": [] }

This is deliberate. A 404 could not be told apart from "unknown plot", and for the vast majority of plots "no contamination" is exactly the answer you are looking for.

From address to contamination

If you start from an address, fetch its cadastral reference first:

Python
import os, requests

KEY = os.environ["DANSKADRESSEAPI_KEY"]
H = {"Authorization": f"Bearer {KEY}"}
BASE = "https://api.danskadresseapi.dk"

adr = requests.get(f"{BASE}/v1/adgangsadresser/0a3f5096-6d67-32b8-e044-0003ba298018",
                   headers=H, timeout=15).json()

elav = adr["ejerlavskode"]
matr = adr["matrikelnr"]

soil = requests.get(f"{BASE}/v1/jordforurening/{elav}/{matr}", headers=H, timeout=15).json()

if not soil["kortlagt"]:
    print("No mapped soil contamination on this plot")
else:
    for case in soil["results"]:
        level = "documented" if case["v2_kortlagt"] else "suspected"
        print(f"{case['lokalitetsnr']}: {level} — {case['attest_url']}")

Filter across plots

The list endpoint accepts ejerlavskode, regionsnavn and niveau:

Bash
curl -H "Authorization: Bearer <key>" \
  "https://api.danskadresseapi.dk/v1/jordforurening?regionsnavn=Region%20Midtjylland&niveau=v2&limit=100"

niveau=v2 also matches localities that are both V1 and V2.

Good to know

  • Data comes from Danmarks Miljøportal (DKjord) and is refreshed nightly. kilde_opdateret shows when the region last touched that particular case.
  • attest_url points to the official soil contamination certificate — the same document you would otherwise have to track down during a property transaction.
  • Several addresses on the same plot naturally share the same cases.
  • A plot can have multiple localities. Check count rather than assuming one.
Was this helpful?