Skip to content

Map layers and tiles

Weather tiles are value-encoded PNGs: each pixel carries the scalar, not a colour. You colour them on the client from the layer’s published stops, so a legend and the map can never disagree, and one tile set serves every palette and unit. Tiles are run-stamped and immutable. 0.2 credits each.

GET /v1/layers

Free. Every (model, var) layer with its current run, the valid hours that are published (including the retained extended run’s tail), zoom ceiling, bounds, encode range, colour stops and min_fxx.

{
"tilerev": 3,
"encoding": "value: R=G=B=(v-lo)/(hi-lo)*254, alpha 0 = nodata",
"layers": [
{
"id": "hrrr/toplift", "model": "hrrr", "var": "toplift",
"units": "m", "encode": [0, 6000], "min_fxx": 1,
"stops": [[0, 72, 60, 90, 0], [1219, 150, 70, 145, 255], ""],
"run": "2026-09-19T12", "valid": ["2026-09-19T12", "2026-09-19T13", ""],
"extended_run": "2026-09-19T06",
"minzoom": 0, "maxzoom": 6, "bounds": [-125, 24, -66.5, 49.5],
"tilejson": "https://api.vertexmaps.com/v1/layers/hrrr/toplift/tilejson.json?valid={valid}",
"tiles": "https://api.vertexmaps.com/v1/tiles/hrrr/{run}/toplift/f{FF}/{z}/{x}/{y}.png",
"attribution": "NOAA HRRR via Vertex API"
}
]
}
GET /v1/layers/{model}/{var}/tilejson.json?valid=2026-09-19T21

Free. A TileJSON 3.0 document for one layer at one valid hour, with the run and forecast hour resolved for you. If the key arrived as ?apikey=, the tile template carries it; otherwise send Authorization: Bearer with tile requests (most SDKs can’t) or append ?apikey= yourself.

{
"tilejson": "3.0.0",
"tiles": ["https://api.vertexmaps.com/v1/tiles/hrrr/2026-09-19T12/toplift/f09/{z}/{x}/{y}.png?apikey=vtx_live_…"],
"minzoom": 0, "maxzoom": 6, "bounds": [-125, 24, -66.5, 49.5],
"attribution": "NOAA HRRR via Vertex API",
"model": "hrrr", "layer": "toplift", "run": "2026-09-19T12", "fxx": 9, "valid": "2026-09-19T21",
"units": "m", "encode": [0, 6000], "stops": [ ]
}

Set your raster source’s maxzoom from the document. Above it, tiles are 204 and the SDK oversamples the last zoom, which is the intended look for 3 km data.

Decode with the encode range, then map value to colour with the stops. Stops are [value, r, g, b, a] rows, sorted by value.

Mapbox GL JS v3 supports this natively:

map.addSource("toplift", { type: "raster", tiles: tj.tiles, tileSize: 256, maxzoom: tj.maxzoom });
const [lo, hi] = tj.encode;
map.addLayer({
id: "toplift", type: "raster", source: "toplift",
paint: {
"raster-color-mix": [((hi - lo) * 255) / 254, 0, 0, lo],
"raster-color-range": [lo, hi],
"raster-color": ["interpolate", ["linear"], ["raster-value"],
...tj.stops.flatMap(([v, r, g, b, a]) => [v, `rgba(${r},${g},${b},${a / 255})`])],
"raster-opacity": 0.7,
},
});

MapLibre, Leaflet, deck.gl, QGIS: decode in a tile-load hook or shader: value = lo + (R / 254) * (hi - lo), transparent where alpha is 0, then look up the stops. Complete examples, with animation, legends, overlays and the static layers: Mapbox GL JS, MapLibre GL JS (a canvas protocol), Leaflet (a canvas tile layer with a value readout).

var Units Models Notes
temp °C all 2 m temperature
cloud, cloudlow, cloudmid, cloudhigh % all (decks: hrrr, rrfs, nam, gfs) Cloud cover, total and by deck
clouddecks packed hrrr, rrfs, nam, gfs R = low, G = mid, B = high deck cover in one tile
precip1h, precip3h mm all Accumulations; min_fxx 1 and 3
snow6hsnow48h cm hrrr, rrfs New snow windows
snowdepth m hrrr, rrfs, nam, gfs
windspeed, gust m/s all 10 m
wstar m/s hrrr, rrfs, nam, gfs Updraft velocity
toplift, cubase m MSL hrrr, rrfs, nam, gfs Top of usable lift, cumulus base; transparent where none
cudepth, odpot, spreadout m hrrr, rrfs, nam, gfs Cumulus depth, overdevelopment potential, spread-out
cape J/kg all
conv m/s hrrr, rrfs, nam Low-level convergence (3 km grids only)
refl dBZ hrrr, rrfs, nam Simulated composite reflectivity
smoke, aqi µg/m³, AQI hrrr Near-surface smoke and its AQI
GET /v1/tiles/{model}/{run}/{var}/f{FF}/{z}/{x}/{y}.png

run is YYYY-MM-DDTHH (UTC), FF the two- or three-digit forecast hour. Use the catalogue or /v1/meta.json to map a valid time to a run and hour; TileJSON does it for you.

GET /v1/meta.json is the raw discovery document the catalogue is built from: per-model runs, valid hours, zoom ceilings, the layers table with encode ranges and stops, and the metadata for overlays. Free; cached for 60 seconds.

Vector companions to the rasters, one credit each, run-stamped and immutable:

Endpoint Content
/v1/barbs/{model}/{run}/f{FF}/{level}.png Wind field as a UV-encoded PNG (u in R, v in G, ±60 m/s) for drawing barbs or particles. Levels: sfc, 1000ft18000ft. Grid bounds in meta.barbs.
/v1/barbs/{model}/{run}/f{FF}/{level}.geojson The same wind field as a ~15 km point grid with speed_kn and direction_deg.
/v1/isobars/{model}/{run}/f{FF}.geojson Mean-sea-level pressure contours.
/v1/thunder/{model}/{run}/f{FF}.geojson Forecast lightning-potential points from HRRR with tiers 1–3 (forecast, not observed strikes).
/v1/precipbands/{model}/{run}/{var}/f{FF}.geojson Precipitation as banded polygons for precip1h / precip3h, for hatched fills.

GET /v1/radar/index.json (free) lists MRMS reflectivity frames at 5-minute steps for the trailing two hours plus a nowcast to +60 minutes, rebuilt every two minutes. Each frame is a tile set at /v1/radar/{frame}/{z}/{x}/{y}.png, value-encoded in dBZ with the refl stops.

Weather and radar tiles are immutable and carry cache-control: public, max-age=31536000, immutable; static layers carry a day. Cache them. Repeat views from your cache are free.