På denne side
Byg på dansk ejendomsdata på minutter
Grundfast er et REST-API. Alle svar er JSON i UTF-8. Base-URL i produktion: https://api.grundfast.dk. Vil du prøve kald direkte i browseren, så åbn den interaktive API-reference (OpenAPI 3.1).
Kom i gang
Hent en nøgle i dashboardet og kald et endpoint. De fleste endpoints kræver en nøgle; demo- og kodeliste-endpoints er åbne.
# gf_test_ = gratis sandbox (intet kort); gf_live_ i produktion curl https://api.grundfast.dk/v1/bbr/ejendom/5651067 \ -H "Authorization: Bearer gf_test_…"
Autentificering
Send din nøgle som bearer-token. Nøgler har præfiks gf_live_ eller gf_test_.
Authorization: Bearer gf_live_…
Test-tilstand (sandbox)
gf_test_-nøgler er en sandbox: de rammer de samme rigtige registre, men faktureres aldrig, tæller ikke mod din plans forbrug, og er begrænset til 25.000 kald/måned. Perfekt til CI og staging — læg dem trygt i dit build. Hvert svar markeres med X-Grundfast-Environment: test, og X-Quota-* viser sandbox-loftet. Ved loftet svarer API'et 429 — skift til en gf_live_-nøgle i produktion.
Endpoints
Hvert endpoint svarer med JSON i UTF-8. Nøgle-mærkede endpoints kræver en Bearer-token; åbne endpoints (demo + kodelister) kan kaldes uden.
BBR
nøgle/v1/bbr/ejendom/:bfeHele ejendommen for et BFE — grund + alle bygninger (oversat, joinet).
/v1/bbr/ejendom/:bfe/geojsonWFS-compat FeatureCollection — én Feature pr. bygning, WGS84.
/v1/bbr/bygning?bfe=Samme som ejendom, valideret query-param.
/v1/bbr/ejendom:batchOp til 50 BFE i ét kald — { bfe: number[] }. Property-keyed, én enhed pr. BFE.
Matriklen
nøgle/v1/matrikel/ejendom/:bfeMatriklen — jordstykker + ejerlav (live; demo: /v1/demo/matrikel).
/v1/matrikel/ejendom:batchOp til 50 BFE i ét kald — { bfe: number[] }. Samme partial-failure-form som BBR-batch.
GeoDanmark
nøgle/v1/geodanmark/bygninger/:bfeGeoDanmark bygningsfootprints — de rigtige bygningsomrids (WGS84-polygoner) pr. bygning på et BFE, dér hvor BBR kun har et punkt. CC BY 4.0 (@geodanmark). Demo: /v1/demo/geodanmark/bygninger.
DAGI
nøgle/v1/dagi/:tema/:kodeDAGI — administrativ geografi (kommune/region/sogn …): navn + best-effort WGS84-geometri. Liste: /v1/dagi og /v1/dagi/:tema. Demo: /v1/demo/dagi.
/v1/dagi/reverseHvilke administrative områder ligger en koordinat i — region, kommune, sogn, retskreds, politikreds og opstillingskreds i ét kald. `?lon=&lat=` (eller DAWA-style `x/y/srid`). Et tema der mangler i svaret er uafklaret, ikke et nej; en tom liste betyder at ingen dansk inddeling dækker punktet.
/v1/dagi:batchOp til 50 områder i ét tema i ét kald — { tema, kode: string[] }.
Adresser (DAR)
nøgle/v1/adresse/:uuidDAR-adresse (register #6) — én adresse-UUID slået op til ren adresse. DAWA-erstatningen. Demo: /v1/demo/adresse.
/v1/adresse/search?q=DAR-native autocomplete — rangerede hits på fritekst over det lokale søgeindeks (demo: /v1/demo/adresse-search).
/v1/adresse:batchOp til 50 DAR-adresse-UUID i ét kald — { uuid: string[] }. Partial-failure pr. UUID.
DHM
nøgle/v1/dhm/punkt?lon=&lat=DHM — terrænkote i et WGS84-punkt (demo: /v1/demo/dhm).
/v1/dhm/kote?lon=&lat=DHM — terrænkote i DVR90 til en situationsplan. Samme svar som /v1/dhm/punkt, men navnet dokumentet bruger; svaret bærer selv system (DVR90), opløsning (0,4 m), metode og usikkerhed (0,05 m). Manglende data er null, aldrig 0.
/v1/dhm/kote:batchDHM — koter for op til 50 punkter i ét kald (hjørnerne af en tegnet bygning + nærmeste skelpunkt). Punkter på samme grund deler ét raster. Afregnes pr. dedupliceret punkt og er ikke en plan-feature. Et ubesvaret punkt havner i fejl, aldrig i punkter med null.
/v1/dhm/profil?fra=&til=&trin=DHM — terrænet langs en ret linje med fald_m, fx faldet fra vej til skel. Ét raster, ikke ét kald pr. station; begge endepunkter er altid med. Afregnes pr. returneret station.
/v1/dhm/terraen?bbox=&trin=DHM — et regulært net af terrænkoter over en bbox i EPSG:25832 METER, det heightfield en 3D-situationsplan står på. Hele griddet er ét raster og derfor ét afregnet kald, hvor de samme punkter gennem kote:batch koster ét pr. punkt. koter er row-major fra nord mod syd; en celle uden data er null, aldrig 0. Maks. 240 m pr. side og 100.000 koter.
/v1/dhm/bygninger/:bfeDHM — målt højde på hver bygning på en ejendom, målt inde i GeoDanmark-fodaftrykket (DVR90). tag_m er 95-percentilen af overfladen, terraen_m medianen af terrænet; hoejde_m er forskellen, eller null med en aarsag — aldrig 0.
Ejendomsvurdering
nøgle/v1/vurdering/:bfeEjendomsvurdering (VUR) pr. BFE — ejendomsværdi, grundværdi, vurderet areal, dækningsafgift og juridisk kategori for hvert registreret år, grupperet pr. vurderingsejendom. Læs `antal_vurderingsejendomme` FØR `seneste`: er der mere end én, er `seneste` null, fordi der ikke findes ét ærligt tal — det er ikke det samme som ingen vurdering, hvilket er en 404. Beløb i HELE kroner, ikke øre. Keyless demo: /v1/demo/vurdering.
Ortofoto
nøgle/v1/orto/tile/:z/:x/:yOrtofoto — web-mercator JPEG-tile (XYZ), 256×256 som standard. Orienterings-backdrop, ikke målfast. `?aar=YYYY` henter en tidligere årgang; `?dpr=2` renderer samme tile i 512×512 til en retina-skærm (samme jord, ét kald). Keyless demo: /v1/demo/orto/tile/:z/:x/:y.
/v1/orto/aargangeHvilke ortofoto-årgange tjenesten UDGIVER, nyeste først — læst af dens egen GetCapabilities, så den svarer også uden upstream-token. National liste, ikke en dækningsudtalelse: brug /v1/orto/daekning til et konkret punkt. Keyless demo: /v1/demo/orto/aargange.
/v1/orto/daekningHvilke luftfoto-årgange er faktisk fløjet hen over et punkt (`?lon=&lat=`). Danmark flyves i en regional rotation, så den nationale liste på /v1/orto/aargange er ikke hvad der dækker et sted. `daekker: null` betyder uafklaret — aldrig "ikke fløjet her". Keyless demo: /v1/demo/orto/daekning.
Stednavne
nøgle/v1/stednavne/punkt?lon=&lat=&radius=Stednavne nær et WGS84-punkt (nearest-first; demo: /v1/demo/stednavne).
Jordforurening
nøgle/v1/jord/omraadeklassificering?lon=&lat=Jordforurening (register #10) — er punktet omfattet af kommunens områdeklassificering (jordforureningslovens § 50 a), og ligger det i et analysefrit delområde? Vejledende: kommunens jordregulativ er det juridiske grundlag, og svaret bærer kommunens eget link. Demo: /v1/demo/jord.
Naturbeskyttelse
nøgle/v1/natur/skovbyggelinje?lon=&lat=Naturbeskyttelse (register #11) — ligger punktet inden for en registreret skovbyggelinje (naturbeskyttelseslovens § 17, 300 m fra skov), eller er linjen ophævet netop dér? Laget rummer begge dele, og svaret skiller dem ad. Demo: /v1/demo/natur.
Byggelinjer & § 3
nøgle/v1/natur/byggelinjer?lon=&lat=Naturbeskyttelse — ti byggelinjer på ét punkt i ét kald: strandbeskyttelse og klitfredning (§ 15), sø og å (§ 16), skov (§ 17), fortidsminde (§ 18), kirke (§ 19), § 3-natur og § 3-vandløb, samt beskyttede sten- og jorddiger (museumsloven § 29 a). afstand_m er fortegnet — negativ inde, positiv ude. Svaret bærer ingen dom; læs status før inden_for. Keyless demo: /v1/demo/byggelinjer.
CVR
nøgle/v1/cvr/:cvrVirksomhed på CVR-nummer (register #8) — navn, adresse, status, branche. Demo: /v1/demo/cvr.
DAWA drop-in
nøgle/v1/autocomplete?q=DAWA-kompatibel samlet autocomplete — adgangsadresser, vejnavne og postnumre i ét.
/v1/adgangsadresser/reverse?lon=&lat=Reverse geocoding — nærmeste adgangsadresse til et WGS84-punkt (DAWA-erstatning).
/v1/adgangsadresser/bfe/:bfeAlle adgangsadresser på et BFE — det omvendte af reverse (DAWA adgangsadresser?bfenummer=). Tom liste (ikke 404), hvis BFE endnu ikke er indekseret.
/v1/datavask/adgangsadresser?betegnelse=Adressevask — match en fritekst-adresse mod DAR med A/B/C-sikkerhedsbånd.
/v1/jordstykker?ejerlavkode=&matrikelnr=Adresse→BFE-bro: jordstykket for en matrikelbetegnelse (ejerlavskode + matrikelnr) → dets BFE; reverse fra en koordinat via /v1/jordstykker/reverse?lon=&lat=.
/v1/postnumre/autocomplete?q=Postnumre-autocomplete på fritekst. Hele listen på /v1/postnumre (usideinddelt — hele korpuset i ét svar; ?stormodtagere=true tilføjer de historiske stormodtager-koder), opslag på /v1/postnumre/:nr.
/v1/vejnavne/autocomplete?q=Vejnavne-autocomplete på tværs af landet (DAWA-kompatibel; ?kommunekode= afgrænser til én kommune). Hele listen på /v1/vejnavne (per_side/side).
/v1/ejerlav/autocomplete?q=Ejerlav-autocomplete på fritekst. Hele listen på /v1/ejerlav (per_side/side), opslag på /v1/ejerlav/:kode.
Eksport
nøgle/v1/exportAsync bulk-eksport (CSV/NDJSON/GeoJSON) over en afgrænset id-liste (bbr/matrikel/adresse). Poll status på /v1/export/:id og hent filen på /v1/export/:id/download. Virker med nøgle eller session.
Åbne (uden nøgle)
åben/v1/kodeliste/:navnEn oversat kodeliste (kode → tekst), fx varmeinstallation.
/v1/demo/ejendomOffline-eksempel — mærk outputtet uden nøgle.
/v1/demo/ejendom.geojsonOffline WFS-compat GeoJSON-eksempel.
TypeScript-SDK
Fuldt typet klient mod hele API-fladen — svaret er typecheckede objekter. Live på npm: npm i @grundfast/sdk (ESM + CJS, nul runtime-dependencies). Foretrækker du REST, kalder du direkte — se cURL ovenfor. Sådan bliver kaldet med SDK’et:
import { GrundfastClient } from '@grundfast/sdk'; const gf = new GrundfastClient({ apiKey: 'gf_test_…' }); // gf_live_ i produktion const ejendom = await gf.ejendom(5651067); console.log(ejendom.jordstykke.ejerlav_navn); console.log(ejendom.bygninger.length, 'bygninger');
// Op til 50 BFE i ét kald — partial-failure pr. BFE. const { results, errors } = await gf.ejendomBatch([5651067, 5651068]); // …eller auto-paginér en stor BFE-liste i 50-chunks: for await (const { bfe, ejendom } of gf.ejendomStream(mineBfeer)) { console.log(bfe, ejendom.antal_bygninger); }
Se den fulde SDK-reference — hver metode pr. register med et typet eksempel.
Webhooks
Abonnér på hændelser (key.created, key.revoked, subscription.updated, usage.threshold) og få et HMAC-SHA256-signeret POST til dit endpoint, når de sker. Registrering sker i dashboardet (eller på /v1/me/webhooks med din session), og hver leverance genforsøges med backoff. Læs webhooks-dokumentationen — event-katalog, payload-skema, signaturverificering og retry.
Svar-format
Et BFE giver én ejendom med alle bygninger. Hver bygning har oversatte koder, arealer, materialer, varme, geometri (WGS84) og enheder.
{ "type": "ejendom", "bfe_nummer": 5651067, "grund_id": "000000b1-…", "kommunekode": "0740", "jordstykke": { "matrikelnummer": null, "ejerlav_kode": null, "ejerlav_navn": null }, "antal_bygninger": 3, "bygninger": [ { "type": "bygning", "anvendelse": { "kode": "120", "tekst": "Fritliggende enfamiliehus" }, "opfoerelsesaar": 1958, "om_tilbygningsaar": 1994, "areal": { "bebygget_m2": 116, "samlet_boligareal_m2": 95 }, "materialer": { "ydervaeg": { "tekst": "Mursten" }, "tag": { "tekst": "Tegl" } }, "varme": { "installation": { "tekst": "Fjernvarme/blokvarme" } }, "fredning": { "fredet": false, "status_tekst": "vurderet", "bevaringsvaerdi": 4, "kilde": "fbb" }, "geometri": { "type": "Point", "coordinates": [10.32, 56.16] }, "enheder": [ { "anvendelse": { "tekst": "…" }, "antal_vaerelser": 4 } ] } ] }
Rate limits
Hver nøgle har en burst-grænse pr. minut (afhænger af din plan) oven på den månedlige kvote. Free: 5.000 kald/md og 1.200 kald/min. Overskrider du en grænse, får du 429. Hvert svar bærer rate-limit-headers, så du kan styre din throughput uden at gætte:
X-RateLimit-Limit # burst-loft (kald/min for din plan) X-RateLimit-Remaining # tilbage i det aktuelle minut-vindue X-RateLimit-Reset # unix-sekunder til vinduet nulstilles X-Quota-Limit # månedlig kvote (inkluderede kald) X-Quota-Remaining # tilbage af månedens kvote X-Quota-Reset # unix-sekunder til kvoten nulstilles Retry-After # sekunder at vente (kun ved 429)
Cache-headers & paginering
Udover rate-limit- og kvote-headerne ovenfor bærer hvert svar et friskheds-signal, så du altid ved, om du ser live eller cachede data:
X-Grundfast-Stale # "true" når svaret kom fra SLA-mirroren under et upstream-udfald X-Grundfast-Cache-Age # cachens alder i sekunder (kun sat ved et stale svar) X-Grundfast-Environment # "test" for gf_test_-nøgler (sandbox — faktureres aldrig)
Under et upstream-udfald serverer SLA-mirroren den sidst kendte kopi med X-Grundfast-Stale: true og X-Grundfast-Cache-Age, så du selv kan afgøre, om alderen er acceptabel. Deployment kan sætte et loft (MAX_STALE_SECONDS): en kopi ældre end loftet afvises med 502/503 i stedet for at blive serveret som et forældet 200.
Register-lister som /v1/ejerlav og /v1/vejnavne sideinddeles med query-parametrene per_side og side (1-indekseret); svaret bærer antal (denne side) og total (hele registret), så du kan paginere uden at gætte. Autocomplete-endpoints klipper i stedet til de bedste hits.
Fejl
Fejl returneres som { "error": "…" } med en passende HTTP-status.
400 ugyldig forespørgsel (fx forkert BFE-format eller manglende påkrævet query-param) 401 manglende / ugyldig API-nøgle 403 kontoen er suspenderet — kontakt support 404 ukendt BFE 429 rate limit eller månedlig kvote opbrugt 502 upstream Datafordeler-fejl (efter retry) 503 kilden er ikke konfigureret i dette deployment