Skip to content

SkySight

Moved from vulture-web/docs/api/skysight.md

The catalogue of SkySight’s forecast regions and layers, kept by hand.

SkySight publishes no machine-readable catalogue. Its own site keeps the regions compiled into its JavaScript and the layers in a global on the authenticated page, and the /api/layers endpoint the app has always called answers with a list frozen years ago: twenty-five entries for Central Europe where the site offers around thirty, and nine of those twenty-five are vector components rather than forecasts anyone would pick.

So the catalogue is maintained here instead. It is hand-written — there is nothing upstream to proxy — and it carries three things SkySight’s own API leaves out: which model backs each region, how a layer is served, and a legend for every layer.

Answers with the sections, the regions and the layers together. A client needs them at once: a layer is only forecast where its model runs, the region says which model that is, and the sections say where each layer belongs.

HeaderValue
Acceptapplication/json
AuthorizationYour API token
Accept-LanguageOptional. Language for layer names and descriptions

Accept-Language takes a normal weighted list — nl-BE,nl;q=0.9,en;q=0.8 gets Dutch. Supported: en, nl, de, fr, es, it, cs, pl. Anything else, or no header at all, answers in English. Region names are not translated; SkySight does not translate them either.

{
"groups": [
{ "id": "thermals", "name": "Thermals" },
{ "id": "clouds", "name": "Clouds" }
],
"regions": [
{
"id": "EUROPE",
"name": "Central Europe",
"tz": "Europe/Warsaw",
"model": "ss",
"interval": 1800,
"sw": [-9.5, 35.7],
"ne": [31.5, 64.2]
}
],
"layers": [
{
"id": "cape",
"group": "clouds",
"name": "CAPE / Storms",
"description": "Convective available potential energy. Higher values indicate greater instability and larger updraughts within deep convective cloud.",
"aircraft": ["glider", "paraglider", "hangglider"],
"models": ["ss", "noaa", "hrrr", "dwd"],
"tiles": "vector",
"composite_models": [],
"tile": "cape",
"legend": {
"unit_type": "",
"unit": "J",
"colors": [
{ "name": "100", "value": "100", "color": [0, 0, 143] },
{ "name": "400", "value": "400", "color": [0, 50, 255] }
]
}
}
]
}
FieldTypeDescription
idstringThe identifier layers are filed under
namestringSection header, in the requested language

Sections are served as data, in the order to show them, so adding one here is enough — a client files each layer under the group it names and lists the sections in this order without having heard of them beforehand. Every layer’s group is one of these ids.

FieldTypeDescription
idstringSkySight’s region identifier, as used in tile URLs
namestringDisplay name
tzstringIANA time zone the region’s forecast hours are expressed in
modelstringModel family: ss, dwd, hrrr or noaa
intervalintegerSeconds between forecasts — 3600 hourly, 1800 twice an hour
sw[number]South-west corner, [lon, lat]. Absent on the global model
ne[number]North-east corner, [lon, lat]. Absent on the global model

The corners let a client offer the right region for wherever its map is looking, rather than asking. They overlap on purpose — the Alps sit inside Central Europe — so a client wanting one region should take the smallest that contains the point. The global model is deliberately uncornered: its box covers one continent’s worth of the world and would swallow guesses that belong elsewhere.

Which regions an account may actually browse is between the account and SkySight; this lists them all and lets the client take the intersection.

interval matters: asking a dwd or hrrr region for a half past the hour requests a forecast that was never produced, and the map comes back blank.

FieldTypeDescription
idstringSkySight’s layer identifier, as used in tile URLs
groupstringThe id of one of the groups above
namestringDisplay name, in the requested language
descriptionstringOne sentence on what the layer shows, in the requested language
aircraft[string]Aircraft the layer is meant for — see below
models[string]Model families that forecast this layer
tilesstringvector or composite — see below
composite_models[string]Model families serving a vector layer as a composite one instead
tilestringThe tile to fetch — its own id unless it is drawn from another’s
legendobjectUnit and colour stops

A layer is available in a region when models includes the region’s model.

aircraft is how a client narrows the catalogue to the pilot in front of it. Four values appear:

ValueMeaning
gliderSailplanes
paragliderParagliders
hanggliderHang gliders
planePowered aircraft — only the Lowest Cloud Layer (cceil)

Most layers list all three soaring wings. The ones that do not are deliberate: SkySight scales flight distance and cross-country speed to the wing and publishes a separate layer for each, so pfdtot and potfd (950 km, 160 kph) carry glider while pfdtothg and potfd_hg (330 km, 50 kph) carry paraglider and hangglider. Both pairs share the names Potential Flight Distance and XC Speed, which is correct — filtered to one aircraft, no pilot is ever shown both. A client that ignores aircraft will show two identically named rows.

Filtering can leave a section empty, so a client must be ready to drop one rather than draw a bare header. Wave is the case that bites: SkySight means the middle altitudes (2000-4000 m) for paragliders as well, but no wave layer at all for hang gliders, so a hang glider pilot’s Wave section has nothing in it. In the other direction, Star Rating is for paragliders and hang gliders only, and a glider pilot never sees it.

tiles decides whether a client can draw the layer at all.

  • vector — a vector tile of coloured polygons. Every stop in legend.colors is one index into the tile’s idx attribute.
  • composite — a raster tile carrying the forecast value in the pixel’s red channel, scaled across the legend’s range, for a shader to colour. Drawing one needs a raster colour ramp. Mapbox v6 has no way to express that, so the iOS app skips these until its map engine can; they are listed so a client that can draw them may.

composite_models covers the layers that are vector tiles in most regions but composite ones on the DWD and HRRR models — most of the thermal and cloud layers are, which is why those regions are mostly undrawable on a vector map.

tile is usually the layer’s own id, but SkySight packs some forecasts into a neighbour’s tile, and a client must fetch what tile says rather than what id says:

  • Cloud cover (tcc) rides in the low-cloud tile (CFRACL). It is painted as three translucent sheets out of that one tile — low from the period source layer, middle from CFRACM, high from CFRACH — each in a flat colour with the opacity carrying how much cloud there is, (idx + 1) / 9. Its legend is the three colours rather than a scale, which is why it is pinned rather than generated.
  • Significant weather (sigwx) is drawn over the thermal-depth tile (dwcrit): the depth of thermals underneath, with cumulus and storm symbols from the sigwx tile on top as a repeating pattern, indexed by its idx.

legend.colors matches the shape SkySight’s own layers request answers with, so a client already reading those needs no second decoder.

Colours are not stored. They are generated from the layer’s range against SkySight’s master ramp — 179 colours from deep blue through cyan, green, yellow and red to violet — sampled at even positions, one stop per step, interpolating between neighbouring entries. Changing a layer’s range therefore changes its legend, and nothing else has to be edited.

The rule was read off SkySight’s own rendering and is checked in the specs against two legends captured from its live map: pfdtot reproduces exactly, hwcrit in Central Europe to within one unit on a single channel of one stop.

One caveat for clients: SkySight uses this array for the legend it draws and clamps the fill to the last colour beyond it. A client using one array for both will leave the most extreme values unpainted unless it clamps the index itself.

StatusReason
403Missing or invalid Authorization header
406Missing or invalid Accept header

Names and descriptions are SkySight’s own words, not a re-translation: they were taken from the translation files SkySight publishes for its own site, so a pilot reading Vulture sees the same terms as on skysight.io. That matters for soaring vocabulary, where a literal translation often is not what pilots say — hwcrit is “Hoogte van thermiek” in Dutch and “Thermik Obergrenze (MSL)” in German, neither of which is a translation of “Height of Thermals”.

They live in locales/*.yml under skysight.layers, alongside the rest of the site’s copy.

A handful of strings are English in every language, because SkySight has not translated them either — the potential-flight-distance description, the Cu coverage and surface wind descriptions, and Thermal Wave, which is new on their site. They fall back to English rather than to a missing-translation marker: an English sentence is readable, and “translation missing” is not.