SplitshotWeather
Pricing Start free trial

API documentation

Four raster layers and two JSON endpoints, behind one key. Tiles are standard XYZ — anything that speaks slippy maps can draw them.

Quickstart

Two requests. Ask what frames exist, then fetch a tile from one.

curl -H "x-api-key: $KEY" \
  https://splitshotweather.com/manifest/composite.json

That returns a frames array of timestamps. Put one into the tile template:

https://splitshotweather.com/tiles/composite/{ts}/{z}/{x}/{y}.png?key=$KEY

In MapLibre or Mapbox GL:

map.addSource('radar', {
  type: 'raster',
  tiles: ['https://splitshotweather.com/tiles/composite/20261024-0610/{z}/{x}/{y}.png?key=' + KEY],
  tileSize: 256,
  maxzoom: 8
});
map.addLayer({ id: 'radar', type: 'raster', source: 'radar',
               paint: { 'raster-opacity': 0.85 } });

maxzoom 8 matters. Tiles are generated to zoom 8 and the source data is about 1 km, so one screen pixel is one data cell around zoom 7. Past that every zoom is interpolation — letting the GPU stretch from 8 looks the same as asking us for deeper tiles and costs you nothing.

Authentication

Every request needs your key, either way round:

x-api-key: <key>Header. Use this where you can.
?key=<key>Query string. For map libraries that cannot attach headers to tile requests.

The query-string form exists because several map SDKs give you no way to set a header on a raster tile request. It is stripped at the edge before the request is cached or logged. Treat the key as a secret either way — anything in a URL ends up in browser history and referrer headers.

Manifests

A manifest says which frames exist right now. Poll it, do not guess — publish cadence varies by layer, and a missed render leaves a gap that counting backwards from "now" would land in.

GET /manifest/{product}.json

{
  "product": "composite",
  "source": "NOAA MRMS MergedReflectivityQCComposite_00.50",
  "updated": "2026-10-24T06:10:33Z",
  "cadenceMinutes": 5,
  "maxZoom": 8,
  "units": "dBZ",
  "legend": [ { "value": 5, "unit": "dBZ", "rgb": [126,211,126] }, … ],
  "tileUrlTemplate": "/tiles/composite/{ts}/{z}/{x}/{y}.png",
  "frames": ["20261024-0540", … , "20261024-0610"],
  "latest": "20261024-0610",
  "forecastTileUrlTemplate": "/tiles/composite-fcst/{ts}/{z}/{x}/{y}.png",
  "forecast": [ { "ts": "20261024-0615", "leadMinutes": 5 }, … ]
}
framesObserved frames, oldest first.
forecastExtrapolated frames, with lead time. Empty on layers without a forecast. Served from a separate template so a projection is never mistaken for a measurement.
legendThe colour ramp, so you can draw a matching scale. Every stop carries value and unit.
cadenceMinutesHow often a new frame appears — step your timeline by this, not by a guess.

Manifests are cached 30 seconds at the edge. Polling faster just burns requests against your quota.

Tiles

GET /tiles/{product}/{ts}/{z}/{x}/{y}.png

256 px PNG with transparency, Web Mercator, standard XYZ (y increasing southward). {ts} comes from a manifest.

A tile with nothing in it is never written, and returns 404. That is the correct answer — draw nothing. It is also most of why this is cheap, so do not treat a 404 as an error. 404s are not billable.

Radar

Close-up of a storm showing contour bands from green through yellow and orange to a red core
Composite reflectivity, zoom 7. Bands are quantised, so edges stay hard at any zoom.
productcomposite
sourceNOAA MRMS composite reflectivity
cadence5 minutes
forecast30 minutes, 5-minute steps
unitsdBZ
Radar colour ramp from 5 to 65 dBZ
5 dBZ (light) → 65 dBZ (severe)

Rain totals

Close-up of rainfall accumulation showing blue through green and yellow
24-hour accumulation, zoom 7. Deliberately unsmoothed — the value is a quantity, not a shape.
productsqpe-1h, qpe-24h
sourceNOAA MRMS multi-sensor QPE — radar corrected against rain gauges
cadencehourly, published about an hour behind the hour it covers
unitsmillimetres (legend also carries inches)
Rainfall colour ramp from 0.01 to 8 inches
0.01 in → 8 in. Non-linear: tight where decisions change, loose where they do not.

Lightning

productlightning
sourceGOES satellite lightning mapper, both satellites
cadence5 minutes, each frame covering a rolling 15-minute window
unitsflashes per cell

Total lightning — in-cloud as well as cloud-to-ground. In-cloud activity usually precedes the first ground strike, so this tends to light up before a ground network would. Located to roughly 8–14 km: it answers "is that storm electrically active", never "the strike was here".

The window is longer than the cadence on purpose, so consecutive frames overlap and an animation moves rather than strobing. The manifest reports windowMinutes.

Lightning colour ramp from 1 to 100 flashes
1 flash → 100+ per cell, over the window

Wind

productwind
sourceNOAA real-time mesoscale analysis, 2.5 km
cadencehourly
unitsmph

Latest frame only — no timeline.

Point forecast

GET /forecast/{lat},{lon}

Current conditions, hourly for the next twelve hours, and seven days. Temperature, feels-like, wind speed and direction, humidity, pressure, visibility, precipitation probability, conditions and an icon.

Coordinates are rounded to two decimal places before anything upstream sees them — about a kilometre, which is finer than the underlying grid and means an exact location never leaves this service.

Historical conditions

GET /history/{lat},{lon}/{iso8601}

What the weather actually was at a point and a moment: temperature, wind, pressure, humidity, cloud cover and precipitation. Back to 2013.

Available on Growth. Unknown values are returned as null rather than filled in — an imputed number cannot be told from a measurement later, and for a historical record that distinction is the whole point.

Coverage

RegionRadarRainLightningWind
CONUS✓✓✓✓
Alaska✓✓—✓
Hawaii✓—✓✓
Puerto Rico✓✓✓✓
Guam✓✓—✓

Lightning stops near 54°N — that is the satellite's field of view, measured, not a gap we intend to fill. Guam is outside both satellites. Hawaii has no published gauge-corrected rainfall. Nothing outside the United States.

Errors & limits

200Fine.
401Missing, malformed or revoked key. Never cached — a key activated a moment ago works immediately.
404No tile there. Expected, not an error. Draw nothing.
429Monthly request limit reached. Body carries an upgrade link.
502Upstream unavailable. Retry.

Only 2xx and 3xx count against your plan. Your 401s and 404s are not billed — a misconfigured client should cost you a bug report, not quota.

A newly issued key can return 401 from edges that have not yet converged. Allow a minute, and treat five consecutive successes as proof rather than one.

Availability

There is no uptime guarantee on Starter or Growth. What there is instead: frames are immutable once published and served from cache, so a failure upstream degrades the service to stale frames rather than blank ones, and frame age is alarmed on. Ask if you need something contractual.