Guide · JavaScript · beginner

Add live radar tiles to MapLibre.

Radar arrives as ordinary XYZ map tiles, so adding it is a raster source and a layer rather than an integration project. This covers exchanging your key for a tile token, picking the newest frame, switching palettes, and animating a loop over recent history.

Exchange your key for a tile token

Tiles are addressed with a short-lived token rather than your API key, which is what makes it safe to let a browser request them directly. Mint the token server side and hand it to the client. The response also carries a url_template, so you can use that rather than assembling the tile URL yourself.

Minting a tile token

curl -X POST "https://api.lightningapi.dev/v1/radar-tiles/token" \
  -H "X-API-Key: lapi_your_key_here"

Pick a frame

Tiles are addressed per frame, where a frame is one radar timestamp. List the available frames and take the newest for a live view, or take a span of them for a loop.

Listing frames

curl "https://tiles.lightningapi.dev/v1/frames?t=TOKEN"

Add the layer

With a frame and a token, the tile URL is a standard XYZ template. Tiles are transparent where there is no echo, so the layer composites straight over your existing base map with no masking needed.

MapLibre raster source and layer

const frame = frames[frames.length - 1];

map.addSource("radar", {
  type: "raster",
  tiles: [
    `https://tiles.lightningapi.dev/v1/radar/${frame}/{z}/{x}/{y}.png?t=${token}`,
  ],
  tileSize: 256,
});

map.addLayer({
  id: "radar",
  type: "raster",
  source: "radar",
  paint: { "raster-opacity": 0.7 },
});

Palettes

Four palettes ship: a conventional reflectivity ramp as the default, plus amber, amber-violet, and thermal. Pass the palette as a query parameter on the tile URL. Colour is applied at request time from stored reflectivity, so switching palettes changes nothing about the underlying values.

Animating a loop

To animate, swap the source tile URL across successive frames rather than adding a layer per frame. Adding layers per frame is the usual first attempt and it stacks translucent images on top of each other.

Stepping through frames

let i = 0;

setInterval(() => {
  i = (i + 1) % frames.length;
  map.getSource("radar").setTiles([
    `https://tiles.lightningapi.dev/v1/radar/${frames[i]}/{z}/{x}/{y}.png?t=${token}`,
  ]);
}, 500);

Radar tiles are included on every plan with their own monthly allowance, separate from your API call quota. An animated loop requests a lot of tiles, so check the allowance before leaving one running on a public page.

Frequently asked questions

What area does radar cover?

The continental United States. The frames endpoint returns a window_seconds value alongside the frame list, which is how far back your own plan lets you request, so read that rather than assuming a fixed depth.

Does this work with Mapbox GL or Leaflet?

Yes. It is a standard XYZ tile scheme, so any library that takes a tile URL template works. Leaflet uses L.tileLayer with the same URL.

Do radar tiles use my API call quota?

No. Tiles have their own monthly allowance, separate from the call quota on the flash endpoints.

Can I put the tile token in client code?

Yes, that is what it is for. It is short lived and scoped to tiles. Your API key stays on the server and is only used to mint tokens.

Can I read the value at a point rather than draw it?

Yes. There is a point value endpoint that returns the reflectivity at a latitude and longitude for a given frame, and a history endpoint for a point over time.

Related

Last checked 2026-09-20

Coverage areas

Lightning data provided as-is; not for safety-critical use. Commercial use is permitted on every current plan. Read the EULA →