SkyFeed / Guides

US weather alerts API for agents and apps

To warn a user, pause a delivery route or flag a risk, your code needs the active National Weather Service alerts for a place, sorted by how serious they are.

The problem

The NWS publishes alerts as CAP-based GeoJSON with long descriptions, nested geometry and fields you rarely need. Querying by point or state, filtering the expired ones and ranking by severity is work every integration repeats.

How /alerts answers it

GET /alerts?state=CA takes a US state or territory code (including PR and GU) or a lat and lon pair. It returns the active alerts sorted by severity, each with event (for example Red Flag Warning or Tropical Storm Watch), severity, urgency, certainty, headline, affected area, onset, ends, the issuing office, protective instruction text when present, and the full description. A point query is the better choice for a specific address or route stop, because a state query can return dozens of alerts for places you do not care about.

Request and response

Example: active alerts in California.

$ curl -i "https://skyfeed.imac2014ville.workers.dev/alerts?state=CA"
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi4uLn0=   # base64 JSON: scheme "exact", network eip155:8453,
                                                  # asset USDC, amount 5000 (= $0.005)
# An x402 client signs the payment, then retries with a PAYMENT-SIGNATURE header.

The paid response (abridged to the first alert; the long description field is omitted. The live count changes constantly):

{
  "ok": true,
  "query": { "state": "CA" },
  "count": 26,
  "alerts": [{
    "event": "Tropical Storm Watch",
    "severity": "Severe",
    "urgency": "Future",
    "certainty": "Possible",
    "headline": "Tropical Storm Watch issued October 9 at 7:59AM PDT by NWS San Diego CA",
    "area": "San Diego County Mountains",
    "onset": "2026-10-09T07:59:00-07:00",
    "ends": "2026-10-09T16:00:00-07:00",
    "sender": "NWS San Diego CA",
    "instruction": null
  }],
  "truncated": false,
  "source": "US National Weather Service (public domain)"
}

JavaScript with @x402/fetch

import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

const signer = privateKeyToAccount(process.env.PRIVATE_KEY); // wallet holding USDC on Base
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(signer) }],
});
const res = await pay("https://skyfeed.imac2014ville.workers.dev/alerts?lat=29.7604&lon=-95.3698");
const { count, alerts } = await res.json();
const severe = alerts.filter(a => a.severity === "Extreme" || a.severity === "Severe");
if (severe.length) notify(severe.map(a => a.headline));

Pricing

/alerts costs $0.005 per call. There is no API key and no account: each request is paid in USDC on Base over x402. Malformed input returns 400 and failed lookups return a non-2xx status, so those are not charged.

Limitations

More guides

Sister services