Community. Driven. Weather. Data. | Always Ad-Free | Developer FriendlyChecking statusDiscord
Become a supporter
Sign in
API

Local storm reports

Official NWS local storm reports, the tornadoes, hail, wind damage and flooding offices confirm, filtered by time, box, category, state and office.


Base URL: https://api.wxalerts.org

The National Weather Service’s local storm reports: what an office has confirmed happened, from spotters, emergency managers, the public and automated stations. Each report is a point, a time, the office’s own event wording and, where there is one, a measured or estimated magnitude.

GET /lsr/reports
GET /lsr/reports?hours=24&state=TX,OK
GET /lsr/reports?hours=72&categories=tornado,hail&bbox=-103,33,-94,37
GET /lsr/reports?office=KOUN

No key needed. Browsers block calls from other websites (CORS allows only wxalerts.org), so call it from a server, script or app. Responses carry Cache-Control: public, max-age=60. Limits are on the overview.

These are official NWS records, not the unofficial reports people file through wxalerts.org, which are a separate feed.

parameter
hours how far back to look, 1 to 72. Default 6
bbox minLon,minLat,maxLon,maxLat. Only reports inside the box
categories comma separated categories. Case does not matter. An unknown name is a 422, not an empty list
state comma separated two letter states or territories, such as TX,OK or PR. Case does not matter
office comma separated issuing offices, as the four letter ID the product carries: KOUN, PAJK, TJSJ. Case does not matter, but the three letter form (OUN) matches nothing

Filters combine: a report has to pass every one given.

The window is on valid_at, when the weather happened, not when the report arrived. Offices often issue a report hours after the event, sometimes the next morning, so a late report can arrive already outside a short window. That is deliberate: it describes weather that is over. Ask for a longer hours to catch up on a day.

Reports come back newest first, as a plain JSON array. There is no paging: a response holds at most 1,000 reports, and past that the oldest in the window are the ones left out.

What a response holds

[
  {
    "id": 34564,
    "valid_at": "2026-11-09T18:41:00Z",
    "event": "Flood",
    "category": "flood",
    "office": "KEWX",
    "lat": 29.83,
    "lon": -100.4,
    "city": "16 N Kickapoo Cavern St",
    "county": "Edwards",
    "state": "TX",
    "source": "Emergency Manager",
    "magnitude": null,
    "magnitude_unit": null,
    "magnitude_method": null,
    "magnitude_trace": false,
    "remarks": "EM report of water over area roadways in Edwards County including Highway 377 and RR 674 following prolonged steady rain. Some locations with 2.5 ft of water and extensive ponding along shoulders. Location is approximate."
  },
  {
    "id": 34563,
    "valid_at": "2026-11-09T18:05:00Z",
    "event": "Non-Tstm Wnd Gst",
    "category": "wind",
    "office": "PAJK",
    "lat": 57.05,
    "lon": -135.36,
    "city": "1 W Sitka",
    "county": "Sitka",
    "state": "AK",
    "source": "ASOS/AWOS",
    "magnitude": 54.0,
    "magnitude_unit": "MPH",
    "magnitude_method": "measured",
    "magnitude_trace": false,
    "remarks": null
  },
  "..."
]
field
id stable for the report. A corrected or reissued report updates the same row, so a client can key on it
valid_at when the event happened, UTC. The product states local time; it is converted once, when the report is read
event the office’s own wording, verbatim and unnormalized: Tstm Wnd Gst and Non-Tstm Wnd Gst are different claims. Show this to a reader
category a coarse grouping for colour and icon choice. See categories
office the issuing office, four letters
lat, lon where, as the office gave it
city the office’s location wording, often a distance and bearing from a town ("3 W Midway"). May be cut short by the product’s column width
county, state as the office gave them
source who reported it: Trained Spotter, Emergency Manager, ASOS/AWOS, Public, CoCoRaHS and so on. Also subject to the column width ("Department of Hig")
magnitude the number, if the report has one. Many flood and damage reports do not, and null there means no number was given, not zero
magnitude_unit MPH for wind, INCH for hail, rain and snow, MI for the visibility in a fog report (offices write it bare; the API supplies the unit)
magnitude_method measured, estimated or unknown, from the product’s M, E or U flag. Keep it with the number: a measured 67 mph gust is an instrument reading, an estimated one is a judgement
magnitude_trace true for a trace (of rain or snow): more than nothing, less than the smallest amount the product can express. magnitude is then null
remarks the office’s free text, or null

Categories

category is assigned from the event wording, so it is a grouping, not the office’s own classification. The event string is always there beside it.

category event wording it covers
tornado tornado, waterspout
funnel funnel cloud, wall cloud
hail hail
wind thunderstorm and non thunderstorm wind gusts and damage, downbursts, marine thunderstorm wind, high sustained winds
flood flood, flash flood, coastal flood, storm surge
rain heavy rain, rain
winter snow, sleet, freezing rain, ice storm, blizzard
lightning lightning
fire wildfire
landslide landslide, mudslide, debris flow
other everything else, such as fog

Errors

status
422 hours outside 1 to 72, a bbox that is not four numbers, or an unknown category ("unknown category: hial")

May we use Microsoft Clarity to see how pages are used (clicks, scrolling and replays of a visit, with anything you type hidden), plus a random ID linking that to crash reports? Only to find bugs and confusing screens. Never advertising, never sold.