# Distance between two addresses

> Calculate the straight-line distance between two addresses with the distance endpoint, or work it out from the coordinates with haversine or UTM32.
>
> https://danadresse.dk/en/guides/afstand-mellem-adresser · verified 2026-11-02
A travel surcharge based on the distance to the customer, a delivery zone of 15 km from the warehouse, or the nearest shop to an address: they all start with the distance between two points.

The API has an endpoint that calculates the distance between two addresses. If you need many distances, it is faster to fetch the coordinates once and calculate yourself. Both give the straight-line distance. Neither takes roads, bridges or ferries into account.

## The distance endpoint

`GET /api/v1/enrich/distance?from={id}&to={id}` takes two access-address ids:

```bash id=distance-curl run=syntax
curl -s "https://api.danadresse.dk/api/v1/enrich/distance?from=0a3f507c-0624-32b8-e044-0003ba298018&to=0a3f507a-ec01-32b8-e044-0003ba298018" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
```

```json id=distance-svar run=no
{
  "from": { "id": "0a3f507c-0624-32b8-e044-0003ba298018", "vejnavn": "Strandvejen", "husnr": "100",
            "postnr": "2900", "lat": 55.7326, "lon": 12.5757 },
  "to":   { "id": "0a3f507a-ec01-32b8-e044-0003ba298018", "vejnavn": "Rådhuspladsen", "husnr": "1",
            "postnr": "1550", "lat": 55.6756, "lon": 12.5696 },
  "distance": { "km": 6.3496, "m": 6349.6, "miles": 3.9455 },
  "bearing": { "degrees": 183.45, "compass": "S" }
}
```

| Field | Content |
|---|---|
| `distance.km`, `distance.m`, `distance.miles` | The straight-line (great-circle) distance |
| `bearing.degrees` | The initial direction from `from` towards `to`, 0 = north, 90 = east |
| `bearing.compass` | The same as a 16-point compass direction, e.g. `S` or `NNE` |
| `from`, `to` | The two addresses with street name, house number, postcode and coordinates |

Errors to handle:

| Status | Code | Cause |
|---|---|---|
| `400` | `params_required` | `from` or `to` is missing |
| `404` | `not_found` | An id does not exist as an access address. `error.missing` lists which |
| `422` | `missing_coords` | One of the addresses has no coordinates |
| `403` | `sandbox_scope` / `browser_key_scope` | Test or browser key. Use a normal live key from the server |

The distance endpoint takes access-address ids only. An address id with floor and door gives `404`. Use `adgangsadresseid`, which you get from autocomplete, datavask or `GET /adresser/{id}`.

## Calculate it yourself: haversine

Once you have the coordinates, the distance is a formula. Haversine calculates the great-circle distance on a sphere and is precise enough for anything within Denmark. The example fetches two addresses in one call and calculates the distance locally:

```python id=haversine-python run=live expect="km"
import math
import os
import requests

def haversine_km(lat1, lon1, lat2, lon2):
    r = 6371.0088
    p1, p2 = math.radians(lat1), math.radians(lat2)
    dp, dl = p2 - p1, math.radians(lon2 - lon1)
    a = math.sin(dp / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dl / 2) ** 2
    return 2 * r * math.asin(math.sqrt(a))

ids = ["0a3f507c-0624-32b8-e044-0003ba298018", "0a3f507a-ec01-32b8-e044-0003ba298018"]
r = requests.get(
    "https://api.danadresse.dk/adgangsadresser",
    params={"id": "|".join(ids), "struktur": "mini"},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
r.raise_for_status()
punkt = {a["id"]: (a["y"], a["x"]) for a in r.json()}   # (lat, lon)
a, b = punkt[ids[0]], punkt[ids[1]]
print(f"{haversine_km(*a, *b):.2f} km")
```

## Calculate it yourself: UTM32 in metres

With `srid=25832` the coordinates are in metres on a flat grid. Within Denmark the distance is then just Pythagoras, and you do not have to convert degrees to metres. The WGS84 coordinates have eight decimals, so haversine and UTM32 agree to within a few centimetres. Use UTM32 when you want to calculate in metres directly:

```js id=utm-node run=live expect="km"
const ids = ["0a3f507c-0624-32b8-e044-0003ba298018", "0a3f507a-ec01-32b8-e044-0003ba298018"];
const url = new URL("https://api.danadresse.dk/adgangsadresser");
url.searchParams.set("id", ids.join("|"));
url.searchParams.set("struktur", "mini");
url.searchParams.set("srid", "25832");

const res = await fetch(url, { headers: { "X-Api-Key": process.env.DANADRESSE_API_KEY } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const punkt = Object.fromEntries((await res.json()).map((a) => [a.id, [a.x, a.y]]));
const [x1, y1] = punkt[ids[0]];
const [x2, y2] = punkt[ids[1]];
const meter = Math.hypot(x2 - x1, y2 - y1);
console.log(`${(meter / 1000).toFixed(3)} km (${Math.round(meter)} m)`);
```

## When to use which?

| Task | Use |
|---|---|
| One distance shown to a user | The distance endpoint. One call, direction included |
| Many distances, e.g. every customer against five warehouses | Fetch the coordinates once, store them and calculate locally |
| "Every address within X km" | `cirkel` on `/adgangsadresser` (see [Addresses in a radius or a polygon](/en/guides/adresser-i-radius-og-polygon)) |
| Distance from a GPS position | Use haversine from the position to the address coordinates (see [Find the address from a GPS position](/en/guides/reverse-geokodning-gps)) |

If you store the access-address id and the coordinates on your customers, you can calculate every distance without calling the API again.

## Edge cases

- **Straight line is shorter than the road.** The driving distance is always longer, and across water or along a fjord the difference can be large.
- **Same building.** Two flats on the same staircase share an access address and have distance 0.
- **Large plots.** The address point is at the entrance. On a farm or an industrial site the buildings can be some way from the point.

## Next steps

- [Addresses in a radius or a polygon](/en/guides/adresser-i-radius-og-polygon)
- [Coordinates and srid 4326/25832](/en/guides/koordinater-srid)
