Not every hut has an ele tag. With elevation=1 every result gets the height of the terrain at its position, so you can sort, filter or colour huts by altitude without gaps.
This query lists the staffed mountain huts in the canton of Valais.
The query
[out:json][timeout:60]; area["ISO3166-2"="CH-VS"]->.valais; nwr["tourism"="alpine_hut"](area.valais); out center;
Run it
Live result from overpass.ch, cached for up to 12 hours. Map data © OpenStreetMap contributors (ODbL). Heights produced using Copernicus WorldDEM™-90 © DLR e.V. 2010-2014 and © Airbus Defence and Space GmbH 2014-2018 provided under COPERNICUS by the European Union and ESA; all rights reserved. Sea depths: GEBCO Compilation Group (2026) GEBCO 2026 Grid.
How it works
area["ISO3166-2"="CH-VS"]is the canton of Valais, by its ISO 3166-2 code. Unlike the name, the code is unambiguous.out center;gives one point per hut, also for huts mapped as a building. Withelevation=1, thecentergets theelevationfield.- Huts stand on slopes and saddles rather than on sharp tops, so the model agrees with
eleto within about 10 m in the median. - The exception is the highest one: the Capanna Regina Margherita stands on the summit of the Signalkuppe at 4,554 m, where the model reads about 60 m low.
Variations
- Nodes carry the height directly, ways and relations in their centre:
h = el.get("elevation") or el["center"]["elevation"]. - Unstaffed shelters too:
nwr["tourism"~"^(alpine_hut|wilderness_hut)$"], as in mountain huts.
Run it from your code
The query is unchanged; elevation=1 in the URL adds the heights. Each height uses one lookup from your elevation allowance.
curl 'https://api.overpass.ch/v1/YOUR_API_KEY/interpreter?elevation=1' \
--data-urlencode 'data@query.overpassql'
import requests
query = open("query.overpassql").read()
r = requests.post("https://api.overpass.ch/v1/YOUR_API_KEY/interpreter",
params={"elevation": 1}, data={"data": query}, timeout=120)
r.raise_for_status()
for el in r.json()["elements"]:
height = el.get("elevation") or el.get("center", {}).get("elevation")
print(el.get("tags", {}).get("name"), height)
const res = await fetch("https://api.overpass.ch/v1/YOUR_API_KEY/interpreter?elevation=1", {
method: "POST",
body: new URLSearchParams({ data: query }),
});
if (!res.ok) throw new Error(await res.text());
const { elements } = await res.json();
for (const el of elements) console.log(el.tags?.name, el.elevation ?? el.center?.elevation);
Save the query as query.overpassql. It works the same in Overpass Turbo, QGIS and JOSM.