---
title: "Search NWS alerts at a point or in a bounding box."
method: GET
path: "/v1/alerts"
tags: ["Alerts"]
---

# Search NWS alerts at a point or in a bounding box.

`GET /v1/alerts`

## Request

- Base URL: `https://api.smarterweather.com`
- URL: `https://api.smarterweather.com/v1/alerts`
- Auth: HTTP bearer

Returns the NWS alerts in effect at a point or inside a bounding
box, now or at a past instant, optionally filtered to exact
event names. Items use the same `Alert` shape as
`GET /v1/weather?include=alerts`, field for field; fetch the
full detail (geometry, affected population) with
`GET /v1/alerts/{id}`.

### Location

Exactly one of:

- `lat` + `lon` — alerts whose area contains the point. Every
  match is returned, newest `effective` first.
- `min_lon`, `min_lat`, `max_lon`, `max_lat` — alerts whose
  area intersects the box. The box must have a non-zero area.
  Results are ordered by severity (`Extreme`, `Severe`,
  `Moderate`, `Minor`, then any other value), then soonest
  `expires`, and capped at 50. `truncated` is `true` when the
  result reached the cap (50): more alerts may exist, and the
  ones left out are the lower-priority ones.

There is no pagination.

### Filters

- `event` — exact NWS event names (e.g. `Tornado Warning`),
  comma-separated or repeated, at most 20.
- `at` — RFC 3339 instant in the past. Returns the alerts that
  were in effect then. Omit it for alerts in effect now. An `at`
  the alerts source rejects is a `400` naming the reason. Items
  returned with `at` are historical snapshots, each as it stood
  at that instant. `GET /v1/alerts/{id}` always returns the
  alert's **current** version, so its detail may have changed
  since (updated, extended or cancelled).

### Caching

Successful responses carry `Cache-Control: max-age=60`, or
`max-age=3600` with `at` (a past snapshot does not change).
The scope is `public` for first-party keys and `private` for
partner keys.

### Coverage

A point outside the 50 US states and DC returns `404`
`outside-coverage` with `next_steps`, and so does an area (a bounding
box) that touches none of the US domains (CONUS, Alaska, Hawaii). A
box that touches one is served as is and may include area outside
the US.

### Auth

Standard sw-api Bearer auth applies.

## Query parameters

- `lat` number, double
- `lon` number, double
- `min_lon` number, double
- `min_lat` number, double
- `max_lon` number, double
- `max_lat` number, double
- `event` string[]
- `at` string, date-time

## Response `200`

Matching alerts, in the order described above. `alerts` is an
empty array when nothing matches.

- AlertsSearchResponse: `GET /v1/alerts` response. `alerts` is always an array, empty when nothing matches.
  - `alerts` Alert[], required
    - `id` string, required: Unique alert identifier (the NWS message id). Pass it to `GET /v1/alerts/{id}` for the full alert.
    - `event` string, required
    - `severity` 'Extreme' | 'Severe' | 'Moderate' | 'Minor' | 'Unknown', required
    - `urgency` 'Immediate' | 'Expected' | 'Future' | 'Past' | 'Unknown', required
    - `certainty` 'Observed' | 'Likely' | 'Possible' | 'Unlikely' | 'Unknown', required
    - `headline` string, required
    - `sender` string, required: Issuing NWS office identifier.
    - `status` string, required: Alert lifecycle status (e.g., `Actual`, `Exercise`, `Test`).
    - `onset` string, date-time, required
    - `ends` string, date-time, required
    - `effective` string, date-time, required
    - `expires` string, date-time, required
    - `expiration` string, date-time, required: Final expiration time used for cache invalidation.
    - `area_desc` string: Human-readable affected area.
    - `highlights` object: Map of salient callouts extracted from the alert text (e.g., `{"hazard": "Strong winds", "impact": "Loose debris possible"}`).
  - `truncated` boolean, required: `true` when the result reached the cap (50); more may exist. Only a bounding-box search is capped, so this is always `false` for a point search. A bounding-box result is ordered by severity, then soonest `expires`, so the alerts left out are the lower-priority ones.

## Other responses

- `400`: Bad request.
- `401`: Missing or invalid API key. Carries a `WWW-Authenticate` challenge and a `next_steps` extension. `recommended` is `device_flow`: the object is a complete no-install mint recipe.
- `402`: Trial key free value ended (lifetime cap spent or key clock expired) while the claim window is still open. Carries `next_steps.recommended = claim` and the per-key claim href.
- `403`: API key lacks the required scope. Carries a `WWW-Authenticate` challenge with `error="insufficient_scope"` and a `next_steps` extension.
- `404`: Resource not found: a location that cannot be resolved (unknown ZIP, unrecognised free-text location), no upstream data for the location, or a missing resource. On a route that checks coverage (its description says so), a location outside the 50 US states and DC returns type `https://smarterweather.com/errors/outside-coverage`; that and the location-not-found problem carry `next_steps` (`recommended = coverage`).
- `429`: Rate limit exceeded. Carries a `next_steps` extension (`recommended: upgrade`, plus `pricing` and `usage`) telling the caller how to lift the limit.
- `500`: Internal server error.
- `502`: Bad gateway. The service received an invalid response from an upstream data source. Transient; clients should retry with backoff.
- `503`: Service unavailable. An upstream dependency is unavailable or shedding load (type `service-unavailable`). Transient; retry with backoff and honor any `Retry-After` header.
- `504`: Gateway timeout. An upstream data source did not respond within the service's budget.

---

[API](https://skmtc.dev/smarterweather/apis/smarter-weather-api.md) · [All operations](https://skmtc.dev/smarterweather/apis/smarter-weather-api/llms.txt) · [OpenAPI document](https://skmtc.dev/smarterweather/apis/smarter-weather-api/revisions/520d55a696e4?raw)
