Find the address from a GPS position
Look up the nearest address from longitude and latitude with reverse geocoding, and handle GPS inaccuracy with a radius search.
A tradesperson app should fill in the address from the phone's position. An insurance claim only has a point on a map. A fleet tool should show which address a vehicle is parked at. All three are reverse geocoding: from coordinate to address.
The API has two endpoints for it, plus a radius search that gives you more control when the position is inaccurate.
The simple call
GET /adgangsadresser/reverse returns the nearest active access address (the building entrance) to the point:
curl -s "https://api.danadresse.dk/adgangsadresser/reverse?x=12.5757&y=55.7326" \ -H "X-Api-Key: $DANADRESSE_API_KEY"
x is longitude and y is latitude. Swapping them is the most common mistake: Denmark lies at roughly 8-15° east and 54-58° north, so an x above 50 is almost always a swap.
The response has the same shape as GET /adgangsadresser/{id}, and struktur=mini or struktur=flad works here too. The most important fields:
| Field | Content |
|---|---|
id | The access-address UUID |
adressebetegnelse | E.g. Strandvejen 100, 2900 Hellerup |
vejstykke.navn, husnr, postnummer.nr, postnummer.navn | The parts of the address |
kommune, sogn, politikreds … | Administrative areas |
adgangspunkt.koordinater | The address's own point, [x, y] |
If your coordinates are in UTM32 (metres), add srid=25832. Then both the input and the coordinates in the response are in metres:
curl -s "https://api.danadresse.dk/adgangsadresser/reverse?x=724434.93&y=6175755.61&srid=25832" \ -H "X-Api-Key: $DANADRESSE_API_KEY"
GET /adresser/reverse works the same way but returns a full address with floor and door. It picks one of the units in the building. In a block of flats the API cannot know which flat the user is in, so let the user choose floor and door afterwards. Fetch the list with GET /adresser?adgangsadresseid={id}&struktur=mini.
What reverse does not tell you
- No distance. The response does not say how far the point is from the address. Calculate it yourself from
adgangspunkt.koordinater(see Distance between two addresses). - No maximum distance. The endpoint looks up to about 60 km away. If the user stands in the middle of a field, you still get an address, maybe a few kilometres away. Only when there is no address within that distance does the API answer
404with the codenot_found. - Active addresses only. Current and provisional addresses are included. Retired addresses are not.
- Always the nearest. Reverse searches in growing areas until the nearest entrance is found, also in dense city areas. It returns the same address the radius search below puts first.
GPS is not exact: use a radius
A phone reports its position with an uncertainty (coords.accuracy in the browser, in metres). Outdoors it is typically 5-20 metres, indoors and between tall buildings often 50 metres or more. With an uncertainty of 40 metres the user could just as well be at the house next door.
So use cirkel=lon,lat,radius on /adgangsadresser with the radius set from the uncertainty. Results come sorted with the nearest first. If there are several candidates, show them as a short list:
const API = "https://api.danadresse.dk"; const headers = { "X-Api-Key": process.env.DANADRESSE_API_KEY }; function afstandMeter(lat1, lon1, lat2, lon2) { const R = 6371008.8, rad = Math.PI / 180; const dLat = (lat2 - lat1) * rad, dLon = (lon2 - lon1) * rad; const a = Math.sin(dLat / 2) ** 2 + Math.cos(lat1 * rad) * Math.cos(lat2 * rad) * Math.sin(dLon / 2) ** 2; return 2 * R * Math.asin(Math.sqrt(a)); } async function adresserVed(lat, lon, noejagtighed) { const radius = Math.min(Math.max(Math.round(noejagtighed), 25), 250); const url = new URL(`${API}/adgangsadresser`); url.searchParams.set("cirkel", `${lon},${lat},${radius}`); url.searchParams.set("struktur", "mini"); url.searchParams.set("per_side", "5"); const res = await fetch(url, { headers }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const kandidater = await res.json(); if (kandidater.length > 0) return kandidater; // Nothing within the radius: fall back to the nearest address at all const rev = await fetch(`${API}/adgangsadresser/reverse?x=${lon}&y=${lat}`, { headers }); if (rev.status === 404) return []; const a = await rev.json(); const [x, y] = a.adgangspunkt.koordinater; return [{ id: a.id, betegnelse: a.adressebetegnelse, x, y }]; } const lat = 55.67565, lon = 12.56935, noejagtighed = 30; for (const a of await adresserVed(lat, lon, noejagtighed)) { console.log(`${a.betegnelse} (afstand ${Math.round(afstandMeter(lat, lon, a.y, a.x))} m)`); }
The radius must be between 1 and 50,000 metres, otherwise the API answers 400 with the code invalid_cirkel. With srid=25832 the centre is in metres.
In the browser
navigator.geolocation gives position and uncertainty. Call the API with a browser key locked to your domain (see Browser keys and allowed domains):
const API_KEY = "dawa_live_your_browser_key"; // locked to your domain navigator.geolocation.getCurrentPosition(async ({ coords }) => { const radius = Math.min(Math.max(Math.round(coords.accuracy), 25), 250); const url = `https://api.danadresse.dk/adgangsadresser?cirkel=${coords.longitude},${coords.latitude},${radius}&struktur=mini&per_side=5`; const res = await fetch(url, { headers: { "X-Api-Key": API_KEY } }); const forslag = await res.json(); visForslag(forslag.map((a) => ({ id: a.id, tekst: a.betegnelse }))); }, (fejl) => console.warn(fejl.message), { enableHighAccuracy: true, timeout: 10000 });
The browser asks the user for permission. If the user says no, or it takes too long, fall back to a normal address field with autocomplete.
Edge cases
- At sea or abroad. If the point is far from any Danish address, reverse gives
404and the circle gives an empty list. - Large plots. The address point sits at the entrance or the road. On a farm or an industrial site the user can be several hundred metres from the point and still be at the right address.
- Missing parameters. Both
xandyare required. If one is missing the API answers400withinvalid_query_parameter. - Precision in the response. Coordinates in the response have eight decimals, as in DAWA. To calculate distances in metres without converting, use
srid=25832. Anysridother than 4326 and 25832 gives400.
Next steps
Related guides
Markdown source Spotted an error? Tell us API-reference (Swagger)