For websites and developers

PeakVisor API

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.

New A panorama with your trail on it Pick one of your PeakVisor trails, choose a compact or a full trail panel and the light of a particular day, and copy the code. Embed your trail →

Embed a panorama

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_LNG

Configuring Your Panorama

Before you can embed a PeakVisor panorama to your website, you need to configure a URL that shows your intended location (e.g., Mont Blanc).

To configure your URL, you first need to know the latitude and longitude of your location, and if you want the view from above the ground, its altitude.

Note

If you click this link (https://peakvisor.com/panorama.html) you will see the PeakVisor's panorama at its default coordinates: (latitude 45.9420159, longitude 7.8699421, and altitude 4598). To get the location you need, use the GPS configurator. You can access the GPS configurator by pressing on the marker icon that’s located next to the search field.

Parameters

ParameterRequiredDescription
lat, lngyesCoordinates of the viewpoint in decimal degrees. Without them the panorama opens at the default view above.
altnoAltitude of the viewpoint in metres. Without it the camera stands on the ground at the point, at eye level.
yawnoHorizontal rotation, from -180 to 180 degrees.
pitchnoVertical rotation, from -90 (straight down) to 90 (straight up) degrees.
hfovnoHorizontal field of view in degrees: zoom, from 140 (widest) to 4 (closest).

As soon as you have the information you need for your panorama, it’s time to create your URL. You can configure your URL using our tool below:

Embedding a URL

Now 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>

Sunrise and sunset behind the mountains

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_LNG

For each day it returns:

  • sunrise: the moment the upper edge of the sun first clears the ridges around your house, with its direction and the height of the skyline there
  • sunset: the moment it disappears behind them
  • sunlight: every period of direct sun in between (on some days the sun dips behind a peak and comes back)
  • flat: the ordinary calendar sunrise and sunset, for comparison

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.

Parameters

ParameterDefaultDescription
lat, lngrequiredCoordinates of the viewpoint in decimal degrees.
heightabout 2Viewpoint 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.
datetodayFirst day, YYYY-MM-DD.
days1Number of days, up to 366: a whole season at once.
Note

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.

Response

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" }
    }
  ]
}
FieldDescription
status"OK", or "ERROR" together with an error message (for example, when lat or lng is missing).
locationThe requested point: ground is the terrain elevation and observer the viewpoint elevation, both in metres.
horizonThe 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[].sunsettime, 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[].sunlightEvery period of direct sun, as from/to pairs; sunlightMinutes is their total.
days[].flatThe ordinary calendar sunrise and sunset over a flat horizon, with its own state.

Using it in Home Assistant

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 }}"

Try it