NWS Weather Scraper: US Forecasts, Alerts & Observations avatar

NWS Weather Scraper: US Forecasts, Alerts & Observations

Pricing

from $0.37 / 1,000 weather scrapeds

Go to Apify Store
NWS Weather Scraper: US Forecasts, Alerts & Observations

NWS Weather Scraper: US Forecasts, Alerts & Observations

Scrape US National Weather Service forecasts, hourly outlooks, active alerts and station observations by coordinate or zone. No API key, no proxy, no browser.

Pricing

from $0.37 / 1,000 weather scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Share

NWS Weather Scraper: Twelve-hour and hourly forecasts, active watches and warnings, and the latest reading from the nearest station, for any US location

Pulls National Weather Service data for any US location: twelve-hour and hourly forecasts, active watches and warnings, and the latest reading from the nearest observation station.

The NWS publishes everything through api.weather.gov, a public API built for programmatic use. There's no key, no quota and, so there's nothing for a browser or a proxy to solve. A four-location forecast run finishes in about two seconds. The one thing NWS asks for is a User-Agent that identifies you, which this Actor sends on every request.

Agent skill: SKILL.md

https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/nws-weather-scraper.md

What you get

FieldWhat it holds
location, locationTypeThe location as normalised, and whether it resolved as a point or a zone
latitude, longitudeCoordinates as sent to NWS (null for zone codes)
city, stateNearest named place for points; zone name and state for zones
gridId, gridX, gridYThe NWS forecast grid cell the point resolved to
forecastOffice, timeZone, radarStationIssuing WFO, IANA timezone, covering radar
dataType, unitsWhich product was fetched, and in which unit system
temperature, temperatureUnit, windSpeed, windDirectionHeadline conditions from the first forecast period
shortForecast, detailedForecastThe one-line and full narrative for that period
forecastPeriods, periodCountEvery period returned, capped by maxPeriods
observationStationNearest station plus its latest temperature, dewpoint, humidity, wind, pressure and visibility
alerts, alertCountActive alerts covering the location, with event, severity, urgency, headline, area, onset, expiry and full text
forecastUrl, updatedAtSource URL and the timestamp NWS stamped on the product
scrapedAtRun timestamp

RUN_SUMMARY in the key-value store holds per-run counts, the settings you used, and any location that failed.

Use cases

  • Demand forecasting. Join daily highs against store-level sales history.
  • Field operations. Check tomorrow's conditions across every depot before dispatch.
  • Event alerting. Poll dataType: "alerts" on a schedule and page on any Severe or Extreme event.
  • Risk and insurance. Build a warning history for a portfolio of insured sites.
  • Newsroom monitoring. Watch heat, flood and winter-storm advisories across a set of counties.

Quick start

Two cities, standard forecast:

{
"locations": ["39.7456,-97.0892", "40.7128,-74.0060"]
}

Hourly detail in metric, no alerts, one day of periods:

{
"locations": ["47.6062,-122.3321", "37.7749,-122.4194"],
"dataType": "hourly",
"units": "si",
"includeAlerts": false,
"maxPeriods": 24
}

Alert monitoring across a set of forecast zones:

{
"locations": ["KSZ009", "TXZ248", "FLZ173"],
"dataType": "alerts",
"contactEmail": "ops@example.com"
}

Input

FieldTypeDefaultNotes
locationsarrayrequired"lat,lon" strings or NWS zone codes such as KSZ009 or KSC201. Mixed input is fine.
dataTypestringforecastforecast, hourly, alerts or observations.
unitsstringusus for F, mph and inHg; si for C, km/h and Pa.
includeAlertsbooleantrueAttach active alerts to every record. Always on when dataType is alerts.
maxPeriodsinteger24Cap stored forecast periods per location. 0 means keep them all.
contactEmailstring""Added to the User-Agent so NWS can contact you about heavy usage.

units only affects gridpoint products. Zone-code forecasts are text only: NWS rejects a units parameter on them and returns no numeric temperature, so temperature is null and the narrative arrives in the forecaster's own units.

Output example

{
"location": "40.7128,-74.006",
"locationType": "point",
"latitude": 40.7128,
"longitude": -74.006,
"city": "New York",
"state": "NY",
"gridId": "OKX",
"gridX": 33,
"gridY": 42,
"forecastOffice": "OKX",
"timeZone": "America/New_York",
"radarStation": "KDIX",
"dataType": "forecast",
"units": "us",
"temperature": 90,
"temperatureUnit": "F",
"windSpeed": "6 to 10 mph",
"windDirection": "SW",
"shortForecast": "Mostly Sunny",
"detailedForecast": "Mostly sunny, with a high near 90. Heat index values as high as 102. Southwest wind 6 to 10 mph.",
"forecastPeriods": [
{
"number": 1,
"name": "Today",
"startTime": "2026-08-06T07:00:00-04:00",
"endTime": "2026-08-06T18:00:00-04:00",
"isDaytime": true,
"temperature": 90,
"temperatureUnit": "F",
"probabilityOfPrecipitation": { "unitCode": "wmoUnit:percent", "value": 9 },
"windSpeed": "6 to 10 mph",
"windDirection": "SW",
"shortForecast": "Mostly Sunny",
"detailedForecast": "Mostly sunny, with a high near 90."
}
],
"periodCount": 4,
"observationStation": null,
"alerts": [
{
"id": "urn:oid:2.49.0.1.840.0.c1834a44913d904db6ce91b95b70d126406790b2.004.1",
"event": "Heat Advisory",
"severity": "Moderate",
"urgency": "Expected",
"certainty": "Likely",
"headline": "Heat Advisory issued August 6 at 2:26AM EDT until August 7 at 8:00PM EDT by NWS Upton NY",
"areaDesc": "New York (Manhattan); Bronx; Richmond (Staten Is.); Kings (Brooklyn); Northern Queens; Southern Queens",
"onset": "2026-08-06T11:00:00-04:00",
"expires": "2026-08-06T10:30:00-04:00",
"senderName": "NWS Upton NY",
"description": "* WHAT.Heat index values up to 104 expected."
}
],
"alertCount": 1,
"forecastUrl": "https://api.weather.gov/gridpoints/OKX/33,42/forecast?units=us",
"updatedAt": "2026-08-06T09:41:52+00:00",
"scrapedAt": "2026-08-06T11:35:21.410Z"
}

With dataType: "observations" the observationStation object is populated instead of forecastPeriods:

{
"stationId": "KMYZ",
"stationName": "Marysville Municipal Airport",
"timestamp": "2026-08-06T10:55:00+00:00",
"textDescription": "Fog/Mist",
"temperature": { "value": 68, "unit": "F" },
"dewpoint": { "value": 64.4, "unit": "F" },
"relativeHumidity": { "value": 88.27, "unit": "%" },
"windSpeed": { "value": 4.7, "unit": "mph" },
"windDirection": { "value": 80, "unit": "deg" },
"windGust": null,
"barometricPressure": { "value": 30.03, "unit": "inHg" },
"visibility": { "value": 3, "unit": "mi" }
}

Finding a location code

Coordinates are the simplest input, and anything you can read off a map works. Zone codes are useful when you want an official NWS area rather than a single point.

Code shapeMeaningExample
SSZnnnPublic forecast zoneKSZ009 (Washington County, KS)
SSCnnnCounty zoneKSC201
SSZnnn (fire)Fire weather zoneKSZ009

To find the zone for a point, run the Actor once with coordinates and read forecastUrl, or open https://api.weather.gov/points/{lat},{lon} and look at properties.forecastZone. Full zone URLs are accepted too, because the Actor takes the last path segment.

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~nws-weather-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"locations": ["40.7128,-74.0060", "41.8781,-87.6298"],
"dataType": "forecast",
"units": "us",
"maxPeriods": 8
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/nws-weather-scraper').call({
locations: ['40.7128,-74.0060', '47.6062,-122.3321'],
dataType: 'forecast',
includeAlerts: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const r of items) {
console.log(`${r.city}, ${r.state}: ${r.temperature}${r.temperatureUnit}, ${r.shortForecast} (${r.alertCount} alerts)`);
}

Limits and behaviour

  • Every point costs two hops. /points/{lat},{lon} resolves a 2.5 km grid cell, and the forecast URL it returns is fetched second. The Actor follows whatever URL NWS hands back rather than building gridpoint URLs itself, so office re-gridding never breaks a run.
  • Coordinates are rounded to four decimals. Anything finer gets a 301 redirect to the nearest supported point, and rounding up front saves the round trip.
  • Coverage is US only. A point outside NWS coverage returns 404 with InvalidPoint, lands in RUN_SUMMARY.failures, and the run continues.
  • A missing User-Agent is a 403. NWS refuses anonymous clients outright, so the Actor always identifies itself, and contactEmail puts your address in the header.
  • Transient errors get retried. 429s and 5xx responses get three attempts with linear backoff, while 400 and 404 are treated as fatal for that location only.
  • Public data only. NWS output is US government work in the public domain.

FAQ

Do I need an API key? No. You supply no credentials.

Do I need a proxy? No. Proxy configuration is not required to run this Actor.

Does it work outside the United States? No. NWS covers US states, territories and coastal waters only, and other coordinates return 404. For worldwide coverage use the Open-Meteo Scraper below.

Why is temperature null for a zone code? Zone forecasts are the forecaster's narrative text with no structured values. Pass coordinates when you need numbers.

How current is the data? Gridpoint forecasts are re-issued several times a day, alerts are effectively real time, and station observations update roughly hourly. updatedAt carries the timestamp NWS stamped on the product it served.

Can I schedule it? Yes, and that is the intended use. There is no quota to exhaust, so hourly or even quarter-hourly alert sweeps are fine.