Retrieving Weather Forecasts from the National Weather Service API
Requirements: IPWorks
Contents
Introduction
The National Weather Service (NWS) provides free access to its forecasts, observations, and alerts for the United States through a REST API at https://api.weather.gov. The API returns JSON data (in the GeoJSON format), and does not require an API key.
This article shows how to retrieve the forecast for a location using the HTTP component to send requests to the API, and the JSON component to parse the responses. Retrieving a forecast takes two requests:
- Request the metadata for a latitude and longitude from the /points endpoint, which returns the URL of the forecast for the area that contains that point.
- Request the forecast from that URL, which returns a list of forecast periods (e.g., "Tonight", "Friday", "Friday Night").
Finding the Forecast for a Location
The NWS asks applications to identify themselves using the User-Agent header, with contact information in case of problems (e.g., the name of the application and an email address). With the HTTP component, the header is set using the UserAgent configuration setting.
The /points/{latitude},{longitude} endpoint returns information about a location, including the URL of its forecast in the properties.forecast field. The latitude and longitude are specified in decimal degrees, with no more than four decimal places. The API responds to more precise coordinates with a redirect to the rounded location, which the HTTP component does not follow by default (see the FollowRedirects property).
HTTP http = new HTTP();
http.Config("UserAgent=(MyWeatherApp, contact@example.com)");
// Retrieve the metadata for a location (the National Weather Service headquarters in Silver Spring, Maryland).
http.Get("https://api.weather.gov/points/38.9936,-77.0224");
JSON json = new JSON();
json.Config("StringProcessingOptions=3"); // Unquote and unescape string values.
json.InputData = http.TransferredData;
json.Parse();
json.XPath = "/json/properties/forecast";
string forecastUrl = json.XText; // e.g., https://api.weather.gov/gridpoints/LWX/96,76/forecast
The response also includes other useful fields, such as properties.forecastHourly (the URL of the hourly forecast) and properties.relativeLocation (the nearest city and state).
Retrieving the Forecast
The forecast contains up to 14 periods (a day and a night period for each of the next 7 days), in the properties.periods array. Each period includes the following fields, among others:
| Field | Description |
|---|---|
| name | The name of the period (e.g., "Today", "Tonight", or "Saturday"). |
| startTime, endTime | The start and end of the period, in ISO 8601 format. |
| isDaytime | Whether the period is a daytime period. |
| temperature, temperatureUnit | The high (for daytime periods) or low (for nighttime periods) temperature, and its unit (e.g., "F"). |
| probabilityOfPrecipitation | The chance of precipitation, as a percentage in its value field (which can be null). |
| windSpeed, windDirection | The wind speed (e.g., "5 to 10 mph") and direction (e.g., "NW"). |
| shortForecast, detailedForecast | A short (e.g., "Sunny") and a detailed description of the weather. |
| icon | The URL of an image that shows the weather conditions. |
The code below requests the forecast from the URL found in the previous step, and then reads each period using the XPath property of the JSON component.
http.Get(forecastUrl);
JSON forecast = new JSON();
forecast.Config("StringProcessingOptions=3");
forecast.InputData = http.TransferredData;
forecast.Parse();
forecast.XPath = "/json/properties/periods";
int count = forecast.XChildren.Count;
for (int i = 1; i <= count; i++)
{
string period = "/json/properties/periods/[" + i + "]/";
forecast.XPath = period + "name";
string name = forecast.XText;
forecast.XPath = period + "temperature";
string temperature = forecast.XText;
forecast.XPath = period + "temperatureUnit";
string unit = forecast.XText;
forecast.XPath = period + "shortForecast";
string summary = forecast.XText;
forecast.XPath = period + "probabilityOfPrecipitation/value";
string precipitation = forecast.XText; // "null" when no value is available.
Console.WriteLine(name + ": " + temperature + unit + ", " + summary +
(precipitation == "null" ? "" : " (" + precipitation + "% chance of precipitation)"));
}
The output looks like this:
Today: 74F, Sunny (0% chance of precipitation)
Tonight: 52F, Clear (0% chance of precipitation)
Friday: 70F, Mostly Sunny (0% chance of precipitation)
...
Other Data
The same approach can be used with the other endpoints of the API, such as:
- The hourly forecast, using the URL in the properties.forecastHourly field of the /points response.
- Active weather alerts for a location, using /alerts/active?point={latitude},{longitude}.
- The latest observation from a weather station, using /stations/{stationId}/observations/latest.
For a full list of endpoints, please see the National Weather Service API documentation.
Notes
- The API only covers the United States and its territories. For other locations, the /points endpoint returns an error (e.g., 404), and the Get method of the HTTP component throws an exception.
- The URL of the forecast for a location rarely changes, so applications that request the forecast for the same location repeatedly can store it, instead of requesting /points each time.
- The API may occasionally return an error (e.g., 500 or 503) when the forecast is being updated. In this case, wait a short time and send the request again.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.