For websites and developers
Put a live 3D mountain panorama on your website — of any viewpoint or of your own trail — or get the real sunrise behind the ridges for your app.
Put an interactive PeakVisor 3D panorama of any viewpoint on your website or blog: give the /embed URL the coordinates of the viewpoint and place it in an iframe.
https://peakvisor.com/embed?lat=YOUR_LAT&lng=YOUR_LNGNow that you have the URL for your panorama, it’s time to embed it on your website for your visitors to enjoy.
To embed a panorama into your web page, place your URL in an iframe tag within the "src" attribute.
For instance, the following snippet of HTML code has been used to embed a panorama of Mount Everest into a website:
<iframe
src="https://peakvisor.com/embed?lat=27.988217&lng=86.924887&alt=8769&yaw=127.12&pitch=-4.67&hfov=60.00"
title="PeakVisor 3D panorama of Mount Everest"
width="100%" height="375" frameborder="0" loading="lazy">
</iframe>The /sun endpoint gives the real sunrise and sunset for any point in the mountains: the moment the sun clears the surrounding ridges, not the calendar time over a flat horizon. Send a GET request with the coordinates and it answers in JSON.
https://peakvisor.com/sun?lat=YOUR_LAT&lng=YOUR_LNGFor each day it returns:
The skyline is traced from the same terrain model as Panorama 3D, so the times match what you see there to about a minute. On days when the sun never clears the mountains (not unusual in Klöntal in winter), sunrise and sunset are empty and the day’s state is "never". Times are ISO 8601 in UTC, and Home Assistant shows them in your local time.
| Parameter | Default | Description |
|---|---|---|
lat, lng | required | Coordinates of the viewpoint in decimal degrees. |
height | about 2 | Viewpoint height in metres above the ground, as in the panorama. Use &height=6 for, say, an upper-floor window or a solar panel on the roof. |
date | today | First day, YYYY-MM-DD. |
days | 1 | Number of days, up to 366: a whole season at once. |
For the coordinates, please copy lat and lng from the address bar of your Panorama 3D view rather than using your Home Assistant home zone. In a valley as deep as Klöntal, a few hundred metres can change the times by hours.
Example for a point above Klöntalersee on 18 October 2026: the calendar says sunrise at 05:46 UTC, but the sun only clears the ridge at 09:17 UTC.
{
"status": "OK",
"location": { "lat": 47.028, "lng": 8.965, "ground": 1021.9, "observer": 1024.0 },
"horizon": { "min": 5.68, "max": 38.39, "bins": 1440, "cached": true },
"days": [
{
"date": "2026-10-18",
"state": "crosses",
"sunrise": { "time": "2026-10-18T09:17:10Z", "azimuth": 148.3, "horizon": 28.3 },
"sunset": { "time": "2026-10-18T15:26:34Z", "azimuth": 244.3, "horizon": 10.0 },
"sunlight": [
{ "from": "2026-10-18T09:17:10Z", "to": "2026-10-18T15:26:34Z" }
],
"sunlightMinutes": 369,
"flat": { "state": "crosses", "sunrise": "2026-10-18T05:46:16Z", "sunset": "2026-10-18T16:31:34Z" }
}
]
}| Field | Description |
|---|---|
status | "OK", or "ERROR" together with an error message (for example, when lat or lng is missing). |
location | The requested point: ground is the terrain elevation and observer the viewpoint elevation, both in metres. |
horizon | The lowest and highest point of the skyline around you, in degrees above the horizontal. |
days[].state | "crosses": the sun rises over the ridges and sets behind them; "never": it never clears the mountains that day; "always": it stays above the skyline all day (polar summer). |
days[].sunrise, days[].sunset | time, the sun’s direction azimuth in degrees from north, and the height of the skyline there, horizon, in degrees. null when there is no sunrise or sunset that day. |
days[].sunlight | Every period of direct sun, as from/to pairs; sunlightMinutes is their total. |
days[].flat | The ordinary calendar sunrise and sunset over a flat horizon, with its own state. |
A REST sensor in configuration.yaml turns the times into timestamp sensors. Replace the coordinates with your own:
rest:
- resource: https://peakvisor.com/sun?lat=47.028&lng=8.965
scan_interval: 3600
sensor:
- name: "Sunrise behind the mountains"
device_class: timestamp
value_template: "{{ value_json.days[0].sunrise.time if value_json.days[0].sunrise else None }}"
- name: "Sunset behind the mountains"
device_class: timestamp
value_template: "{{ value_json.days[0].sunset.time if value_json.days[0].sunset else None }}"