# US Weather Forecast & Alerts Scraper - NWS API, $1/1K (`plotpointtech/us-weather-forecast-alerts`) Actor

Official National Weather Service 7-day and hourly forecasts, current conditions and active alerts for any US address, ZIP, city or lat/lon. Temps in F and C, severity filters, new-alert monitoring. $1 per 1,000 records.

- **URL**: https://apify.com/plotpointtech/us-weather-forecast-alerts.md
- **Developed by:** [Plot Point Technologies](https://apify.com/plotpointtech) (community)
- **Categories:** Automation, Developer tools, Integrations
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.62 / 1,000 weather records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## US Weather Forecast & Alerts Scraper (National Weather Service API)

**Get the official National Weather Service 7-day forecast, hourly forecast, current conditions and active weather alerts for any US address, ZIP code, city, coordinates or NWS zone, as clean JSON or spreadsheet rows.** Temperatures come in both °F and °C, wind is parsed into numbers, and alerts include the headline, full description, safety instructions, effective and expiry times and affected areas. A monitoring mode remembers alert IDs between scheduled runs so you only get new alerts. **$1 per 1,000 records.**

### What does this US weather scraper do?

- **Reads the official NWS API** (api.weather.gov), the same data behind weather.gov. US government data, public domain, no API key.
- **Accepts locations in any common form**: `latitude,longitude`, a 5-digit ZIP code, `City, ST`, a full US street address, or an NWS zone ID (`NYZ072`, `TXC453`). Addresses are geocoded with the free US Census Geocoder; ZIP codes and cities with Census TIGERweb.
- **Collects five data types** (pick any):
  - **7-day forecast**: 14 day/night periods with temperature, precipitation chance, wind and the full written forecast.
  - **Hourly forecast**: up to about 156 hours with temperature, dewpoint, humidity, precipitation chance and wind.
  - **Current conditions** from the nearest reporting station: temperature, dewpoint, humidity, wind and gusts, pressure, visibility, wind chill / heat index, precipitation in the last hour and the raw METAR. If the nearest station has no recent report, the next nearest is used.
  - **Active alerts** (warnings, watches, advisories) for each location's point or zone, or for whole states, with severity, urgency, certainty and event-type filters.
  - **Raw gridpoint data** (advanced): the NWS numeric forecast grids, such as hourly temperature, wind gust, rainfall and snowfall amounts.
- **Monitors alerts**: with **Only new alerts** turned on and a schedule, each run outputs only alerts it has not reported before.
- **Respects NWS guidance**: identifies itself with a contact User-Agent, reuses point and forecast lookups within a run, limits concurrent requests and backs off on rate-limit or server errors.

### Who uses it?

- **Logistics and fleet teams** checking wind, snow and storm warnings along delivery routes and at depots.
- **Event organizers and venues** watching rain chances and heat for outdoor dates.
- **Insurance and claims teams** logging which alerts were active at insured addresses and when.
- **Construction and field-service companies** planning concrete pours, roofing, crane work and technician schedules around wind, rain and temperature.
- **Operations and safety teams** feeding new severe-weather alerts into Slack, email, ticketing or SMS.
- **Developers and AI agents** that need a clean, consistent US weather feed without handling the NWS points-to-gridpoint lookups themselves.

### How to use it

1. Click **Try for free** (or **Start**).
2. Enter your **Locations**, one per line, for example `Denver, CO`, `78701`, `40.7128,-74.0060` or `1600 Pennsylvania Ave NW, Washington, DC 20500`.
3. Choose the **Data to collect**: forecast, hourly forecast, current conditions, alerts and/or gridpoint data.
4. Optional: add **Alerts for whole states** (e.g. `TX`, `FL`) and alert filters (severity, urgency, certainty, event words such as `Tornado` or `Flood`).
5. For alert monitoring, turn on **Only new alerts** and add a schedule (for example every 15 minutes) in Apify Console.
6. Run it and download the results as JSON, CSV or Excel, or connect them to your other tools.

### Input example

```json
{
  "locations": ["New York, NY", "Denver, CO", "78701", "40.7128,-74.0060"],
  "dataTypes": ["forecast", "hourly", "observations", "alerts"],
  "alertStates": ["TX"],
  "hourlyHours": 24,
  "forecastOutput": "perLocation",
  "alertSeverity": ["Extreme", "Severe"],
  "onlyNewAlerts": false,
  "maxResults": 1000
}
```

| Field | What it does |
|---|---|
| `locations` | Lat/lon, ZIP, `City, ST`, street address or NWS zone ID, one per line. |
| `dataTypes` | `forecast`, `hourly`, `observations`, `alerts`, `gridpoint`. Default: forecast + alerts. |
| `alertStates` | Two-letter state (or marine area) codes for all active alerts in that state. |
| `hourlyHours` | Hours of hourly forecast to keep (1 to 156, default 48). |
| `forecastOutput` | `perLocation` (one record with a list of periods, cheapest) or `perPeriod` (one flat row per period). |
| `alertSeverity`, `alertUrgency`, `alertCertainty` | Keep only alerts with these CAP values. Empty means all. |
| `alertEvents` | Keep only alerts whose event name contains one of these words, e.g. `Tornado Warning`, `Flood`, `Heat`. |
| `onlyNewAlerts` | Monitoring mode: output only alerts not seen in earlier runs. |
| `alertStoreName` | Name of the key-value store that remembers seen alert IDs (one name per monitor). |
| `includeTestAlerts` | Also return test and exercise alerts (off by default). |
| `gridpointLayers` | Layers for raw gridpoint data, or `all`. |
| `maxResults` | Stop after this many records. |

### Output example

This is a real record from the default run (forecast for Denver, CO; periods shortened to two of 14):

```json
{
  "input": "Denver, CO",
  "locationType": "city",
  "matchedName": "Denver city, CO",
  "latitude": 39.7618502,
  "longitude": -104.8811054,
  "nwsCity": "Denver",
  "nwsState": "CO",
  "gridId": "BOU",
  "gridX": 67,
  "gridY": 62,
  "forecastOffice": "BOU",
  "forecastZone": "COZ040",
  "countyZone": "COC031",
  "fireWeatherZone": "COZ240",
  "timeZone": "America/Denver",
  "radarStation": "KFTG",
  "dataType": "forecast",
  "forecastGeneratedAt": "2026-11-01T19:12:04+00:00",
  "forecastUpdatedAt": "2026-11-01T18:47:11+00:00",
  "elevationM": 1615.1,
  "currentPeriodName": "This Afternoon",
  "currentTemperatureF": 63,
  "currentTemperatureC": 17.2,
  "currentShortForecast": "Chance Light Rain",
  "currentPrecipitationProbability": 35,
  "currentWind": "S 7 to 10 mph",
  "maxPrecipitationProbability": 65,
  "highsF": [63, 54, 58, 56, 56, 57, 55],
  "lowsF": [46, 42, 37, 38, 36, 37, 36],
  "periodCount": 14,
  "periods": [
    {
      "number": 1,
      "name": "This Afternoon",
      "startTime": "2026-11-01T12:00:00-07:00",
      "endTime": "2026-11-01T18:00:00-07:00",
      "isDaytime": true,
      "temperatureF": 63,
      "temperatureC": 17.2,
      "temperatureTrend": null,
      "precipitationProbability": 35,
      "windSpeed": "7 to 10 mph",
      "windSpeedMphMin": 7,
      "windSpeedMphMax": 10,
      "windSpeedKmhMax": 16.1,
      "windDirection": "S",
      "shortForecast": "Chance Light Rain",
      "detailedForecast": "A chance of rain after 4pm. Mostly cloudy. High near 63, with temperatures falling to around 58 in the afternoon. South wind 7 to 10 mph, with gusts as high as 16 mph. Chance of precipitation is 40%.",
      "icon": "https://api.weather.gov/icons/land/day/rain,40?size=medium"
    },
    {
      "number": 2,
      "name": "Tonight",
      "startTime": "2026-11-01T18:00:00-07:00",
      "endTime": "2026-11-02T06:00:00-07:00",
      "isDaytime": false,
      "temperatureF": 46,
      "temperatureC": 7.8,
      "precipitationProbability": 35,
      "windSpeed": "6 mph",
      "windDirection": "SSW",
      "shortForecast": "Chance Light Rain",
      "detailedForecast": "A chance of rain. Mostly cloudy, with a low around 46. South southwest wind around 6 mph. Chance of precipitation is 40%. New rainfall amounts less than a tenth of an inch possible."
    }
  ],
  "fetchedAt": "2026-11-01T19:12:04Z"
}
```

An alert record (from a test run, description shortened) looks like this:

```json
{
  "input": "AKZ318",
  "locationType": "zone",
  "matchedName": "Municipality of Skagway, AK",
  "alertScope": "zone:AKZ318",
  "dataType": "alert",
  "alertId": "urn:oid:2.49.0.1.840.0.8d2524301db1fde3dde29af7d5519d584990a2c7.001.1",
  "event": "Winter Storm Warning",
  "headline": "Winter Storm Warning issued November 1 at 8:52AM AKST until November 1 at 3:00PM AKST by NWS Juneau AK",
  "severity": "Severe",
  "urgency": "Expected",
  "certainty": "Likely",
  "messageType": "Update",
  "effective": "2026-11-01T08:52:00-09:00",
  "expires": "2026-11-01T15:00:00-09:00",
  "areaDesc": "Municipality of Skagway",
  "areas": ["Municipality of Skagway"],
  "affectedZones": ["AKZ318"],
  "description": "* WHAT...Heavy snow expected. Total snow accumulations of 9 to 14 inches possible. ...",
  "instruction": "If you must travel, keep an extra flashlight, food, and water in your vehicle in case of an emergency. ...",
  "senderName": "NWS Juneau AK",
  "eventCode": "WSW",
  "alertUrl": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.8d2524301db1fde3dde29af7d5519d584990a2c7.001.1"
}
```

Every record also carries the location fields (`input`, `matchedName`, `latitude`, `longitude`, `nwsCity`, `nwsState`, grid and zone IDs, `timeZone`). Current-conditions records add `stationId`, `stationName`, `stationDistanceKm`, `observedAt`, `textDescription`, `temperatureF/C`, `dewpointF/C`, `relativeHumidity`, `windSpeedMph/Kmh`, `windGustMph/Kmh`, `windDirection`, `pressureHpa`, `pressureInHg`, `visibilityMiles/Km`, `windChillF`, `heatIndexF`, `precipitationLastHourIn/Mm` and `rawMetar`.

### How much does it cost?

You pay **$1 per 1,000 records** (plus a negligible start fee), with volume discounts on higher Apify plans. One record is one location's forecast, one hourly forecast, one current-conditions report, one gridpoint data set, or one alert.

- Forecast + alerts for 50 stores, with 10 active alerts in total: about 60 records = **$0.06**.
- Daily forecast, hourly and current conditions for 200 job sites for a month: 200 x 3 x 30 = 18,000 records = **$18**.
- Monitoring every 15 minutes for new severe alerts in two states, about 30 new alerts a day: about 900 records a month = **$0.90**. Runs with no new alerts cost only the start fee.

The **per-period** layout charges every forecast period as its own record; keep the default **per-location** layout for the lowest cost.

### Use it via API, Make, Zapier, n8n or an AI agent

Run it from the Apify API or client libraries (JavaScript, Python) and read the results from the run's dataset. It works with the Apify integrations for Make, Zapier, n8n, Google Sheets, Slack and webhooks, so a scheduled monitor can post each new alert to a channel. AI agents can call it through the Apify MCP server.

### FAQ

**Is this legal to use?**
Yes. The NWS API is an official, free, public US government service intended for automated use, and NWS data is in the public domain. The tool identifies itself with a contact User-Agent as NWS asks. You are responsible for how you use the data; NWS forecasts and alerts are not a replacement for official emergency instructions.

**Does it cover locations outside the US?**
No. NWS covers the United States and its territories (and nearby coastal waters). Points outside its area are logged and skipped, not charged.

**How fresh is the data?**
Every run queries the live API. `forecastUpdatedAt` shows when NWS last updated the forecast; `observedAt` shows when the station reported. Forecasts usually update every hour or few hours, observations roughly hourly.

**How does "Only new alerts" work?**
Seen alert IDs are stored in a named key-value store in your Apify account and expire a few days after the alert ends. When NWS updates an alert (for example extends it), the update has a new ID and is reported again; `messageType` tells you whether it is an `Alert`, `Update` or `Cancel`.

**Why are there no alert records?**
There may simply be no active alerts for that place, or your filters removed them. The log shows how many alerts were active for each location before filters.

**How accurate is the geocoding?**
Street addresses use the Census address-range geocoder; ZIP codes use the centre of the Census ZIP Code Tabulation Area; cities use the Census place's internal point. `matchedName` shows what was matched. For exact sites, give coordinates.

### Related tools from Plot Point Technologies

- [Building Permits Scraper - Construction Leads, 13 Cities](https://apify.com/plotpointtech/building-permits-feed): new building permits from 13 US and Canadian cities in one format.
- [Local Business Leads Scraper - MX-Checked Emails & Phones](https://apify.com/plotpointtech/local-business-leads): local businesses by category and city.
- [RSS Feed Reader & Monitor - Any Feed to JSON](https://apify.com/plotpointtech/rss-feed-reader-monitor): monitor any RSS feed and get only new items.
- [News Scraper - Worldwide News Search by Keyword](https://apify.com/plotpointtech/worldwide-news-search): news coverage of storms and events by keyword.

Plot Point Technologies is not affiliated with the National Weather Service, NOAA or the US Census Bureau.

***

If this tool saved you time, we would be grateful for a short review on this page; it helps other people find it. If something did not work as expected, please open an issue on the **Issues** tab and we will look into it quickly.

# Actor input Schema

## `locations` (type: `array`):

One location per line. Accepted: latitude,longitude (e.g. 40.7128,-74.0060), a 5-digit ZIP code (e.g. 78701), 'City, ST' (e.g. Denver, CO), a US street address (e.g. 1600 Pennsylvania Ave NW, Washington, DC 20500), or an NWS zone ID (e.g. NYZ072 forecast zone or TXC453 county zone). Addresses, ZIP codes and cities are geocoded with the free US Census Geocoder / TIGERweb services.

## `dataTypes` (type: `array`):

Each selected data type produces its own record(s) per location. 'Active alerts' gives one record per alert.

## `alertStates` (type: `array`):

Two-letter state codes (e.g. TX, FL) to get ALL active alerts in that state, in addition to alerts for the locations above. Marine area codes (e.g. GM, PZ) also work.

## `hourlyHours` (type: `integer`):

How many hours of the hourly forecast to keep (NWS provides up to about 156).

## `forecastOutput` (type: `string`):

Per location keeps it cheap (1 record = whole forecast). Per period gives flat spreadsheet rows but each period is a billed record.

## `alertSeverity` (type: `array`):

Keep only alerts with these severities. Empty = all.

## `alertUrgency` (type: `array`):

Keep only alerts with these urgencies. Empty = all.

## `alertCertainty` (type: `array`):

Keep only alerts with these certainties. Empty = all.

## `alertEvents` (type: `array`):

Keep only alerts whose event name contains one of these words, e.g. Tornado Warning, Flood, Winter Storm, Heat. Empty = all.

## `onlyNewAlerts` (type: `boolean`):

Remember alert IDs between runs in a named key-value store and output only alerts not seen in earlier runs. Use with a schedule (e.g. every 15 minutes) to get a feed of new alerts. Updated alerts get a new ID from NWS and are reported again.

## `alertStoreName` (type: `string`):

Name of the key-value store that remembers seen alerts. Use a different name for each separate monitor.

## `includeTestAlerts` (type: `boolean`):

By default only alerts with status 'Actual' are returned.

## `gridpointLayers` (type: `array`):

Only for 'Raw gridpoint data'. NWS layer names, e.g. temperature, windGust, quantitativePrecipitation, snowfallAmount, skyCover. Enter 'all' for every layer. Empty = a standard set of 13 layers.

## `maxResults` (type: `integer`):

Stop after this many records (you pay per record).

## Actor input object example

```json
{
  "locations": [
    "New York, NY",
    "Denver, CO"
  ],
  "dataTypes": [
    "forecast",
    "alerts"
  ],
  "hourlyHours": 48,
  "forecastOutput": "perLocation",
  "onlyNewAlerts": false,
  "alertStoreName": "nws-alert-monitor",
  "includeTestAlerts": false,
  "maxResults": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locations": [
        "New York, NY",
        "Denver, CO"
    ],
    "dataTypes": [
        "forecast",
        "alerts"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plotpointtech/us-weather-forecast-alerts").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "locations": [
        "New York, NY",
        "Denver, CO",
    ],
    "dataTypes": [
        "forecast",
        "alerts",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("plotpointtech/us-weather-forecast-alerts").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locations": [
    "New York, NY",
    "Denver, CO"
  ],
  "dataTypes": [
    "forecast",
    "alerts"
  ]
}' |
apify call plotpointtech/us-weather-forecast-alerts --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plotpointtech/us-weather-forecast-alerts"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6LDDj5tNmdBiaickg/builds/FuS9of0VSfikhWswA/openapi.json
