You can write the haversine formula from memory or you can make one request. /distance takes two cities — or two raw coordinates — and gives you the great-circle distance both ways, in kilometres and miles.
Between two cities
Pass two GeoNames ids as from and to. You'll find ids on any city result or by searching /cities:
curl "https://countries.dev/distance?from=2988507&to=2643743"{
"from": { "name": "Paris", "countryCode": "FR", "latitude": 48.85341, "longitude": 2.3488 },
"to": { "name": "London", "countryCode": "GB", "latitude": 51.50853, "longitude": -0.12574 },
"distanceKm": 343.8,
"distanceMiles": 213.6
}Both endpoints of the trip come back in full, so you can render "Paris → London, 343.8 km" without a second lookup for the names.
Between two coordinates
Already have the points? Skip the city lookup and pass them directly as lat1, lng1, lat2, lng2:
curl "https://countries.dev/distance?lat1=48.8534&lng1=2.3488&lat2=51.5085&lng2=-0.1257"{
"from": { "latitude": 48.8534, "longitude": 2.3488 },
"to": { "latitude": 51.5085, "longitude": -0.1257 },
"distanceKm": 343.8,
"distanceMiles": 213.6
}Sorting things by how far away they are
Pair it with reverse geocoding to turn a user's coordinates into "how far is each store":
const here = { lat: 48.85, lng: 2.35 };
const withDistance = await Promise.all(
stores.map(async (s) => {
const { distanceKm } = await fetch(
`https://countries.dev/distance?lat1=${here.lat}&lng1=${here.lng}&lat2=${s.lat}&lng2=${s.lng}`,
).then((r) => r.json());
return { ...s, distanceKm };
}),
);
withDistance.sort((a, b) => a.distanceKm - b.distanceKm);This is the straight-line (as-the-crow-flies) distance, not driving distance — exactly what you want for "nearest branch", radius filters and rough travel estimates.
Written by
Dov Azencot
At
Thu Jun 25 2026