{"openapi":"3.1.0","info":{"title":"Running Cat Geo API","version":"1","description":"Base URL https://geo.runningcat.dev. Send your key as `Authorization: Bearer <key>` or `x-api-key: <key>`; keys come from https://geo.runningcat.dev/account. Coordinates are [lon, lat] in degrees (WGS 84), times ISO 8601 in UTC, distances in km or m as the field name says. Errors answer `{\"error\": \"...\", \"reason\": \"...\"}` with the status codes listed per operation.\n\nAn answer with an error status (4xx or 5xx) costs nothing and does not count against the plan. Every answer says what it cost and what is left: `X-Request-Cost`, `X-RateLimit-Limit` and `X-RateLimit-Remaining` (per minute), `X-RateLimit-Day-Limit` and `X-RateLimit-Day-Remaining`.\n\nCredits to show: map data © OpenStreetMap contributors (ODbL); weather and air quality from Open-Meteo.com (CC BY 4.0); terrain from Mapterhorn; air quality stations and river gauges as each answer's `credits` or the data sources page lists.","termsOfService":"https://geo.runningcat.dev/terms"},"servers":[{"url":"https://geo.runningcat.dev"}],"security":[{"bearer":[]},{"apiKey":[]}],"tags":[{"name":"Reports","description":"Several answers about one point, area or route in one request."},{"name":"Places and time zones","description":"What lies at a point and what time it is there."},{"name":"Elevation and terrain","description":"Heights, profiles and terrain tiles."},{"name":"Map layers","description":"Protected areas, trails, pistes, lifts, boundaries and land cover."},{"name":"Weather","description":"Forecasts for a point, an area and a route on the way."},{"name":"Air quality","description":"Forecasts and what stations measure now."},{"name":"Rivers","description":"Water levels and discharge at river gauges."},{"name":"Routing","description":"Routes, loops and the surfaces of a route."},{"name":"Stops along a route","description":"Water, food, shops and more along a route."},{"name":"OpenStreetMap data","description":"Overpass QL and OSM features by tag."},{"name":"Service","description":"The state of the data."}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"},"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/v1/point":{"get":{"operationId":"getV1Point","tags":["Reports"],"summary":"Everything about a point","description":"Place, time zone, elevation, weather, air quality, air quality stations and river gauges at a point in one request. `include` picks the parts (comma-separated: place, timezone, elevation, weather, air, airStations, rivers; all by default). A part that fails comes back in `errors` with the reason; the others still answer.\n\nCost: One request whatever the parts.","parameters":[{"name":"lon","in":"query","required":true,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":6.1432},{"name":"lat","in":"query","required":true,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":46.2044},{"name":"include","in":"query","required":false,"description":"Comma-separated parts: place, timezone, elevation, weather, air, airStations, rivers","schema":{"type":"string"},"example":"place,timezone,elevation"},{"name":"lang","in":"query","required":false,"description":"Language of place names, e.g. en, de, pl; local names when absent","schema":{"type":"string"},"example":"en"},{"name":"days","in":"query","required":false,"description":"Forecast days, 1 to 14 (default 2)","schema":{"type":"integer"}},{"name":"hours","in":"query","required":false,"description":"Air quality hours, 1 to 120 (default 24)","schema":{"type":"integer"}},{"name":"pastHours","in":"query","required":false,"description":"Past hours of the air quality model before the current hour, 0 to 48 (default 0)","schema":{"type":"integer"}},{"name":"radiusKm","in":"query","required":false,"description":"Search radius for stations and gauges, 1 to 100 km (default 10)","schema":{"type":"number"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"lon":6.1432,"lat":46.2044,"place":{"lon":6.1432,"lat":46.2044,"country":{"code":"CH","name":"Switzerland"},"region":{"name":"Geneva","code":"CH-GE"},"locality":{"name":"Geneva","type":"city","distanceKm":0.39},"nearestPlace":{"name":"Saint-Gervais","type":"neighbourhood","distanceKm":0.26},"areas":[{"level":2,"name":"Switzerland","code":"CH"},{"level":4,"name":"Geneva","code":"CH-GE"},{"level":8,"name":"Geneva"}],"timezone":{"tz":"Europe/Zurich","offsetMin":60}},"timezone":{"tz":"Europe/Zurich","offsetMin":60},"elevation":{"ele":374}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/area":{"get":{"operationId":"getV1Area","tags":["Reports"],"summary":"Everything over an area","description":"Weather and air quality grids, elevation, air quality stations, river gauges and map layers over a box. `include` picks the parts (weather, air, airStations, elevation, rivers, layers; all but layers by default). Grids have about `cells` cells (at most 400) listed from the north-west corner row by row, hourly from the current hour; cells × hours at most 9600. Stations, gauges and layers need a box of at most 16 square degrees.\n\nCost: One request per part; layers one per layer.","parameters":[{"name":"bbox","in":"query","required":true,"description":"west,south,east,north in degrees, at most 3600 square degrees","schema":{"type":"string"},"example":"6.0,46.1,6.3,46.3"},{"name":"include","in":"query","required":false,"description":"Comma-separated parts: weather, air, airStations, elevation, rivers, layers","schema":{"type":"string"},"example":"weather,elevation"},{"name":"cells","in":"query","required":false,"description":"Grid cells, 1 to 400 (default 100)","schema":{"type":"integer"},"example":4},{"name":"hours","in":"query","required":false,"description":"Hours, 1 to 120 (default 24)","schema":{"type":"integer"},"example":2},{"name":"layers","in":"query","required":false,"description":"Comma-separated layers: protected_area, route, piste, aerialway, boundary (default protected_area, route, piste, aerialway)","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"bbox":[6,46.1,6.3,46.3],"rows":2,"cols":2,"lon":[6.075,6.225],"lat":[46.25,46.15],"weather":{"times":["2026-11-12T12:00:00Z","2026-11-12T13:00:00Z"],"values":{"temperatureC":[[11.6,12.3,12.2,12],[11.8,12.3,12.3,12.2]],"feelsLikeC":[[10.4,11.4,10.9,11.5],[10.1,11,11.1,11.6]],"precipitationMm":[[0.8,0.9,1,1.1],[0.2,0.4,0.4,0.7]],"weatherCode":[[61,61,61,61],[61,61,61,61]],"windKmh":[[9.4,9.2,11.7,6.6],[12.8,12.1,12,8.4]],"windDirDeg":[[40,21,34,351],[38,27,33,10]],"gustKmh":[[16.2,18.4,22.3,16.6],[24.8,20.9,24.1,19.8]],"cloudPct":[[100,100,100,100],[100,100,100,100]],"humidityPct":[[94,94,95,98],[91,94,95,99]],"pressureHpa":[[992.9,992.9,992.9,993.1],[992,992.1,992.1,992.2]],"boundaryLayerM":[[205,185,210,145],[230,180,185,120]]}},"elevation":{"values":[453.2,435,424.3,526.6]}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/report":{"post":{"operationId":"postV1RouteReport","tags":["Reports"],"summary":"Everything along a route","description":"Elevation profile, weather at the time you reach each point, time zones, air quality stations, river gauges, map layers, surfaces and land cover along a route in one request. `include` picks the parts (profile, weather, timezones, airStations, rivers, layers, surfaces, landcover; by default profile, weather, timezones, airStations, rivers, layers); the other fields are those of the single endpoints below. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request per part.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"include":{"minItems":1,"type":"array","items":{"type":"string","enum":["profile","weather","timezones","airStations","rivers","layers","surfaces","landcover"]}},"departure":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"speedKmh":{"type":"number","minimum":2,"maximum":80},"stepKm":{"type":"number","minimum":0.5,"maximum":100},"stepM":{"type":"number","minimum":10,"maximum":1000},"layers":{"minItems":1,"type":"array","items":{"type":"string","enum":["protected_area","route","piste","aerialway","boundary"]}},"bufferM":{"type":"number","minimum":0,"maximum":1000},"bufferKm":{"type":"number","minimum":0.1,"maximum":20},"lang":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Za-z]{2,4})?$"}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]},"include":["profile","timezones","surfaces","landcover"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"profile":{"routeLengthKm":7.567,"stepM":10,"ascentM":814,"descentM":109,"minM":374,"maxM":1093.7,"structures":[{"fromKm":0.139,"toKm":0.178,"kind":"tunnel","name":"Passage de la Petite-Corraterie","maxheight":null,"maxheightM":null},{"fromKm":1.05,"toKm":1.07,"kind":"tunnel","name":null,"maxheight":"default","maxheightM":null},{"fromKm":3.89,"toKm":3.91,"kind":"bridge","name":null,"maxheight":null,"maxheightM":null}],"profile":[{"km":0,"lon":6.1432,"lat":46.2044,"ele":374},{"km":0.01,"lon":6.14324,"lat":46.204315,"ele":374.4},{"km":0.02,"lon":6.143281,"lat":46.204229,"ele":374.5}]},"timezones":{"at":"2026-11-12T12:35:36.495Z","routeLengthKm":7.6,"timezones":[{"tz":"Europe/Zurich","fromKm":0,"toKm":5.6,"offsetMin":60},{"tz":"Europe/Paris","fromKm":5.6,"toKm":7.6,"offsetMin":60}]},"surfaces":{"km":{"paved":2.76,"unpaved":0.32,"unknown":4.49},"highwayKm":{"none":1.95,"footway":1.53,"service":1.25,"path":0.7,"residential":0.54,"tertiary":0.44,"track":0.32,"cycleway":0.2,"living_street":0.18,"unclassified":0.16,"pedestrian":0.14,"secondary":0.06,"primary":0.04,"motorway":0.04,"secondary_link":0.02,"platform":0.02},"runs":[{"fromKm":0,"toKm":0.02,"surface":"asphalt","highway":"residential","tracktype":null,"smoothness":null},{"fromKm":0.02,"toKm":0.04,"surface":"unknown","highway":"cycleway","tracktype":null,"smoothness":null},{"fromKm":0.04,"toKm":0.059,"surface":"asphalt","highway":"pedestrian","tracktype":null,"smoothness":"good"}],"heightLimits":[]},"landcover":{"routeLengthKm":7.57,"stepM":50,"km":{"built":3.1,"park":1.7,"forest":1.07,"grassland":0.85,"unmapped":0.65,"farmland":0.15,"water":0.05},"runs":[{"fromKm":0,"toKm":0.25,"class":"built"},{"fromKm":0.25,"toKm":0.3,"class":"park"},{"fromKm":0.3,"toKm":0.35,"class":"built"}]}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/where":{"get":{"operationId":"getV1Where","tags":["Places and time zones"],"summary":"Where a point is","description":"Country, region, locality, the nearest named place, protected areas and the time zone at a point.\n\nCost: One request.","parameters":[{"name":"lon","in":"query","required":true,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":6.1432},{"name":"lat","in":"query","required":true,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":46.2044},{"name":"lang","in":"query","required":false,"description":"Language of place names, e.g. en, de, pl; local names when absent","schema":{"type":"string"},"example":"en"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"lon":6.1432,"lat":46.2044,"country":{"code":"CH","name":"Switzerland"},"region":{"name":"Geneva","code":"CH-GE"},"locality":{"name":"Geneva","type":"city","distanceKm":0.39},"nearestPlace":{"name":"Saint-Gervais","type":"neighbourhood","distanceKm":0.26},"areas":[{"level":2,"name":"Switzerland","code":"CH"},{"level":4,"name":"Geneva","code":"CH-GE"},{"level":8,"name":"Geneva"}],"timezone":{"tz":"Europe/Zurich","offsetMin":60}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}},"post":{"operationId":"postV1Where","tags":["Places and time zones"],"summary":"Where many points are","description":"The same for up to 1000 points, in order. `at` (ISO time) sets the moment for the time zone offsets; now by default.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"points":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}},"lang":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Za-z]{2,4})?$"},"at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["points"]},"example":{"points":[[6.1432,46.2044],[19.94,50.06]],"lang":"en"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"places":[{"lon":6.1432,"lat":46.2044,"country":{"code":"CH","name":"Switzerland"},"region":{"name":"Geneva","code":"CH-GE"},"locality":{"name":"Geneva","type":"city","distanceKm":0.39},"nearestPlace":{"name":"Saint-Gervais","type":"neighbourhood","distanceKm":0.26},"areas":[{"level":2,"name":"Switzerland","code":"CH"},{"level":4,"name":"Geneva","code":"CH-GE"},{"level":8,"name":"Geneva"}],"timezone":{"tz":"Europe/Zurich","offsetMin":60}},{"lon":19.94,"lat":50.06,"country":{"code":"PL","name":"Poland"},"region":{"name":"Lesser Poland Voivodeship","code":"PL-12"},"locality":{"name":"Krakow","type":"city","distanceKm":0.31},"nearestPlace":{"name":"Krakow","type":"city","distanceKm":0.31},"areas":[{"level":2,"name":"Poland","code":"PL"},{"level":4,"name":"Lesser Poland Voivodeship","code":"PL-12"},{"level":6,"name":"Krakow"}],"timezone":{"tz":"Europe/Warsaw","offsetMin":60}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/timezones":{"post":{"operationId":"postV1Timezones","tags":["Places and time zones"],"summary":"Time zones of points","description":"IANA time zone and its offset in minutes east of UTC for up to 10,000 points, at `at` (now by default).\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"points":{"minItems":1,"maxItems":10000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}},"at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["points"]},"example":{"points":[[6.1432,46.2044],[-73.98,40.75]]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"timezones":[{"tz":"Europe/Zurich","offsetMin":60},{"tz":"America/New_York","offsetMin":-300}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/timezones":{"post":{"operationId":"postV1RouteTimezones","tags":["Places and time zones"],"summary":"Time zones along a route","description":"The stretches of a route in each time zone, with their offsets at `at`. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"routeLengthKm":7.6,"at":"2026-11-12T12:35:38.786Z","timezones":[{"tz":"Europe/Zurich","fromKm":0,"toKm":5.6,"offsetMin":60},{"tz":"Europe/Paris","fromKm":5.6,"toKm":7.6,"offsetMin":60}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/places/search":{"post":{"operationId":"postV1PlacesSearch","tags":["Places and time zones"],"summary":"Find places by name","description":"Villages, towns, cities and other named places matching a query: exact names first, then names starting with the query, larger and more populous first. Each name comes as \"Place, Region, Country\", in `locale` where the place has it. Place names only, no street addresses.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","minLength":2,"maxLength":120},"limit":{"default":6,"type":"integer","minimum":1,"maximum":10},"locale":{"type":"string","pattern":"^[a-z]{2}$"}},"required":["query"]},"example":{"query":"Chamonix","limit":2,"locale":"en"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"places":[{"name":"Chamonix, Auvergne-Rhône-Alpes, France","lat":46.0295495,"lon":6.6117818},{"name":"Chamonix-Mont-Blanc, Auvergne-Rhône-Alpes, France","lat":45.9230969,"lon":6.8700009}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/elevation":{"get":{"operationId":"getV1Elevation","tags":["Elevation and terrain"],"summary":"Height of a point","description":"Height above sea level in metres (0.1 m steps); open sea is 0.\n\nCost: One request.","parameters":[{"name":"lon","in":"query","required":true,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":7.6586},{"name":"lat","in":"query","required":true,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":45.9763}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"ele":4449.1}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}},"post":{"operationId":"postV1Elevation","tags":["Elevation and terrain"],"summary":"Heights of points","description":"Heights of the ground for up to 10,000 points, in order; null where there is no terrain. Each point is read on its own, so a point in a tunnel gets the mountain above it and one on a bridge the valley below; for a route or a recorded track use `POST /v1/route/profile` (with `at: \"points\"` to keep its own points), which follows the road there.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"points":{"minItems":1,"maxItems":10000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["points"]},"example":{"points":[[7.6586,45.9763],[6.1432,46.2044]]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"elevations":[4449.1,374]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/profile":{"post":{"operationId":"postV1RouteProfile","tags":["Elevation and terrain"],"summary":"Elevation profile of a route","description":"Heights every `stepM` metres (10 to 1000; chosen by length when absent), with climb, descent, lowest and highest point. A profile has at most 5,000 samples, so on a long route the step grows past the one asked for (10 m holds up to about 50 km, 20 m up to 100 km); the answer's `stepM` is the step used. `at: \"points\"` gives a height at each point of the route as sent instead, for recorded tracks: no resampling, distances stay the track's, up to 50,000 points (more answers 413), `stepM` null in the answer. On bridges and in tunnels (OSM `bridge` and `tunnel` ways the route runs along) the heights follow the road: a straight line between the heights just beyond each end, not the valley under a bridge or the mountain over a tunnel. A recorded track whose points stray from a tunnel or bridge where GPS was lost still counts as on it within 80 m, as long as no other road is nearer than 25 m. `structures` lists those stretches (`fromKm`, `toKm`, `kind` bridge or tunnel, `name`, and the clearance: `maxheight` as tagged in OSM, `maxheightM` in metres when it is a number, null when untagged; `default` means no sign and room for the country's general limit, `below_default` no sign and less room than that); it is null when they could not be looked up and the heights are the terrain's. `heights: \"terrain\"` gives the ground under every point instead. For a recorded track send it here with `at: \"points\"` rather than to `POST /v1/elevation`, which reads each point on its own and so cannot follow a road through a tunnel. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"stepM":{"type":"number","minimum":10,"maximum":1000},"at":{"description":"step (default): heights every stepM metres along the line; points: a height at each point of the route as sent (a recorded track), up to 50,000 points, stepM ignored","type":"string","enum":["step","points"]},"heights":{"description":"road (default): on bridges and in tunnels the heights follow the road, a straight line between the heights at their ends; terrain: the ground under every point, valleys under bridges and mountains over tunnels included","type":"string","enum":["road","terrain"]}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]},"stepM":500}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"routeLengthKm":7.567,"stepM":500,"ascentM":733,"descentM":31,"minM":375.1,"maxM":1090.8,"structures":[{"fromKm":0.139,"toKm":0.178,"kind":"tunnel","name":"Passage de la Petite-Corraterie","maxheight":null,"maxheightM":null},{"fromKm":1.05,"toKm":1.07,"kind":"tunnel","name":null,"maxheight":"default","maxheightM":null},{"fromKm":3.89,"toKm":3.91,"kind":"bridge","name":null,"maxheight":null,"maxheightM":null}],"profile":[{"km":0,"lon":6.1432,"lat":46.2044,"ele":375.1},{"km":0.5,"lon":6.145218,"lat":46.200126,"ele":383.6},{"km":1,"lon":6.147237,"lat":46.195852,"ele":385.8}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/dem/{z}/{x}/{y}.png":{"get":{"operationId":"getV1DemByZByXByYPng","tags":["Elevation and terrain"],"summary":"Terrain tiles (Terrarium)","description":"Terrain tiles for hillshading, 3D terrain and contours, in Terrarium encoding: height in metres = R × 256 + G + B / 256 − 32768. `{y}.png` is 256 px, zoom 0 to 13; `{y}.webp` is 512 px lossless, zoom 0 to 12. All land is covered; there is no zoom 14, so a contour layer drawn at 14 sets maxzoom 13 on its source. 404 where there is no tile. Credit: terrain from Mapterhorn.\n\nCost: One request per 50 tiles.","parameters":[{"name":"z","in":"path","required":true,"description":"Zoom","schema":{"type":"integer"},"example":12},{"name":"x","in":"path","required":true,"description":"Tile column","schema":{"type":"integer"},"example":2117},{"name":"y","in":"path","required":true,"description":"Tile row","schema":{"type":"integer"},"example":1446}],"responses":{"200":{"description":"OK","content":{"image/png or image/webp":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/layers/{layer}":{"get":{"operationId":"getV1LayersByLayer","tags":["Map layers"],"summary":"A map layer in a box","description":"Protected areas, hiking and cycling routes, ski pistes, lifts or administrative boundaries in a box, as a GeoJSON FeatureCollection with OSM tags; `truncated` is true when `limit` cut it. Layers: protected_area, route, piste, aerialway, boundary. `kinds` narrows a layer (route: hiking, bicycle, mtb, ...; boundary: admin levels such as 2, 4).\n\nCost: One request.","parameters":[{"name":"layer","in":"path","required":true,"description":"protected_area, route, piste, aerialway, boundary","schema":{"type":"string"},"example":"protected_area"},{"name":"bbox","in":"query","required":true,"description":"west,south,east,north in degrees, at most 16 square degrees","schema":{"type":"string"},"example":"6.0,46.1,6.3,46.3"},{"name":"kinds","in":"query","required":false,"description":"Comma-separated kinds within the layer","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Features, 1 to 5000 (default 2000)","schema":{"type":"integer"},"example":2},{"name":"lang","in":"query","required":false,"description":"Language of place names, e.g. en, de, pl; local names when absent","schema":{"type":"string"},"example":"en"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"type":"FeatureCollection","truncated":true,"features":[{"type":"Feature","id":"R5555535","properties":{"layer":"protected_area","kind":"protected_area","name":"Parc naturel régional du Haut-Jura","tags":{"name":"Parc naturel régional du Haut-Jura","name:br":"Park natur rannvroel ar Jura-Uhel","name:de":"Regionaler Naturpark Hochjura","name:en":"Jura Mountains Regional Natural Park","name:fr":"Parc naturel régional du Haut-Jura","website":"https://www.parc-haut-jura.fr/","boundary":"protected_area","wikidata":"Q3364633","wikipedia":"fr:Parc naturel régional du Haut-Jura","iucn_level":"5","protect_class":"5","protection_title":"parc naturel régional"}},"geometry":{"type":"Polygon","coordinates":[[[6.065334,46.3],[6.064507,46.298717],[6.063409,46.297955]]]}},{"type":"Feature","id":"R14980670","properties":{"layer":"protected_area","kind":"protected_area","name":"Réserve naturelle de la haute chaîne du Jura","tags":{"name":"Réserve naturelle de la haute chaîne du Jura","access":"restricted","leisure":"nature_reserve","name:it":"Riserva naturale dell'Alta Catena del Giura","website":"https://www.rnn-hautechainedujura.fr/","boundary":"protected_area","wikidata":"Q3457394","wikipedia":"fr:Réserve naturelle nationale de la haute chaîne du Jura","protect_class":"4","protection_title":"Réserve naturelle nationale"}},"geometry":{"type":"Polygon","coordinates":[[[6.00879,46.3],[6.007759,46.298401],[6.00648,46.297266]]]}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/layers/landcover":{"get":{"operationId":"getV1LayersLandcover","tags":["Map layers"],"summary":"Land cover in a box","description":"What the ground is, from OpenStreetMap areas: forest, scrub, grassland, farmland, wetland, water, glacier, bare, park, built (`kind`). A GeoJSON FeatureCollection, largest areas first, clipped to the box; the box is at most 0.1 square degrees because forests and fields come by the thousand. `kinds` keeps some classes.\n\nCost: One request.","parameters":[{"name":"bbox","in":"query","required":true,"description":"west,south,east,north, at most 0.1 square degrees","schema":{"type":"string"},"example":"6.10,46.15,6.30,46.30"},{"name":"kinds","in":"query","required":false,"description":"Comma-separated classes: forest, scrub, grassland, farmland, wetland, water, glacier, bare, park, built","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Features, 1 to 5000 (default 2000)","schema":{"type":"integer"},"example":2}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"type":"FeatureCollection","truncated":true,"features":[{"type":"Feature","id":"R332617","properties":{"layer":"landcover","kind":"water","name":"Le Léman","tags":{"ele":"372","boat":"yes","name":"Le Léman","salt":"no","tidal":"no","water":"lake","name:ca":"Llac Léman","name:cs":"Ženevské jezero","name:da":"Lemansøen","name:de":"Genfersee","name:en":"Lake Geneva","name:es":"Lago Lemán","name:et":"Genfi järv","name:fr":"Le Léman","name:he":"אגם ז'נבה","name:hr":"Ženevsko jezero","name:hu":"Genfi-tó","name:is":"Genfarvatn","name:it":"Lago Lemano","name:ja":"レマン湖","name:lb":"Genferséia","name:nl":"Meer van Genève","name:pl":"Jezioro Genewskie","name:ru":"Женевское озеро","name:sk":"Ženevské jazero","name:sl":"Ženevsko jezero","name:sr":"Женевско језеро","name:tt":"Женева күле","name:uk":"Женевське озеро","natural":"water","alt_name":"Lac Léman;Lac de Genève","name:frp":"Lèman","swimming":"yes","wikidata":"Q6403","ref:gwlnr":"CH0097570000","wikipedia":"fr:Léman","ref:gewiss":"9757","short_name":"Léman","alt_name:da":"Genevesøen","alt_name:de":"Genfer See","alt_name:en":"Lake Leman","alt_name:es":"Lago de Ginebra","alt_name:et":"Leman järv","alt_name:fr":"Lac Léman;Lac de Genève","alt_name:hr":"Lemansko jezero","alt_name:hu":"Leman-tó","alt_name:it":"Lago di Ginevra","alt_name:lb":"Lemanerséi","alt_name:sr":"Леманско језеро","intermittent":"no","name:sr-Latn":"Ženevsko jezero","name:language":"fr","ref:CH:hls-dhs":"008657","alt_name:sr-Latn":"Lemansko jezero","wikimedia_commons":"Category:Lake Geneva","ref:CH:bafu.vec25-seen":"24"}},"geometry":{"type":"Polygon","coordinates":[[[6.24206,46.3],[6.242094,46.299805],[6.2423,46.299805]],[[6.153364,46.210418],[6.153634,46.210504],[6.153989,46.210318]],[[6.154307,46.205679],[6.154317,46.205603],[6.154342,46.205678]]]}},{"type":"Feature","id":"R1247524","properties":{"layer":"landcover","kind":"built","name":null,"tags":{"landuse":"residential"}},"geometry":{"type":"Polygon","coordinates":[[[6.12724,46.200587],[6.127121,46.200456],[6.128454,46.200008]],[[6.179778,46.182497],[6.179899,46.18257],[6.180054,46.182308]],[[6.179839,46.18263],[6.180187,46.183992],[6.180947,46.185019]]]}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/landcover":{"post":{"operationId":"postV1RouteLandcover","tags":["Map layers"],"summary":"Land cover along a route","description":"What the ground is along a route, every 50 m (coarser over 250 km): kilometres per class and the stretches of each, in route order. A point takes the class of the smallest area it lies in (a wood inside a park is forest); `unmapped` where OpenStreetMap maps no area (often roads, villages and fields nobody drew). A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"routeLengthKm":7.57,"stepM":50,"km":{"built":3.1,"park":1.7,"forest":1.07,"grassland":0.85,"unmapped":0.65,"farmland":0.15,"water":0.05},"runs":[{"fromKm":0,"toKm":0.25,"class":"built"},{"fromKm":0.25,"toKm":0.3,"class":"park"},{"fromKm":0.3,"toKm":0.35,"class":"built"}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/layers":{"post":{"operationId":"postV1RouteLayers","tags":["Map layers"],"summary":"Map layers along a route","description":"The layer features a route runs through or within `bufferM` (0 to 1000, default 30) of, with the stretches of the route inside each. Layers protected_area, route, piste, aerialway by default. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"layers":{"minItems":1,"type":"array","items":{"type":"string","enum":["protected_area","route","piste","aerialway","boundary"]}},"bufferM":{"type":"number","minimum":0,"maximum":1000},"lang":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Za-z]{2,4})?$"}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"routeLengthKm":7.57,"stepM":50,"bufferM":30,"features":[{"layer":"route","id":"R11063902","kind":"hiking","name":"ViaJacobi","tags":{"to":"Genève (frontière)","ref":"4","from":"Genève","name":"ViaJacobi","route":"hiking","network":"nwn","distance":"9","operator":"Wanderland Schweiz","osmc:symbol":"green:green::4:white"},"stretches":[{"fromKm":0,"toKm":0.2},{"fromKm":0.75,"toKm":0.75}],"km":0.2},{"layer":"route","id":"R1307899","kind":"bicycle","name":"Cyclévasion Genève-Salève","tags":{"to":"Pas-de-l'Échelle","ref":"104","from":"Genève","name":"Cyclévasion Genève-Salève","route":"bicycle","name:fr":"Cyclévasion Genève-Salève","network":"lcn","distance":"7","operator":"Etat de Genève et Ville de Genève"},"stretches":[{"fromKm":0,"toKm":0},{"fromKm":0.5,"toKm":0.6}],"km":0.1},{"layer":"route","id":"R1230605","kind":"hiking","name":"Eaux d'Arve - Pinchat","tags":{"name":"Eaux d'Arve - Pinchat","route":"hiking","network":"lwn","osmc:symbol":"yellow::yellow_diamond"},"stretches":[{"fromKm":2.95,"toKm":3}],"km":0.05}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/weather":{"get":{"operationId":"getV1Weather","tags":["Weather"],"summary":"Forecast for a point","description":"Current conditions, hourly and daily forecast for up to 14 days (default 7), corrected to the height of the point; the local time zone comes along. Hours carry temperature, feels-like, precipitation, weather code, wind, gusts, cloud cover, humidity, sea-level pressure (`pressureHpa`) and the height of the boundary layer (`boundaryLayerM`, from the global GFS model everywhere, about 13 km cells). Units: °C, mm, km/h, degrees, percent, hPa, m; times in UTC.\n\nCost: One request.","parameters":[{"name":"lon","in":"query","required":true,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":6.1432},{"name":"lat","in":"query","required":true,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":46.2044},{"name":"days","in":"query","required":false,"description":"1 to 14 (default 7)","schema":{"type":"integer"},"example":2}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"lon":6.1432,"lat":46.2044,"elevationM":374,"current":{"time":"2026-11-12T12:30:00Z","temperatureC":12.7,"feelsLikeC":11.7,"precipitationMm":0.1,"weatherCode":61,"windKmh":9.8,"windDirDeg":36,"gustKmh":23,"cloudPct":100,"humidityPct":93,"pressureHpa":992.5,"boundaryLayerM":205,"isDay":true},"hourly":[{"time":"2026-11-11T23:00:00Z","temperatureC":10.1,"feelsLikeC":9.7,"precipitationMm":0,"weatherCode":3,"windKmh":2.6,"windDirDeg":164,"gustKmh":5.4,"cloudPct":100,"humidityPct":97,"pressureHpa":1002.4,"boundaryLayerM":10,"isDay":false},{"time":"2026-11-12T00:00:00Z","temperatureC":9.9,"feelsLikeC":9.3,"precipitationMm":0,"weatherCode":3,"windKmh":2.9,"windDirDeg":150,"gustKmh":4.3,"cloudPct":100,"humidityPct":97,"pressureHpa":1001.7,"boundaryLayerM":10,"isDay":false},{"time":"2026-11-12T01:00:00Z","temperatureC":10.2,"feelsLikeC":9.8,"precipitationMm":0,"weatherCode":3,"windKmh":1.6,"windDirDeg":117,"gustKmh":5.4,"cloudPct":100,"humidityPct":95,"pressureHpa":1000.8,"boundaryLayerM":10,"isDay":false}],"daily":[{"date":"2026-11-12","minC":9.9,"maxC":12.7,"precipitationMm":15.7,"windMaxKmh":10.8,"gustMaxKmh":23,"weatherCode":61,"sunrise":"2026-11-12T06:32:07Z","sunset":"2026-11-12T16:06:42Z"},{"date":"2026-11-13","minC":3.9,"maxC":11.5,"precipitationMm":1.3,"windMaxKmh":25.2,"gustMaxKmh":57.2,"weatherCode":61,"sunrise":"2026-11-13T06:33:33Z","sunset":"2026-11-13T16:05:32Z"}],"timezone":{"tz":"Europe/Zurich","offsetMin":60}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/weather/area":{"get":{"operationId":"getV1WeatherArea","tags":["Weather"],"summary":"Forecast grid over an area","description":"Forecast on a grid of about `cells` cells (at most 400), listed from the north-west corner row by row: `values.<name>[step][cell]`, with `times` for the steps. `hours` steps come back, `stepHours` apart, from `pastHours` before the current hour. cells × steps at most 9600. Keys given the bulk_grid permission (on request) may ask for up to 20,000 cells and 250,000 values; such grids are built one at a time behind other requests, so they take longer.\n\nCost: One request.","parameters":[{"name":"bbox","in":"query","required":true,"description":"west,south,east,north in degrees, at most 3600 square degrees","schema":{"type":"string"},"example":"6.0,46.1,6.3,46.3"},{"name":"cells","in":"query","required":false,"description":"1 to 400 (default 100)","schema":{"type":"integer"},"example":4},{"name":"stepDeg","in":"query","required":false,"description":"Instead of cells: a lattice with cell centres at west + k·stepDeg and north − k·stepDeg, 0.01 to 10 degrees, so the cells can sit on a model's own nodes (CAMS Europe: every 0.1° at x.x5°, CAMS Global: every 0.4°)","schema":{"type":"number"}},{"name":"hours","in":"query","required":false,"description":"How many steps come back, 1 to 120 (default 24)","schema":{"type":"integer"},"example":2},{"name":"stepHours","in":"query","required":false,"description":"Hours between two steps, 1 to 6 (default 1)","schema":{"type":"integer"}},{"name":"pastHours","in":"query","required":false,"description":"Start this many hours before the current hour, 0 to 48 (default 0); the window may span up to 168 hours","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"bbox":[6,46.1,6.3,46.3],"rows":2,"cols":2,"lon":[6.075,6.225],"lat":[46.25,46.15],"times":["2026-11-12T12:00:00Z","2026-11-12T15:00:00Z"],"values":{"temperatureC":[[11.6,12.3,12.2,12],[11.4,12.1,12.1,11.9]],"feelsLikeC":[[10.4,11.4,10.9,11.5],[10.5,10.9,11.1,10.9]],"precipitationMm":[[0.8,0.9,1,1.1],[1.2,1.1,1.1,1.4]],"weatherCode":[[61,61,61,61],[61,61,61,61]],"windKmh":[[9.4,9.2,11.7,6.6],[6.9,10.8,9.9,9.1]],"windDirDeg":[[40,21,34,351],[43,26,19,342]],"gustKmh":[[16.2,18.4,22.3,16.6],[19.4,21.2,19.1,19.8]],"cloudPct":[[100,100,100,100],[100,100,100,100]],"humidityPct":[[94,94,95,98],[93,94,96,96]],"pressureHpa":[[992.9,992.9,992.9,993.1],[991.7,991.5,991.7,991.7]],"boundaryLayerM":[[205,185,210,145],[200,120,130,100]]}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/weather/current":{"post":{"operationId":"postV1WeatherCurrent","tags":["Weather"],"summary":"Current weather at many points","description":"Current conditions at up to 2,000 points in one request, in order (for example a wind field for a map): the same fields as `current` in `/v1/weather`, the boundary layer height included. Over 400 points the request waits its turn behind other large requests.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"points":{"minItems":1,"maxItems":2000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["points"]},"example":{"points":[[6.1432,46.2044],[19.94,50.06]]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"points":[{"lon":6.1432,"lat":46.2044,"current":{"time":"2026-11-12T12:30:00Z","temperatureC":12.7,"feelsLikeC":11.7,"precipitationMm":0.1,"weatherCode":61,"windKmh":9.8,"windDirDeg":36,"gustKmh":23,"cloudPct":100,"humidityPct":93,"pressureHpa":992.5,"boundaryLayerM":205,"isDay":true}},{"lon":19.94,"lat":50.06,"current":{"time":"2026-11-12T12:30:00Z","temperatureC":8,"feelsLikeC":7,"precipitationMm":0,"weatherCode":2,"windKmh":1.1,"windDirDeg":162,"gustKmh":4.7,"cloudPct":80,"humidityPct":89,"pressureHpa":997.8,"boundaryLayerM":585,"isDay":true}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/weather":{"post":{"operationId":"postV1RouteWeather","tags":["Weather"],"summary":"Weather along a route on the way","description":"The forecast at points along the route for the time you reach each of them, leaving at `departure` (now by default) at `speedKmh` (default 20), every `stepKm`; a summary gives the coldest and warmest, the wettest hour, the strongest headwind and gust. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"departure":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"speedKmh":{"type":"number","minimum":2,"maximum":80},"stepKm":{"type":"number","minimum":0.5,"maximum":100}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]},"speedKmh":18}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"routeLengthKm":7.6,"departure":"2026-11-12T12:35:43.550Z","arrival":"2026-11-12T13:00:57.025Z","speedKmh":18,"summary":{"minTemperatureC":8.4,"maxTemperatureC":12.7,"maxPrecipitationMm":0.7,"maxHeadwindKmh":-3.1,"maxGustKmh":27},"points":[{"km":0,"lon":6.1432,"lat":46.2044,"time":"2026-11-12T12:35:43.550Z","temperatureC":12.7,"feelsLikeC":11.7,"precipitationMm":0.4,"weatherCode":61,"windKmh":9.9,"windDirDeg":37,"gustKmh":21.1,"cloudPct":100,"humidityPct":92,"pressureHpa":992.1,"boundaryLayerM":230,"isDay":true,"headwindKmh":-3.3,"crosswindKmh":9.3},{"km":5,"lon":6.17818,"lat":46.16746,"time":"2026-11-12T12:52:23.550Z","temperatureC":12.2,"feelsLikeC":11.4,"precipitationMm":0.5,"weatherCode":61,"windKmh":8.8,"windDirDeg":31,"gustKmh":19.2,"cloudPct":100,"humidityPct":95,"pressureHpa":992.2,"boundaryLayerM":180,"isDay":true,"headwindKmh":-3.5,"crosswindKmh":8.1},{"km":7.6,"lon":6.2,"lat":46.15,"time":"2026-11-12T13:00:57.025Z","temperatureC":8.4,"feelsLikeC":6.3,"precipitationMm":0.7,"weatherCode":61,"windKmh":11.2,"windDirDeg":33,"gustKmh":27,"cloudPct":100,"humidityPct":100,"pressureHpa":992.3,"boundaryLayerM":120,"isDay":true,"headwindKmh":-3.1,"crosswindKmh":10.8}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/air":{"get":{"operationId":"getV1Air","tags":["Air quality"],"summary":"Air quality forecast for a point","description":"Current and hourly PM2.5, PM10, nitrogen dioxide, ozone, sulphur dioxide, carbon monoxide, dust, UV index, European and US AQI; in Europe also ammonia and pollen (alder, birch, grass, mugwort, olive, ragweed). µg/m³; pollen in grains/m³.\n\nCost: One request.","parameters":[{"name":"lon","in":"query","required":true,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":6.1432},{"name":"lat","in":"query","required":true,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":46.2044},{"name":"hours","in":"query","required":false,"description":"Hours from the current one, 1 to 120 (default 48)","schema":{"type":"integer"},"example":2},{"name":"pastHours","in":"query","required":false,"description":"Past hours of the model before the current hour, 0 to 48 (default 0): what the forecast said for the last hours, to set against what stations measured","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"lon":6.1432,"lat":46.2044,"current":{"time":"2026-11-12T12:00:00Z","pm25":3,"pm10":4.5,"nitrogenDioxide":9.5,"ozone":45,"sulphurDioxide":0.3,"carbonMonoxide":143,"ammonia":1.2,"dust":0,"uvIndex":0.5,"europeanAqi":19,"usAqi":38,"alderPollen":0,"birchPollen":0,"grassPollen":0,"mugwortPollen":0,"olivePollen":0,"ragweedPollen":0},"hourly":[{"time":"2026-11-12T12:00:00Z","pm25":3,"pm10":4.5,"nitrogenDioxide":9.5,"ozone":45,"sulphurDioxide":0.3,"carbonMonoxide":143,"ammonia":1.2,"dust":0,"uvIndex":0.5,"europeanAqi":19,"usAqi":38,"alderPollen":0,"birchPollen":0,"grassPollen":0,"mugwortPollen":0,"olivePollen":0,"ragweedPollen":0},{"time":"2026-11-12T13:00:00Z","pm25":2.7,"pm10":4.3,"nitrogenDioxide":9.2,"ozone":48,"sulphurDioxide":0.3,"carbonMonoxide":140,"ammonia":1.2,"dust":0,"uvIndex":0.3,"europeanAqi":18,"usAqi":38,"alderPollen":0,"birchPollen":0,"grassPollen":0,"mugwortPollen":0,"olivePollen":0,"ragweedPollen":0}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/air/area":{"get":{"operationId":"getV1AirArea","tags":["Air quality"],"summary":"Air quality grid over an area","description":"The air quality values of `/v1/air` on a grid, shaped like the weather grid, with the same `hours`, `stepHours` and `pastHours`. Keys given the bulk_grid permission (on request) may ask for up to 20,000 cells and 250,000 values; such grids are built one at a time behind other requests, so they take longer.\n\nCost: One request.","parameters":[{"name":"bbox","in":"query","required":true,"description":"west,south,east,north in degrees, at most 3600 square degrees","schema":{"type":"string"},"example":"6.0,46.1,6.3,46.3"},{"name":"cells","in":"query","required":false,"description":"1 to 400 (default 100)","schema":{"type":"integer"},"example":4},{"name":"stepDeg","in":"query","required":false,"description":"Instead of cells: a lattice with cell centres at west + k·stepDeg and north − k·stepDeg, 0.01 to 10 degrees, so the cells can sit on a model's own nodes (CAMS Europe: every 0.1° at x.x5°, CAMS Global: every 0.4°)","schema":{"type":"number"}},{"name":"hours","in":"query","required":false,"description":"How many steps come back, 1 to 120 (default 24)","schema":{"type":"integer"},"example":2},{"name":"stepHours","in":"query","required":false,"description":"Hours between two steps, 1 to 6 (default 1)","schema":{"type":"integer"}},{"name":"pastHours","in":"query","required":false,"description":"Start this many hours before the current hour, 0 to 48 (default 0); the window may span up to 168 hours","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"bbox":[6,46.1,6.3,46.3],"rows":2,"cols":2,"lon":[6.075,6.225],"lat":[46.25,46.15],"times":["2026-11-12T12:00:00Z","2026-11-12T13:00:00Z"],"values":{"pm25":[[3,3.5,3.6,4.3],[2.5,3.2,3.1,4.4]],"pm10":[[3.7,4.9,4.7,5.6],[3.5,4.9,4.5,5.2]],"nitrogenDioxide":[[6.5,10.5,10.9,14.1],[6.2,9.1,9.7,13.8]],"ozone":[[54,43,45,35],[55,44,48,38]],"sulphurDioxide":[[0.3,0.3,0.3,0.3],[0.2,0.3,0.3,0.3]],"carbonMonoxide":[[136,154,153,165],[130,147,149,165]],"ammonia":[[0.9,1.1,1.2,1],[0.9,1.2,1.3,1.1]],"dust":[[0,0,0,0],[0,0,0,0]],"uvIndex":[[0.5,0.5,0.4,0.4],[0.3,0.4,0.3,0.3]],"europeanAqi":[[18,21,21,25],[18,18,19,25]],"usAqi":[[30,42,38,39],[29,42,38,39]],"alderPollen":[[0,0,0,0],[0,0,0,0]],"birchPollen":[[0,0,0,0],[0,0,0,0]],"grassPollen":[[0,0,0,0],[0,0,0,0]],"mugwortPollen":[[0,0,0,0],[0,0,0,0]],"olivePollen":[[0,0,0,0],[0,0,0,0]],"ragweedPollen":[[0,0,0,0],[0,0,0,0]]}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/air/stations":{"get":{"operationId":"getV1AirStations","tags":["Air quality"],"summary":"Measured air quality at stations","description":"The latest value per pollutant (last 3 hours; 6 for EEA stations) at official stations (`kind=government`) and volunteer sensors (`kind=citizen`), nearest first: around a point (`lon`, `lat`, `radiusKm` 1 to 100, default 25) or in a box (`bbox`, nearest its centre first). µg/m³; `credits` names the sources to show.\n\nCost: One request.","parameters":[{"name":"lon","in":"query","required":false,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":19.94},{"name":"lat","in":"query","required":false,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":50.06},{"name":"radiusKm","in":"query","required":false,"description":"1 to 100 (default 25)","schema":{"type":"number"}},{"name":"bbox","in":"query","required":false,"description":"west,south,east,north in degrees, at most 16 square degrees","schema":{"type":"string"},"example":"6.0,46.1,6.3,46.3"},{"name":"limit","in":"query","required":false,"description":"Around a point 1 to 100 (default 10); in a box 1 to 1000 (default 200)","schema":{"type":"integer"},"example":2},{"name":"kind","in":"query","required":false,"description":"government or citizen; both when absent","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"stations":[{"id":"syngeos:10043","name":"Kraków, Warszawska 24","kind":"citizen","lon":19.94143,"lat":50.07168,"distanceKm":1.3,"time":"2026-11-12T10:37:38.000Z","values":{"pm10":19,"pm25":23}},{"id":"syngeos:10082","name":"Kraków, Warszawska 24","kind":"citizen","lon":19.94367,"lat":50.07152,"distanceKm":1.31,"time":"2026-11-12T11:05:27.000Z","values":{"o3":38,"pm10":11,"pm25":11}}],"credits":["Syngeos sensor network (https://syngeos.pl)"]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/air/stations":{"post":{"operationId":"postV1RouteAirStations","tags":["Air quality"],"summary":"Air quality stations along a route","description":"Stations within `bufferKm` (0.1 to 20) of the route, in route order with `alongKm`; up to `limit` (at most 500). A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"bufferKm":{"type":"number","minimum":0.1,"maximum":20},"limit":{"type":"integer","minimum":1,"maximum":500},"kind":{"type":"string","enum":["government","citizen"]}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[19.9,50.07],[19.98,50.05]]},"limit":2}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"stations":[{"id":"gios:400","name":"Kraków, Aleja Krasińskiego","kind":"government","lon":19.92619,"lat":50.05768,"distanceKm":0.6,"alongKm":2.25,"time":"2026-11-12T12:00:00.000Z","values":{"co":544,"no2":38.2,"pm10":37.7,"pm25":19.8}},{"id":"syngeos:10043","name":"Kraków, Warszawska 24","kind":"citizen","lon":19.94143,"lat":50.07168,"distanceKm":1.25,"alongKm":2.75,"time":"2026-11-12T10:37:38.000Z","values":{"pm10":19,"pm25":23}}],"credits":["Źródło danych: GIOŚ - EKOINFONET; current data are unverified and may change, CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)","Syngeos sensor network (https://syngeos.pl)"]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/air/stations/{id}/history":{"get":{"operationId":"getV1AirStationsByIdHistory","tags":["Air quality"],"summary":"Readings of one station","description":"Hourly readings per pollutant for the last `days` (1 to 7, default 7). The id comes from the station lists.\n\nCost: One request.","parameters":[{"name":"id","in":"path","required":true,"description":"source:station, e.g. gios:400","schema":{"type":"string"},"example":"gios:400"},{"name":"days","in":"query","required":false,"description":"1 to 7 (default 7)","schema":{"type":"integer"},"example":1}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"id":"syngeos:10043","readings":{"pm10":[{"time":"2026-11-11T14:00:00.000Z","value":15},{"time":"2026-11-11T15:00:00.000Z","value":17},{"time":"2026-11-11T16:00:00.000Z","value":17}],"pm25":[{"time":"2026-11-11T13:00:00.000Z","value":11},{"time":"2026-11-11T14:00:00.000Z","value":11},{"time":"2026-11-11T15:00:00.000Z","value":12}]},"credits":["Syngeos sensor network (https://syngeos.pl)"]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/rivers":{"get":{"operationId":"getV1Rivers","tags":["Rivers"],"summary":"River gauges","description":"The latest water level (cm above the gauge zero), discharge (m³/s), change over a day and the warning state at gauges, nearest first: around a point (`lon`, `lat`, `radiusKm` 1 to 100, default 25) or in a box (`bbox`).\n\nCost: One request.","parameters":[{"name":"lon","in":"query","required":false,"description":"Longitude, −180 to 180","schema":{"type":"number"},"example":6.1432},{"name":"lat","in":"query","required":false,"description":"Latitude, −90 to 90","schema":{"type":"number"},"example":46.2044},{"name":"radiusKm","in":"query","required":false,"description":"1 to 100 (default 25)","schema":{"type":"number"}},{"name":"bbox","in":"query","required":false,"description":"west,south,east,north in degrees, at most 16 square degrees","schema":{"type":"string"},"example":"6.0,46.1,6.3,46.3"},{"name":"limit","in":"query","required":false,"description":"Around a point 1 to 100 (default 10); in a box 1 to 1000 (default 200)","schema":{"type":"integer"},"example":2}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"gauges":[{"id":"hubeau:V035501202","name":"[Le Rhône] en Suisse - Halle de l'Ile - Barrage du Seujet (OFEV)","river":null,"lon":6.1416,"lat":46.20457,"distanceKm":0.13,"time":"2026-11-12T12:00:00.000Z","levelCm":null,"change24hCm":null,"dischargeM3s":107,"warningCm":null,"alarmCm":null,"state":null},{"id":"bafu:2606","name":"Genève, Halle de l'Île","river":"Rhône","lon":6.14154,"lat":46.20466,"distanceKm":0.13,"time":"2026-11-12T12:20:00.000Z","levelCm":null,"change24hCm":null,"dischargeM3s":110.375,"warningCm":null,"alarmCm":null,"state":null}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/rivers":{"post":{"operationId":"postV1RouteRivers","tags":["Rivers"],"summary":"River gauges along a route","description":"Gauges within `bufferKm` (0.1 to 20, default 2) of the route, nearest first. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"bufferKm":{"type":"number","minimum":0.1,"maximum":20}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"gauges":[{"id":"bafu:2606","name":"Genève, Halle de l'Île","river":"Rhône","lon":6.14154,"lat":46.20466,"distanceKm":0.13,"time":"2026-11-12T12:20:00.000Z","levelCm":null,"change24hCm":null,"dischargeM3s":110.375,"warningCm":null,"alarmCm":null,"state":null},{"id":"hubeau:V035501202","name":"[Le Rhône] en Suisse - Halle de l'Ile - Barrage du Seujet (OFEV)","river":null,"lon":6.1416,"lat":46.20457,"distanceKm":0.13,"time":"2026-11-12T12:00:00.000Z","levelCm":null,"change24hCm":null,"dischargeM3s":107,"warningCm":null,"alarmCm":null,"state":null},{"id":"bafu:2170","name":"Genève, Bout du Monde","river":"Arve","lon":6.15935,"lat":46.1803,"distanceKm":0.16,"time":"2026-11-12T12:20:00.000Z","levelCm":37949.2,"change24hCm":15.3,"dischargeM3s":64.84,"warningCm":null,"alarmCm":null,"state":null}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/rivers/{id}/history":{"get":{"operationId":"getV1RiversByIdHistory","tags":["Rivers"],"summary":"Readings of one gauge","description":"Readings for the last `days` (1 to 30, default 7). The id comes from the gauge lists.\n\nCost: One request.","parameters":[{"name":"id","in":"path","required":true,"description":"source:station, e.g. hubeau:V035501202","schema":{"type":"string"},"example":"hubeau:V035501202"},{"name":"days","in":"query","required":false,"description":"1 to 30 (default 7)","schema":{"type":"integer"},"example":1}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"id":"hubeau:V035501202","readings":[{"time":"2026-11-11T12:40:00.000Z","levelCm":null,"dischargeM3s":83.7},{"time":"2026-11-11T13:00:00.000Z","levelCm":null,"dischargeM3s":92.2},{"time":"2026-11-11T13:10:00.000Z","levelCm":null,"dischargeM3s":87.9}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route":{"post":{"operationId":"postV1Route","tags":["Routing"],"summary":"A route through points","description":"A route through 2 to 50 points on OpenStreetMap data. Profiles: `bike`, `city`, `road-bike`, `quiet-road-bike`, `gravel`, `mtb`, `hiking`, `car`, `shortest` (default `bike`; `city` keeps to cycleways and off busy roads). `alternative` 1 to 3 gives other routes. The answer is a LineString with a height at every point, its length, climb and riding time, and `surfaces`: kilometres paved, unpaved and unknown, kilometres per `highway` value, and the stretches of each way kind with its OSM `surface`, `highway`, `tracktype` (grade1 solid to grade5 soft) and `smoothness` (null where the way has no such tag), so a stretch without a surface tag can still be judged by the kind of way. `format: \"gpx\"` answers a GPX file instead. 404 `no_route` when a point cannot be reached with the profile; 504 `timeout` after two minutes (add waypoints or split the trip).\n\nCost: One request and one route per started 100 km of the route found (50 km for `mtb`).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"points":{"minItems":2,"maxItems":50,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}},"profile":{"type":"string","enum":["bike","city","road-bike","quiet-road-bike","gravel","mtb","hiking","car","shortest"]},"alternative":{"type":"integer","minimum":0,"maximum":3},"format":{"type":"string","enum":["geojson","gpx"]}},"required":["points"]},"example":{"points":[[6.1432,46.2044],[6.2,46.15]],"profile":"bike"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"profile":"bike","lengthKm":18.82,"ascentM":735,"durationS":8696,"geometry":{"type":"LineString","coordinates":[[6.143198,46.204407,374],[6.143206,46.204408,374],[6.143399,46.204372,374]]},"surfaces":{"km":{"paved":18,"unpaved":0.04,"unknown":0.79},"highwayKm":{"tertiary":6.34,"cycleway":5.23,"secondary":3.46,"residential":2.25,"unclassified":0.68,"primary":0.47,"track":0.2,"pedestrian":0.07,"footway":0.07,"primary_link":0.06},"runs":[{"fromKm":0,"toKm":0.235,"surface":"asphalt","highway":"residential","tracktype":null,"smoothness":null},{"fromKm":0.235,"toKm":0.308,"surface":"asphalt","highway":"pedestrian","tracktype":null,"smoothness":null},{"fromKm":0.308,"toKm":0.584,"surface":"asphalt","highway":"unclassified","tracktype":null,"smoothness":null}]}}},"application/gpx+xml":{"schema":{"type":"string"},"example":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- track-length = 18820 filtered ascend = 735 plain-ascend = 703 cost=21949 energy=.2kwh time=2h 24m 56s -->\n<gpx \n xmlns=\"http://www.topografix.com/GPX/1/1\" \n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n creator=\"BRouter-1.7.10\" version=\"1.1\">\n <trk>\n  <name>brouter_trekking_0</name>\n  <trkseg>\n   <trkpt lon=\"6.143198\" lat=\"46.204407\"><ele>374.0</ele></trkpt>\n   <trkpt lon=\"6.143206\" lat=\"46.204408\"><ele>374.0</ele></trkpt>\n   <trkpt lon=\"6.143"}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/loop":{"post":{"operationId":"postV1RouteLoop","tags":["Routing"],"summary":"A round trip from a point","description":"A loop of about `distanceKm` (5 to 200) back to `start`, setting off towards `direction` (degrees, 0 = north, default 0); another direction gives another loop. The length usually lands within 10 % of the asked one. If no loop can be made that way (a glacier, the sea), the other directions are tried. The answer has the shape of `/v1/route`.\n\nCost: One request and one route per started 100 km of the route found (50 km for `mtb`).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"start":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2},"distanceKm":{"type":"number","minimum":5,"maximum":200},"profile":{"type":"string","enum":["bike","city","road-bike","quiet-road-bike","gravel","mtb","hiking","car","shortest"]},"direction":{"type":"number","minimum":0,"maximum":360}},"required":["start","distanceKm"]},"example":{"start":[6.1432,46.2044],"distanceKm":25,"profile":"bike","direction":90}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"profile":"bike","lengthKm":25.807,"ascentM":141,"durationS":4932,"geometry":{"type":"LineString","coordinates":[[6.143198,46.204407,374],[6.143206,46.204408,374],[6.143201,46.204436,374]]},"surfaces":{"km":{"paved":16.01,"unpaved":0.05,"unknown":9.75},"highwayKm":{"none":7.07,"secondary":6.25,"residential":4.64,"tertiary":2.58,"cycleway":2.51,"living_street":0.96,"unclassified":0.89,"footway":0.26,"service":0.21,"primary":0.21,"path":0.13,"pedestrian":0.08},"runs":[{"fromKm":0,"toKm":0.01,"surface":"asphalt","highway":"residential","tracktype":null,"smoothness":null},{"fromKm":0.01,"toKm":0.044,"surface":"asphalt","highway":"residential","tracktype":null,"smoothness":"excellent"},{"fromKm":0.044,"toKm":0.104,"surface":"asphalt","highway":"residential","tracktype":null,"smoothness":null}]}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route/surfaces":{"post":{"operationId":"postV1RouteSurfaces","tags":["Routing"],"summary":"Surfaces of any track","description":"The OSM `surface` along a track you already have (an imported GPX, a drawn line): every 20 m the track takes the nearest road or path within 25 m. The answer has the shape of `surfaces` in `/v1/route`: kilometres paved, unpaved and unknown, kilometres per `highway`, and stretches with `surface`, `highway`, `tracktype` and `smoothness`. The track is not re-routed. `unknown` surface: the way has no surface tag (its highway, tracktype and smoothness still come along), or no way lies within 25 m (then all three are null). `heightLimits` lists the stretches on ways with a height limit, tunnels and passages under bridges included, so you can tell whether a car with bikes on the roof fits: `maxheight` as tagged in OSM (the lower of `maxheight` and `maxheight:physical`), `maxheightM` in metres (feet converted), or `below_default`, meaning no sign but less room than the country's general limit (`maxheightM` null); `name` of the way. Only what is tagged on the ways: a height barrier mapped as a point on the road is not in the list, and a way with no tag may still be low. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]}},"required":["route"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"km":{"paved":2.76,"unpaved":0.32,"unknown":4.49},"highwayKm":{"none":1.95,"footway":1.53,"service":1.25,"path":0.7,"residential":0.54,"tertiary":0.44,"track":0.32,"cycleway":0.2,"living_street":0.18,"unclassified":0.16,"pedestrian":0.14,"secondary":0.06,"primary":0.04,"motorway":0.04,"secondary_link":0.02,"platform":0.02},"runs":[{"fromKm":0,"toKm":0.02,"surface":"asphalt","highway":"residential","tracktype":null,"smoothness":null},{"fromKm":0.02,"toKm":0.04,"surface":"unknown","highway":"cycleway","tracktype":null,"smoothness":null},{"fromKm":0.04,"toKm":0.059,"surface":"asphalt","highway":"pedestrian","tracktype":null,"smoothness":"good"}],"heightLimits":[]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route-poi/categories":{"get":{"operationId":"getV1RoutePoiCategories","tags":["Stops along a route"],"summary":"Stop categories","description":"The categories and subtypes `/v1/route-poi/corridor` answers with: the OSM tags behind each, the default distance from the route, whether it is in the default search, and GPX and FIT waypoint symbols. `version` (also the ETag) changes when the catalog does.\n\nCost: One request.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"version":"a266ea079477","defaultCategories":["grocery","fuel","food"],"maxDistanceM":5000,"maxCorridorKm2":2000,"fallbackExport":{"gpx":"Waypoint","fit":"generic"},"categories":[{"id":"grocery","inDefaultSearch":true,"defaultDistanceM":200,"sources":["db","tiles"],"export":{"gpx":"Shopping Center","fit":"store"},"subtypes":[{"id":"supermarket","osm":[{"shop":["supermarket"]}],"export":{"gpx":"Shopping Center","fit":"store"}},{"id":"convenience","osm":[{"shop":["convenience"]}],"export":{"gpx":"Convenience Store","fit":"store"}},{"id":"bakery","osm":[{"shop":["bakery"]}],"export":{"gpx":"Convenience Store","fit":"food"}}]},{"id":"fuel","inDefaultSearch":true,"defaultDistanceM":200,"sources":["db","tiles"],"export":{"gpx":"Gas Station","fit":"store"},"subtypes":[{"id":"fuel","osm":[{"amenity":["fuel"]}],"export":{"gpx":"Gas Station","fit":"store"}}]},{"id":"food","inDefaultSearch":true,"defaultDistanceM":200,"sources":["db","tiles"],"export":{"gpx":"Restaurant","fit":"food"},"subtypes":[{"id":"cafe","osm":[{"amenity":["cafe"]}],"export":{"gpx":"Restaurant","fit":"food"}},{"id":"restaurant","osm":[{"amenity":["restaurant"]}],"export":{"gpx":"Restaurant","fit":"food"}},{"id":"fast_food","osm":[{"amenity":["fast_food"]}],"export":{"gpx":"Fast Food","fit":"food"}}]}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route-poi/corridor":{"post":{"operationId":"postV1RoutePoiCorridor","tags":["Stops along a route"],"summary":"Stops along a route","description":"Water, food, groceries, toilets, bike shops and fuel (and on request places to sleep, sights, charging, benches, picnic spots) along a route, each with its kilometre along the route and its distance from it, plus the stretches of more than 40 km without water and food (`gaps`). The route comes as `points` of `{lat, lon, d}` (d: metres from the start), or as `sections` of them for separate pieces; up to 1,000 points. Distances: each category's default, `maxDistanceM` for all, or `distancesM` per category, up to 5,000 m; route length × the widest distance at most 2,000 km·km (1,000 km at 2 km, 400 km at 5 km), else 413. Chain stores carry their brand `logo` and `icon` URLs.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"points":{"minItems":2,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"lat":{"type":"number","minimum":-85,"maximum":85},"lon":{"type":"number","minimum":-180,"maximum":180},"d":{"type":"number","minimum":0}},"required":["lat","lon","d"]}},"sections":{"minItems":1,"maxItems":64,"type":"array","items":{"minItems":2,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"lat":{"type":"number","minimum":-85,"maximum":85},"lon":{"type":"number","minimum":-180,"maximum":180},"d":{"type":"number","minimum":0}},"required":["lat","lon","d"]}}},"categories":{"maxItems":11,"type":"array","items":{"type":"string","enum":["grocery","fuel","food","water","toilets","bike","sleep","sights","charging","bench","picnic"]}},"maxDistanceM":{"type":"integer","minimum":1,"maximum":5000},"distancesM":{"type":"object","propertyNames":{"type":"string","enum":["grocery","fuel","food","water","toilets","bike","sleep","sights","charging","bench","picnic"]},"additionalProperties":{"type":"integer","minimum":1,"maximum":5000}},"includeSprings":{"type":"boolean"}}},"example":{"points":[{"lat":46.2044,"lon":6.1432,"d":0},{"lat":46.19,"lon":6.15,"d":1666}],"categories":["water","food"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"pois":[{"id":"node/12456128201","category":"food","subtype":"restaurant","name":"Little Kitchen","lat":46.205307,"lon":6.1434257,"flags":{},"tags":{"amenity":"restaurant"},"distanceAlongRouteKm":0,"offsetFromRouteM":102},{"id":"node/1379366890","category":"water","subtype":"drinking_water","name":null,"lat":46.2047788,"lon":6.1417476,"flags":{"hasWater":true},"tags":{"amenity":"fountain","drinking_water":"yes"},"distanceAlongRouteKm":0,"offsetFromRouteM":120},{"id":"node/3032374079","category":"food","subtype":"restaurant","name":"Le Paradis","lat":46.2054609,"lon":6.1419829,"flags":{},"tags":{"website":"https://www.terrasse-paradis.ch/","addr:street":"Quai Turrettini","amenity":"restaurant"},"distanceAlongRouteKm":0,"offsetFromRouteM":151}],"totals":{"grocery":0,"fuel":0,"food":79,"water":19,"toilets":0,"bike":0},"totalCount":98,"gaps":[],"gapCount":0,"routeLengthKm":7.568,"partial":false,"cached":false,"source":"db","coverage":[{"sectionIndex":0,"segmentIndexes":[0,1,2]}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"413":{"description":"The route is too long or has too many points (`too_long`)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/route-poi/tile/{row}/{col}":{"get":{"operationId":"getV1RoutePoiTileByRowByCol","tags":["Stops along a route"],"summary":"All stops in a tile","description":"Every stop of the default categories in one 0.1° tile (row = floor(lat × 10), col = floor(lon × 10)), for apps that cache stops by area.\n\nCost: One request.","parameters":[{"name":"row","in":"path","required":true,"description":"floor(lat × 10)","schema":{"type":"integer"},"example":462},{"name":"col","in":"path","required":true,"description":"floor(lon × 10)","schema":{"type":"integer"},"example":61}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"pois":[{"id":"node/10009315581","category":"water","subtype":"drinking_water","name":null,"lat":46.2185561,"lon":6.150866,"flags":{"hasWater":true},"tags":{"amenity":"drinking_water","access":"yes","fee":"no"}},{"id":"node/10079250380","category":"food","subtype":"restaurant","name":"Hanae","lat":46.2043595,"lon":6.1563109,"flags":{},"tags":{"opening_hours":"Tu-Sa 12:00-14:00,19:00-22:00","website":"https://hanae-restaurant.ch/","addr:street":"Rue des Pierres-du-Niton","addr:housenumber":"5","addr:city":"Genève","phone":"+41 22 736 93 93","amenity":"restaurant"}},{"id":"node/10096957554","category":"food","subtype":"fast_food","name":"River Side","lat":46.2013962,"lon":6.1553355,"flags":{},"tags":{"opening_hours":"Mo 19:00-01:00; Tu 19:00-02:00; We 19:00-02:30; Th 19:00-03:00; Fr, Sa 19:00-04:00; Su 19:00-00:00","phone":"+41227362365","amenity":"fast_food"}}],"complete":true,"source":"db","fetchedAt":"2026-11-12T12:36:13.181Z","row":462,"col":61,"version":1}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/overpass/interpreter":{"post":{"operationId":"postV1OverpassInterpreter","tags":["OpenStreetMap data"],"summary":"Overpass QL","description":"Overpass QL queries answered from our copy of OpenStreetMap, in the Overpass JSON format. Send the query as the body (text/plain), as the form field `data`, or as `?data=` on GET; `/v1/overpass/api/interpreter` works too, and the key may come as `?key=`. `open_at=YYYY-MM-DDTHH:MM` (local time) keeps only the places open then. Errors come back as `remark`, as Overpass does. See the Overpass QL examples page for what is supported.\n\nCost: One request.","parameters":[{"name":"open_at","in":"query","required":false,"description":"Local time such as 2026-11-10T06:30","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"text/plain":{"schema":{"type":"string"},"example":"node[\"amenity\"=\"drinking_water\"](around:300,46.2044,6.1432);out;"}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"version":0.6,"generator":"Running Cat Geo API","osm3s":{"timestamp_osm_base":"2026-11-02T21:21:26+00:00","copyright":"The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."},"elements":[{"type":"node","id":897590805,"lat":46.2054894,"lon":6.1451637,"tags":{"amenity":"drinking_water","fountain":"bottle_refill","check_date":"2023-05-24"}},{"type":"node","id":1906525422,"lat":46.2028922,"lon":6.1448299,"tags":{"amenity":"drinking_water","designation":"potable water"}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/poi/corridor":{"post":{"operationId":"postV1PoiCorridor","tags":["OpenStreetMap data"],"summary":"OSM features along a route by tag","description":"OSM nodes and ways (with `center`) whose tags match `filters` (`{\"amenity\": [\"cafe\", \"restaurant\"], ...}`, 1 to 50 keys) within `buffer_m` of the route. 422 `not_covered` outside the map data. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"buffer_m":{"type":"number","minimum":1,"maximum":20000},"filters":{"type":"object","propertyNames":{"type":"string","pattern":"^[A-Za-z0-9_:.-]{1,64}$"},"additionalProperties":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[^\\u0000-\\u001f']*$"}}}},"required":["route","buffer_m","filters"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]},"buffer_m":300,"filters":{"amenity":["drinking_water"]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"source":"db","elements":[{"type":"node","id":897590805,"lat":46.2054894,"lon":6.1451637,"tags":{"amenity":"drinking_water","fountain":"bottle_refill","check_date":"2023-05-24"}},{"type":"node","id":1485121637,"lat":46.1903548,"lon":6.1505338,"tags":{"amenity":"drinking_water"}},{"type":"node","id":1769544502,"lat":46.1919462,"lon":6.1465644,"tags":{"amenity":"drinking_water","fountain":"drinking","check_date":"2024-01-30"}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/poi/boxes":{"post":{"operationId":"postV1PoiBoxes","tags":["OpenStreetMap data"],"summary":"OSM features in boxes by tag","description":"The same in up to 16 boxes `[west, south, east, north]` of at most 1 square degree each.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"boxes":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90},{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":4,"maxItems":4}},"filters":{"type":"object","propertyNames":{"type":"string","pattern":"^[A-Za-z0-9_:.-]{1,64}$"},"additionalProperties":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[^\\u0000-\\u001f']*$"}}}},"required":["boxes","filters"]},"example":{"boxes":[[6.14,46.2,6.16,46.21]],"filters":{"amenity":["cafe"]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"source":"db","elements":[{"type":"node","id":626085414,"lat":46.206384,"lon":6.1450353,"tags":{"name":"Starbucks","brand":"Starbucks","amenity":"cafe","cuisine":"coffee_shop","takeaway":"yes","addr:city":"Genève","official_name":"Starbucks Coffee","brand:wikidata":"Q37158","brand:wikipedia":"en:Starbucks","opening_hours":"Mo-Fr 06:30-20:30; Sa 07:00-20:30; Su 07:30-20:30","source:opening_hours":"atp","check_date:opening_hours":"2026-11-05","phone":"+41 43 421 42 26","website":"https://www.starbucks.co.uk/store-locator/40024-96840/quai-des-bergues"}},{"type":"node","id":656492497,"lat":46.2009495,"lon":6.1415985,"tags":{"name":"Café du Grütli","phone":"+41 22 321 51 58","amenity":"cafe","cuisine":"regional","website":"https://www.cafedugrutli.ch/","diet:vegan":"yes","wheelchair":"yes","addr:street":"Rue du Général-Dufour","opening_hours":"Mo-Th 08:00-24:00, Fr 16:00-23:00, Sa 16:00-01:00, Su 16:00-23:00","addr:housenumber":"16","diet:gluten_free":"yes"}},{"type":"node","id":767144613,"lat":46.207876,"lon":6.1416771,"tags":{"name":"Chatime","brand":"Chatime","branch":"KINAYO","amenity":"cafe","cuisine":"bubble_tea","takeaway":"yes","brand:wikidata":"Q16829306"}}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/roads/along":{"post":{"operationId":"postV1RoadsAlong","tags":["OpenStreetMap data"],"summary":"Roads along a route","description":"Highway ways within `buffer_m` (1 to 200) of a route, with their OSM tags and geometry. For surface statistics `/v1/route/surfaces` does the matching for you. A route is GeoJSON `{\"type\": \"LineString\", \"coordinates\": [[lon, lat], ...]}` or a MultiLineString of sections in order, up to 20,000 km.\n\nCost: One request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"route":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}},"required":["type","coordinates"]},{"type":"object","properties":{"type":{"type":"string","const":"MultiLineString"},"coordinates":{"minItems":1,"type":"array","items":{"minItems":2,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":{"type":"number"},"minItems":2}}}},"required":["type","coordinates"]}]},"buffer_m":{"type":"number","minimum":1,"maximum":200}},"required":["route","buffer_m"]},"example":{"route":{"type":"LineString","coordinates":[[6.1432,46.2044],[6.15,46.19],[6.175,46.17],[6.2,46.15]]},"buffer_m":20}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"source":"db","ways":[{"id":4272838,"tags":{"lit":"yes","name":"Rue Lombard","lanes":"2","busway":"lane","oneway":"yes","highway":"secondary","surface":"asphalt","cycleway":"share_busway","maxspeed":"50","lanes:psv":"1","psv:lanes":"yes|designated"},"geometry":[[6.147473,46.195835],[6.147557,46.19577],[6.147715,46.195644]]},{"id":5070216,"tags":{"lit":"yes","name":"Boulevard de la Tour","lanes":"3","oneway":"yes","highway":"secondary","surface":"asphalt","maxspeed":"30","cycleway:right":"lane"},"geometry":[[6.14679,46.195418],[6.146854,46.195432],[6.146914,46.195452]]},{"id":5070228,"tags":{"lit":"yes","name":"Rue de la Cité","bicycle":"designated","highway":"pedestrian","surface":"sett","segregated":"no"},"geometry":[[6.14362,46.203894],[6.143629,46.203875],[6.143649,46.203835]]}]}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"422":{"description":"Part of the request is outside the loaded map data (`not_covered`)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}},"/v1/status":{"get":{"operationId":"getV1Status","tags":["Service"],"summary":"Data status","description":"The loaded OpenStreetMap regions, when they were imported and how fresh their data is, and how busy the server is.\n\nCost: One request.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"import":{"regions":["africa","antarctica","australia-oceania"],"version":31,"import_id":31,"imported_at":"2026-11-08T17:55:10.220669+00:00","switched_at":"2026-11-08T17:55:10.220669+00:00","data_timestamp":"2026-11-02T21:21:26+00:00","region_details":[{"region":"africa","import_id":29,"switched_at":"2026-11-08T17:53:57.686042+00:00","data_timestamp":"2026-11-07T21:21:36+00:00"},{"region":"antarctica","import_id":30,"switched_at":"2026-11-08T17:55:10.220669+00:00","data_timestamp":"2026-11-07T21:21:36+00:00"},{"region":"australia-oceania","import_id":28,"switched_at":"2026-11-07T09:06:14.889892+00:00","data_timestamp":"2026-11-05T21:23:02+00:00"}]},"flyover":{"memory":0,"store":0,"db":0,"uncovered":0,"failed":0,"memory_bytes":0,"db_slots":{"active":0,"waiting":0}},"requests":{"running":1,"waiting":0}}}}},"400":{"description":"The request is invalid; `error` says why."},"401":{"description":"The key is missing or unknown."},"404":{"description":"Nothing there (no route, no tile, unknown path)."},"429":{"description":"A limit is reached: `quota` (per minute, day or routes a day) or `concurrency` (requests at once). Wait for `Retry-After` seconds."},"503":{"description":"The server is busy (`busy`) or a data set is not available (`unavailable`); retry after `Retry-After`."}}}}}}