When the sky turns green over a county in Oklahoma and a wedge of rotating cloud touches down, a single sentence—“Tornado Warning”—leaves a National Weather Service forecast office and, within seconds, sets off the sirens, interrupts the broadcast, buzzes the phones, and crackles over the weather radio. That sentence is a federal data record. The NWS issues every official US watch, warning, and advisory as a machine-readable message in a standard format, and our weather_alerts table is a rolling snapshot of roughly 3,000 of them— the nation's active and recently expired hazard messaging, captured as it streams.
This article covers what the alerts feed is and how the National Weather Service fits inside NOAA; the precise vocabulary that separates a watch from a warning from an advisory; the structured fields every alert carries—event type, the severity/urgency/certainty grading, the effective and expiration times, and the affected area; how geography is encoded with NWS zone and county codes in the UGC and SAME systems; the Common Alerting Protocol standard and how the same message feeds the Emergency Alert System, Wireless Emergency Alerts, and NOAA Weather Radio; why this dataset is a live rolling window rather than a deep historical archive and how it complements the NOAA storm-events record; the analytical uses of a national feed of official hazard messages; a Python workflow that pulls active alerts from api.weather.gov and tallies them by event type and state and filters by severity; and the caveats—the snapshot nature, the zone-not-point geography, and the difference between an alert and a verified event—that every analyst must keep in mind.
What the dataset is
The National Weather Service (NWS) is the agency within the National Oceanic and Atmospheric Administration (NOAA), itself part of the Department of Commerce, charged with providing weather, water, and climate forecasts and warnings for the United States. Among its many products, the one with the most direct public-safety consequence is the alert: the official watch, warning, or advisory that tells the public a hazard is possible, likely, or occurring. These alerts cover the full range of weather and hydrologic hazards—tornado, severe thunderstorm, flash flood, river flood, hurricane and tropical storm, storm surge, winter storm and ice, blizzard, excessive heat, wind chill, high wind, dense fog, red flag fire weather, and many more—and a handful of non-weather messages relayed through the same channel.
In our database this live feed is stored as the table weather_alerts, with the grain of one row per alert message, keyed by the alert identifier. Because alerts are issued and then expire, the table is not a cumulative log of every alert ever issued; it is a rolling window of roughly 3,000 active and recently expired messages, refreshed as new alerts come in and old ones age out. The columns capture what kind of hazard the alert is for, how serious and how soon it is, when it takes effect and ends, where it applies, and the message text that the forecaster wrote:
id -- the unique alert identifier (the table key)
event -- human-readable hazard, e.g. "Tornado Warning"
message_type -- Alert, Update, or Cancel
status -- Actual, Exercise, Test, or Draft
category -- Met (meteorological), Geo, Safety, etc.
severity -- Extreme, Severe, Moderate, Minor, Unknown
urgency -- Immediate, Expected, Future, Past, Unknown
certainty -- Observed, Likely, Possible, Unlikely, Unknown
response -- recommended action: Shelter, Evacuate, Avoid, ...
effective -- when the alert takes effect
onset -- when the hazard is expected to begin
expires -- when the alert expires from the active set
ends -- when the hazard itself is expected to end
area_desc -- plain-text list of the affected areas
geocode_ugc -- NWS Universal Geographic Code zone/county list
geocode_same -- SAME (FIPS-based) codes used by NOAA Weather Radio
sender_name -- the issuing NWS forecast office
headline -- one-line summary of the alert
description -- the full narrative text of the hazard
instruction -- the protective-action guidance for the publicThe id is the table key, but the analytically load-bearing fields are event, the trio of severity, urgency, and certainty, the time pair effective/expires, and the geography in geocode_ugc. The event string is the human-readable hazard name a person hears—“Flash Flood Warning,” “Winter Storm Watch”—and it is the natural axis for tallying what is in effect. The message_type distinguishes an original Alert from an Update that supersedes it and a Cancel that ends it early, which matters because a single hazard episode can generate a chain of messages that all share a common reference. Together these fields turn a free-text bulletin into a structured record that a screening system, a dashboard, or an analyst can act on programmatically.
The vocabulary: watch, warning, advisory
The single most important thing to understand about NWS alerts—and the thing the public most often gets wrong—is that the words are not interchangeable. The NWS uses a precise, deliberate vocabulary in which a watch, a warning, and an advisory mean three distinct things, and the difference is the difference between being ready and taking cover.
A watch means that conditions are favorable for the hazard to develop—the ingredients are in place, but the event is not yet imminent or confirmed. The message to the public is be prepared: review your plan, stay informed, be ready to act. A tornado watch, typically issued for a large multi-county area by the Storm Prediction Center, says the atmosphere could produce tornadoes over the next several hours; it does not mean a tornado is on the ground. A warning, by contrast, means the hazard is imminent or already occurring. The message is take action now. A tornado warning, issued by the local forecast office for a much smaller and more specific area, means a tornado has been detected by radar or spotted on the ground and people in the warned area should shelter immediately. The mental model the NWS teaches is the layered one of a watch covering a wide area and a longer time, and a warning fired inside it for the specific place and moment the danger is real.
An advisory covers conditions that are less severe than warning criteria but still significant enough to cause inconvenience or, if unheeded, a hazard—a winter weather advisory for a few inches of snow, a dense fog advisory, a small craft advisory. The message is to use caution and adjust plans. The distinction between advisory-level and warning-level conditions is set by defined criteria that vary by hazard and by region: the snowfall total that triggers a winter storm warning in the mountains of Colorado is different from the total that triggers one on the Gulf Coast, because the same snow does very different things to two populations. This trio—watch, warning, advisory—is the backbone of the entire system, and reading the event field correctly means parsing which of the three a given alert is before drawing any conclusion about how urgent it is.
Severity, urgency, and certainty
Layered on top of the watch/warning/advisory vocabulary is a separate, machine-readable grading scheme that the Common Alerting Protocol standardizes across every alert: severity, urgency, and certainty. These three orthogonal axes are what let an automated system rank and route alerts without parsing the prose, and together they encode the forecaster's judgment about how bad, how soon, and how sure.
Severity describes the magnitude of the threat to life and property, on a scale of Extreme, Severe, Moderate, Minor, and Unknown. A destructive tornado warning or a major hurricane warning carries an Extreme severity; a routine small-craft advisory carries a Minor one. Urgency describes how soon protective action is needed—Immediate (act now), Expected (act soon, within roughly the next hour), Future (act in the foreseeable future), Past, or Unknown. The urgency axis is what separates a warning, which is almost always Immediate or Expected, from a watch, which is usually Future. Certainty describes the forecaster's confidence that the event will occur—Observed (it is happening now, confirmed), Likely, Possible, Unlikely, or Unknown. A tornado warning based on a confirmed ground report is Observed; one based on radar-indicated rotation is Likely; a watch is Possible.
These three fields, plus the response field that names the recommended protective action (Shelter, Evacuate, Avoid, Prepare, Monitor), are the heart of why CAP is a standard worth having. A downstream system—a phone carrier deciding whether to push a Wireless Emergency Alert, an emergency manager building a dashboard, an analyst filtering for the most dangerous messages—can read the structured grading rather than try to interpret free text. The worked example later in this article uses exactly this: it filters the active feed to alerts that are both Severe-or-Extreme in severity and Immediate-or-Expected in urgency, which isolates the action-now tier from the much larger background of advisories and watches without ever looking at the event name. That is the standard doing its job: the same three coded fields mean the same thing on a tornado warning in Kansas and a tsunami warning in Alaska.
Geography: zones, counties, UGC and SAME
An alert is meaningless without a place, and NWS alerts encode geography with a system that predates and underlies the modern map polygons: the zone. The country is divided into public forecast zones—subdivisions of counties, or whole counties, drawn so that areas with similar weather are grouped together—and into corresponding marine, fire-weather, and other specialized zones. An alert is issued for one or more of these zones (or, for some warnings, for the counties themselves), and that membership is what determines who is covered. Each NWS forecast office is responsible for a defined set of zones, its county warning area, which is why the issuing office in sender_name and the zones in the geocode always belong together.
The zones are referenced by two parallel coding systems that appear in the geocode field. The Universal Geographic Code (UGC) is the NWS internal scheme: a code that begins with the two-letter state abbreviation, a letter indicating whether it is a zone (Z) or a county (C), and a three-digit number identifying the specific zone or county—so a code like TXZ123 identifies a particular forecast zone in Texas. The SAME code—Specific Area Message Encoding—is the FIPS-based numeric code used by NOAA Weather Radio and the Emergency Alert System to address an alert to a specific county, so that a weather radio programmed for one county only sounds for alerts that include that county's SAME code. The two systems carry the same geographic intent in different alphabets, and an alert typically lists several of each because a single hazard rarely respects one zone's boundary.
For an analyst, the geocode is the join key to geography, and it has a convenient property the worked example exploits: because every UGC code begins with the state postal abbreviation, a coarse state-level tally of active alerts falls directly out of the codes with no external lookup table. Finer geography—mapping a zone to its actual polygon, or rolling alerts up to a metro area or a watershed—requires joining the UGC or SAME code to the NWS zone shapefiles or to a county crosswalk, but the codes themselves are the durable, stable identifiers that make that join possible. Modern warnings also carry a storm-based polygon—a precise, irregular shape covering only the path of the threat—in addition to the zones, which is why a tornado warning can light up only part of a county; but the zone and county codes remain the backbone of the alerting geography and the thing the feed most reliably provides.
The Common Alerting Protocol and the alert pipeline
The format that holds all of this together is the Common Alerting Protocol (CAP), an open, international standard for exchanging emergency alerts in a single machine-readable structure. CAP is not specific to weather—it is used for all kinds of public warnings—but the NWS adopted it as the carrier for its alerts, which is why every field described above (event, severity, urgency, certainty, the area codes, the effective and expiration times) maps to a defined CAP element. The decisive consequence of using a standard is interoperability: one CAP message, issued once by a forecast office, can be consumed by many different downstream systems without each one needing a bespoke parser.
That is exactly what happens. The same CAP alert that appears in this dataset is the message that feeds the Emergency Alert System (EAS), which interrupts radio and television broadcasts; the Wireless Emergency Alerts (WEA) system, which pushes the short, attention-grabbing messages to mobile phones in the affected area for the most dangerous events; and NOAA Weather Radio, the dedicated radio network that broadcasts continuous weather information and sounds an alarm, addressed by SAME code, when a warning is issued for the listener's county. The Integrated Public Alert and Warning System operated by FEMA is the federal backbone that distributes these alerts across the channels. Because the dataset is the CAP feed itself—the upstream source, not a downstream copy—it is a live snapshot of the nation's official hazard messaging as it is being sent to every one of those channels at once. When you read a row in weather_alerts, you are reading the same record that is, at that moment, buzzing phones and interrupting broadcasts in the zones it names.
A rolling window, not an archive
The defining structural fact about this dataset—and the one that most shapes how it should be used—is that it is a rolling window of active and recently expired alerts, not a deep historical archive. Alerts are issued with an expiration time, and once an alert expires it leaves the active set. The feed at api.weather.gov is built to answer the question “what is in effect right now?”—the operational question that drives the alerting channels—and so our table, captured from that feed, holds the active set plus a tail of recently expired messages, on the order of 3,000 records at any given time. It is a live instrument, not a ledger.
This has a direct and important consequence: you cannot answer a long-run historical question from a single snapshot of this dataset. “How many tornado warnings were issued in the United States last year?” or “has the number of excessive-heat warnings risen over the past decade?” are questions about a population of alerts that have long since expired and dropped off the active feed. To study alerts over time you must either capture the feed repeatedly and accumulate your own time series, or turn to a dataset built for the historical question. For the deep record of what actually happened—the verified storm reports, the damage, the casualties, stretching back half a century—the companion dataset is the NOAA Storm Events Database, which is the after-the-fact archive of weather events and their impacts. The relationship between the two is the relationship between a warning and a verified event: this feed is the real-time message that a hazard may be coming; storm events is the durable record of what the hazard did. They answer different questions, and confusing the two—treating the live alert feed as a historical census, or expecting the storm-events archive to tell you what is in effect this minute—is the most common analytical error.
Analytical uses
A live, national, structured feed of every official hazard message supports a distinctive set of uses, most of which lean on its real-time nature rather than fighting it.
Situational dashboards and operational monitoringare the foundational use. Because the feed is the authoritative current state of US hazard messaging, it is what powers a live map of active warnings, a count of how many people are currently under a tornado watch, or an emergency-management dashboard that shows every alert in a region color-coded by severity. The structured severity, urgency, and certainty fields make it possible to filter to the action-now tier instantly, and the zone geography makes it possible to scope the view to a state, a county warning area, or a single county.
Geographic targeting and notification is the operational complement: filtering the feed to the alerts that include a particular UGC or SAME code is exactly how a notification system decides whom to alert, and the same logic lets an analyst answer “which alerts apply to this address's zone?” Joining the geocodes to population data turns a list of zones into an estimate of exposure —how many people are under each active alert—which is the bridge between a feed of messages and a measure of impact.
Building a longitudinal series by capturing the feedis the use that escapes the snapshot limitation. By polling the active-alerts endpoint on a schedule and storing every new alert by its identifier, an analyst can accumulate a faithful history of issuance over time—event-type frequency, seasonal patterns, the geographic distribution of warnings, the lead time between onset and a warning—that no single snapshot contains. Finally, verification against outcomes closes the loop: aligning the alerts captured over time with the NOAA storm-events record of what actually occurred is how the performance of the warning system itself is measured—how often a warned event verified, how often an event arrived unwarned, and how the lead times are trending—the analysis that turns two complementary federal datasets into an assessment of public-safety effectiveness.
Python workflow: active alerts from api.weather.gov
The script below pulls the currently active alerts from the NWS API, then computes three views: a tally of the active alerts by event type (what hazards are in effect), a tally by state derived directly from the UGC geocodes, and a filtered slice of the most serious messages (those graded both Severe-or-Extreme and Immediate-or-Expected). No API key is required; the NWS asks only that you send a descriptive User-Agent identifying your application so they can reach you and so your requests are less likely to be swept up by a security event. The feed is GeoJSON, with each feature's propertiesobject holding one CAP alert, so the script lifts the properties into a dataframe and works from there. Requirements: requests and pandas.
import requests
import pandas as pd
from collections import Counter
# NWS API -- the official source for active US watches, warnings, and
# advisories. Free, no API key required. A descriptive User-Agent is
# requested by NWS so they can contact you about your application and so
# your traffic is less likely to be caught by a security event.
BASE = "https://api.weather.gov"
HEADERS = {
"User-Agent": "(ai-analytics.org, contact@ai-analytics.org)",
"Accept": "application/geo+json",
}
def active_alerts(params=None):
# /alerts/active returns the currently in-effect alerts as a GeoJSON
# FeatureCollection. Each feature's "properties" is one CAP message.
r = requests.get(f"{BASE}/alerts/active", headers=HEADERS,
params=params or {}, timeout=60)
r.raise_for_status()
feats = r.json().get("features", [])
rows = [f.get("properties", {}) for f in feats]
return pd.DataFrame(rows)
df = active_alerts()
print(f"Active alerts in effect right now: {len(df):,}")
# --- 1. Tally by event type (the human-readable hazard name) ----------
# e.g. "Tornado Warning", "Flood Advisory", "Winter Storm Watch".
print("\nTop 15 active alert types:")
for event, n in df["event"].value_counts().head(15).items():
print(f" {event:<34} {n:>5,}")
# --- 2. Tally by state ------------------------------------------------
# Geography is encoded in geocode -> UGC zone/county codes. The first two
# characters of each UGC code are the state postal abbreviation, so a
# coarse state tally falls out of the geocodes without extra lookups.
state_counter = Counter()
for codes in df.get("geocode", pd.Series(dtype=object)).dropna():
seen = set()
for ugc in (codes or {}).get("UGC", []):
st = str(ugc)[:2]
if st.isalpha():
seen.add(st)
for st in seen:
state_counter[st] += 1
print("\nTop 15 states by number of active alerts:")
for st, n in state_counter.most_common(15):
print(f" {st} {n:>5,}")
# --- 3. Filter to the most serious messages ---------------------------
# CAP grades each alert on severity (Extreme/Severe/Moderate/Minor),
# urgency (Immediate/Expected/Future), and certainty (Observed/Likely/
# Possible). Warnings are the action-now tier; watches mean "be ready".
serious = df[
df["severity"].isin(["Extreme", "Severe"])
& df["urgency"].isin(["Immediate", "Expected"])
]
print(f"\nSevere/Extreme + Immediate/Expected alerts: {len(serious):,}")
for _, row in serious.head(10).iterrows():
area = str(row.get("areaDesc", ""))[:40]
print(f" {row['event']:<28} [{row['severity']}/{row['urgency']}] "
f"exp {str(row.get('expires',''))[:16]} {area}")
# Targeted pulls: the same endpoint accepts query parameters, e.g.
# active_alerts({"area": "TX"}) -- one state
# active_alerts({"event": "Tornado Warning"}) -- one hazard nationwide
# active_alerts({"severity": "Extreme"}) -- highest severity only
Two notes on using this in practice. First, the state tally is deliberately coarse: it counts an alert once per state it touches by reading the two-letter prefix of each UGC code, which is fast and lookup-free but treats a single multi-state alert as appearing in each of its states—the right behavior for “how many active alerts touch this state,” but not a count of distinct alerts. For anything finer than a state roll-up, join the full UGC or SAME codes to the NWS zone and county crosswalk. Second, the endpoint accepts query parameters—area for a state or marine zone, event for a specific hazard nationwide, severity for the highest tier—so most targeted questions are better answered by filtering at the API than by pulling everything and filtering locally. And because the feed is the active set by design, any study of alerts over time must run this capture on a schedule and persist results by alert identifier rather than expecting a single call to contain history.
Limitations and analytical caveats
The alerts feed is the authoritative real-time record of US hazard messaging, but it carries structural features an analyst must internalize before drawing conclusions from it.
It is a snapshot of the active set, not a history.This is the cardinal caveat, restated because it is so easy to violate. The feed answers “what is in effect now,” and expired alerts leave it. Any count of alerts “over the past year,” any trend line, any seasonal comparison, requires a time series the analyst has accumulated by repeated capture—or the NOAA storm-events archive for verified outcomes. A single pull of roughly 3,000 records is a photograph of a moment, and the number itself fluctuates wildly: a quiet day has a few hundred active alerts, while a major winter storm or a severe-weather outbreak can drive the active count far higher. Drawing a conclusion about “how many alerts there are” from one snapshot measures the weather on that day, not anything durable.
Geography is by zone, not by point. An alert applies to forecast zones and counties, which are areas, not coordinates. A zone-based alert tells you the hazard is somewhere in the named zones, not that every location in them is equally at risk—and a storm-based warning polygon, where present, may cover only a sliver of a county the zone codes list in full. Estimating exposure from the geocodes requires joining to the zone geometries and to population, and treating a county as uniformly affected because one of its zones is warned will overstate the footprint. The codes are precise identifiers; the areas they name are coarse relative to where the danger actually is.
An alert is a forecast message, not a verified event.A warning means the NWS judged a hazard imminent or occurring; it does not guarantee the hazard materialized as forecast, and conversely a hazard can occur with little or no warning. The feed is the messaging layer, and messages are issued under uncertainty— the certainty field encodes exactly that. Whether a warned tornado actually touched down, how strong it was, what it damaged: none of that lives in the alert. It lives in the storm-events record, compiled after the fact. Treating the alert feed as a record of what happened, rather than of what was warned, conflates the forecast with the outcome.
Message chains and updates require care. A single hazard episode rarely produces a single message. An initial alert is often followed by updates that extend, shrink, or re-target it, and by a cancellation when the threat passes—each a distinct record, linked by reference. A naive count of rows in the feed therefore over-counts hazard episodes, because one tornado warning that is updated twice is three records. Any analysis that wants to count distinct hazards rather than distinct messages must collapse the chain using the message type and the reference links, not simply count id values.
Held with these caveats in mind, the weather_alerts table is a uniquely immediate resource: a live, structured, nationally complete snapshot of the official watches, warnings, and advisories that the National Weather Service is issuing right now —the same Common Alerting Protocol messages driving the sirens, the broadcasts, the phone alerts, and the weather radios—and the real-time companion to the deep historical record of what the country's weather has actually done.
Related writing
NOAA Storm Events Database: The Federal Record Behind 50 Years of US Weather Disasters — The historical companion to the live alerts feed: where weather_alerts is the real-time message that a hazard may be coming, storm events is the verified, after-the-fact archive of what the hazard did, and aligning the two is how the warning system's performance is measured.
USGS Earthquakes: The Federal Catalog of Every Significant Global Quake — A sister real-time federal hazard feed: like the NWS alerts, the USGS earthquake catalog is a continuously updated public stream of events graded by magnitude and location, and both anchor the kind of geographic, severity-filtered situational analysis this article describes.
FEMA Disaster Declarations: The Federal Database Behind 70 Years of US Natural Disasters — The downstream consequence layer: when the hazards these alerts warn of cause damage at scale, the federal response is a FEMA disaster declaration, and the declarations record is where the warning, the event, and the recovery dollars meet.