Obscura

NWS Alerts

Active weather alerts and warnings from the U.S. National Weather Service.

nws_alerts — the dataset name to pass to the Obscura API.

Category Physical Columns 21 Refresh Every 6 hours Point-in-time available_date

What one row means

One row is a single active National Weather Service CAP (Common Alerting Protocol) alert — e.g. a Tornado Warning, Small Craft Advisory, or Special Weather Statement for one issuing office/area — as returned by the current snapshot of api.weather.gov/alerts/active, upserted on the alert's stable id and refreshed in place on every subsequent poll while it remains active.

One row per one row per currently-or-recently-active NWS CAP alert, keyed by id (the alert's GeoJSON feature URI); no history of past alert states is retained, only the latest-seen values per id.

Point-in-time availability

Every Obscura dataset carries available_date: the calendar day the publisher made the row available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the same thing on every dataset in the catalog.

For nws_alerts: snapshot: available_date = COALESCE(captured_date, synced_at::date), the date this poller captured the active-alerts feed. Equal to ingestion time on a live poll; on a bronze replay it is the original poll day, never the replay day.

Refresh cadence

Obscura refreshes nws_alerts every 6 hours — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.

Schema — 21 columns

The full public column list for nws_alerts, with the meaning of every field. The same schema is served unauthenticated at https://api.obscura.trade/v1/catalog/nws_alerts.

ColumnTypeDescription
idtext · not nullPrimary key: the NWS alert's full GeoJSON feature `id`, a URI like 'https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.<uuid>.<rev>.<seq>'. Stable across a single alert's lifecycle; a corrected/updated CAP message on the same underlying hazard gets a new suffix.
eventtextNWS event/product name from CAP properties.event, e.g. 'Small Craft Advisory', 'Tornado Warning', 'Special Weather Statement'.
severitytextExtreme / Severe / Moderate / Minor / Unknown. Mutable: refreshed on every re-poll of an existing alert id.
certaintytextObserved / Likely / Possible / Unlikely / Unknown — NWS's confidence the described hazard will occur. Refreshed on every re-poll.
urgencytextImmediate / Expected / Future / Past / Unknown — how soon responsive action is needed. Refreshed on every re-poll.
categorytextCAP category code, e.g. 'Met' (meteorological), 'Geo', 'Safety'. Set once at first insert; not updated on subsequent polls.
statustextCAP properties.status: Actual / Exercise / System / Test / Draft — the live active feed mixes real alerts with keepalive Test messages, so this is the filter that keeps test traffic out of the real alert stream. Refreshed on re-poll.
message_typetextCAP properties.messageType: Alert / Update / Cancel / Ack / Error — flags whether this message is a new alert or a cancellation/correction of an existing one. Refreshed on re-poll (an alert can flip to Cancel).
descriptiontextCAP properties.description: the full multi-paragraph free-text alert body — the substantive NLP text payload (`headline` is only a one-liner). Set once at first insert.
instructiontextCAP properties.instruction: free-text protective-action guidance ("Turn around, don't drown…"). Set once at first insert.
responsetextCAP properties.response (responseType): Avoid / Shelter / Evacuate / Execute / Monitor / None — the categorical recommended action, not derivable from `event`. Refreshed on re-poll.
sender_nametextCAP properties.senderName: the issuing NWS office, e.g. 'NWS Albuquerque NM'. An entity attribute otherwise only buried in `headline` free text. Set once at first insert.
area_desctextFree-text NWS area description, e.g. a county/zone name or coastal segment — the human-readable geographic scope of the alert. Set once at insert, not updated on re-poll.
headlinetextCAP headline: a human-readable one-line summary combining event, issuing office, and effective/expiry window as free text. Set once at insert, not updated on re-poll.
event_timetimestamp with time zoneThe timestamp NWS designates as when the described hazard becomes/became effective (CAP properties.effective). A natural event timestamp — not the public-availability moment, which is `synced_at` / `available_date`. Set once at first insert of a given alert id.
expirestimestamp with time zoneCAP properties.expires — the timestamp after which this alert is no longer active/valid. Kept fresh via upsert since NWS commonly extends/shortens an alert's expiry across polls of the same id.
senttimestamp with time zoneCAP properties.sent — the moment the CAP message was disseminated (issuance time). A better public-availability proxy than `synced_at` and distinct from `event_time` (effective). Refreshed on re-poll.
onsettimestamp with time zoneCAP properties.onset — the timestamp the described hazard is expected to begin, distinct from `event_time` (message-effective). Refreshed on re-poll.
endstimestamp with time zoneCAP properties.ends — the timestamp the described hazard is expected to end, distinct from `expires` (message-validity end). Refreshed on re-poll.
captured_datedateThe UTC calendar day the active-alerts feed was POLLED — the day this alert became knowable to us. `Utc::now().date_naive()` on a live run, `BronzeObject::captured_day()` on a bronze replay, so re-parsing an old snapshot keeps its original date instead of stamping the replay day. Deliberately NOT `sent` (the CAP dissemination instant): adopting `sent` would move live values — an alert sent at 23:50 UTC and polled after midnight would shift a day earlier — so `sent` stays a natural column and this one carries our own capture provenance. NULL on rows written before migration 000175, where `available_date` falls back to `synced_at::date` — the same value for a live poll.
available_datedatePUBLIC-availability date = `COALESCE(captured_date, synced_at::date)` — the date this poller observed the alert. DB-generated (STORED), read-only; the point-in-time column to filter/join on — NEVER `event_time`'s date.

Access nws_alerts

Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.

import obscura

client = obscura.Client("obs_live_…")

df = client.query(
    dataset="nws_alerts",
    start="2024-01-01",
)

Create a free account Browse all 95 datasets

Frequently asked questions

What is in the nws_alerts dataset?

Active weather alerts and warnings from the U.S. National Weather Service. One row is a single active National Weather Service CAP (Common Alerting Protocol) alert — e.g. a Tornado Warning, Small Craft Advisory, or Special Weather Statement for one issuing office/area — as returned by the current snapshot of api.weather.gov/alerts/active, upserted on the alert's stable id and refreshed in place on every subsequent poll while it remains active.

How do I avoid look-ahead bias with nws_alerts?

Filter on nws_alerts.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — snapshot: available_date = COALESCE(captured_date, synced_at::date), the date this poller captured the active-alerts feed. Equal to ingestion time on a live poll; on a bronze replay it is the original poll day, never the replay day. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get nws_alerts?

As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="nws_alerts". The column schema is public at https://api.obscura.trade/v1/catalog/nws_alerts.

How often is nws_alerts updated?

Obscura refreshes nws_alerts on a every 6 hours schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.

Related datasets

Flight ActivityAircraft positions and flights from the OpenSky network of ADS-B receivers. USGS EarthquakesEarthquakes worldwide with location, depth and magnitude, from the USGS. Weather DailyDaily weather by city worldwide from Open-Meteo: temperature, precipitation, wind and more. Weather HourlyHourly weather by city worldwide from Open-Meteo.