# US Weather Forecast by Coordinates (`grit-77/us-weather-forecast`) Actor

US weather forecast lookup by coordinates from the National Weather Service. Export flat forecast-period JSON rows with update times and source URLs for planning workflows.

- **URL**: https://apify.com/grit-77/us-weather-forecast.md
- **Developed by:** [Grit](https://apify.com/grit-77) (community)
- **Categories:** Travel, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.30 / 1,000 forecast periods

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 by Coordinates

Get official US National Weather Service forecast periods as flat JSON rows for logistics and outdoor planning, with update times and traceable source URLs.

The actor requests `https://api.weather.gov/points/{latitude},{longitude}`, follows `properties.forecast`, and exports its forecast periods in source order. It sends an identifying User-Agent. No API key, address lookup, maps or imagery are needed.

### What it returns

| Field | Meaning |
|---|---|
| `status` | `ok` for a usable period; `error` for a free diagnostic |
| `latitude`, `longitude` | Requested decimal-degree coordinates |
| `periodNumber`, `name`, `isDaytime` | NWS period identifier, label and day/night flag |
| `startTime`, `endTime` | ISO timestamps with source timezone offsets |
| `temperature`, `temperatureUnit` | NWS numeric temperature and `F` or `C`; no conversion |
| `windSpeed`, `windDirection` | NWS speed text such as `2 to 6 mph`, and compass direction |
| `precipitationProbability` | NWS precipitation probability, 0-100 percent; `null` means unknown |
| `shortForecast` | NWS forecast summary |
| `issuedTime`, `updateTime` | NWS `properties.updateTime`, the forecast update time |
| `generatedAt` | NWS response generation timestamp; distinct from forecast update time |
| `sourceUrl` | Official grid forecast URL; failed discovery diagnostics may contain the points URL |
| `errorCode`, `errorMessage` | Diagnostic category and explanation; `null` on successful rows |

Weather fields can be absent on diagnostic rows. The dataset's Forecast periods view includes weather and diagnostic fields; the output link opens the dataset items.

### Input example

The Console prefill is:

```json
{"latitude":38.8894,"longitude":-77.0352,"maxItems":6}
```

Latitude and longitude are required numeric values. `maxItems` defaults to 6 and accepts integers from 1 through 14. It caps **all exported rows**, including diagnostic rows. Missing coordinates fail with a clear input message instead of querying an unrelated location.

Optional `userAgent` identifies your application to NWS. Its default is `us-weather-forecast/1.0 (Apify coordinate forecast actor)`. You may add your own public website/contact to it; use 10-256 printable ASCII characters.

### Real output example

One row from the local DC run on 2026-10-06; the full six-row dataset is in `sample_output.json`:

```json
{
  "status": "ok",
  "latitude": 38.8894,
  "longitude": -77.0352,
  "periodNumber": 1,
  "name": "Overnight",
  "startTime": "2026-10-06T03:00:00-04:00",
  "endTime": "2026-10-06T06:00:00-04:00",
  "isDaytime": false,
  "temperature": 46,
  "temperatureUnit": "F",
  "windSpeed": "5 mph",
  "windDirection": "N",
  "precipitationProbability": 0,
  "shortForecast": "Clear",
  "issuedTime": "2026-10-06T06:22:50+00:00",
  "updateTime": "2026-10-06T06:22:50+00:00",
  "generatedAt": "2026-10-06T07:13:38+00:00",
  "sourceUrl": "https://api.weather.gov/gridpoints/LWX/97,71/forecast",
  "errorCode": null,
  "errorMessage": null
}
```

### Pricing

Proposed price: **$0.0003 per successful `forecast_period`**, or $0.30 per 1,000 successful periods, plus any Apify platform usage charges. The six-period prefill has $0.0018 in actor event fees. Invalid input and diagnostic rows do not incur this event. Successful cached periods are charged normally.

The proposal is below the most used returned forecast comparable, epctex/weather-scraper, at $0.0006/result, observed 2026-10-06. `PRICING.md` records the Store API queries, selection scope, competing event units and a free alternative. Pricing must be configured by the owner before publication.

### Limits and source behavior

- US NWS **land forecast coverage only**. Non-US coordinates, unsupported land points and marine points without `properties.forecast` produce an uncharged diagnostic. Coverage is determined by NWS, not a bounding box.
- One coordinate per run. Requests are sequential, with at most one outstanding request. The actor exports NWS period forecasts, not hourly forecasts, current observations or alerts.
- Coordinates are rounded to four decimal places for the NWS points lookup. Requested coordinates are retained in output.
- Source fields and period lengths are preserved. Missing precipitation is `null`, not a fabricated zero. Period-level parsing failures become individual diagnostic rows.
- Transient transport failures and HTTP 429/500/502/503/504 get up to four attempts with exponential backoff and jitter. HTTP 429 waits at least five seconds before retrying. Numeric and HTTP-date Retry-After guidance takes precedence; waits longer than 300 seconds are deferred to a later run.
- Forecast payloads are cached by official URL and NWS updateTime in the default key-value store. Cache-Control, Age, Date and Expires bound freshness, with ceilings of one hour for forecasts and one day for point mappings. Expired entries use ETag/Last-Modified validators when available. Source failures do not return stale forecasts.
- Cached data survives restarts when the same key-value store is retained. Separate cloud runs normally have separate default stores; no cross-account shared cache is provided.
- The spending limit is checked before each successful row, and output stops when the SDK reports it reached. Diagnostic rows do not trigger `forecast_period`; monetization must not also price generic dataset rows.

Official source and retry/coverage guidance: [NWS API documentation](https://www.weather.gov/documentation/services-web-api). NWS data is public and free; the proposed fee covers the actor's extraction and delivery.

### Local run and verification

Use the existing shared virtual environment; no packages were installed into it. From this actor directory:

```powershell
C:/GritWork/earn/.venv/Scripts/python tools/local_run.py
C:/GritWork/earn/.venv/Scripts/python tools/run_checks.py unit
C:/GritWork/earn/.venv/Scripts/python tools/run_checks.py live
apify validate-schema
```

`tools/local_run.py` sets `APIFY_LOCAL_STORAGE_DIR=<actor>/storage`, writes the prefill to `storage/key_value_stores/default/INPUT.json` if absent, and runs `python -m src` without the Apify CLI. Edit INPUT.json to change location. Local dataset rows are saved in `storage/datasets/default/`; SDK `__metadata__.json` files are storage bookkeeping, not results. Local dataset writes append to existing rows.

`tools/verify_delivery.py all` runs isolated input probes and compares the real dataset against an independent official response. It clears only each probe's previous dataset to measure per-run rows, and retains cache records for restart checks. Evidence logs include tests, schema validation, source responses and file digests. The container uses `apify/actor-python:3.12`.

### FAQ

**Does it resolve city names or addresses?** No. Supply numeric coordinates; the actor does not call a geocoding service.

**Can I use it outside the US?** No. A non-US point returns a coverage diagnostic, not substituted global weather.

**Why is rain probability null?** NWS did not supply a usable probability. Zero means a supplied zero-percent value; null means unknown.

**What is the issue time?** `issuedTime` is NWS `updateTime`; `generatedAt` tells you when the API response was generated.

**Is this an emergency alert or aviation briefing service?** It exports land forecast periods. Alerts and aviation products are outside its scope; consult the relevant official NWS products for those decisions.

### Use with AI agents / MCP

After the owner publishes the actor, connect it through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). Pass numeric latitude, longitude and maxItems, read the default dataset link, and inspect each row's status before using weather values. Preserve sourceUrl and issuedTime when explaining a planning decision; treat null precipitation as unknown and do not invent a numeric wind speed from a range string. This delivery includes the actor, not a separate MCP server; a cloud MCP invocation has not been tested.

# Actor input Schema

## `latitude` (type: `number`):

Numeric latitude in decimal degrees. The coordinate must be in supported US NWS land forecast coverage.

## `longitude` (type: `number`):

Numeric longitude in decimal degrees; west is negative. No address lookup or geocoding is performed.

## `maxItems` (type: `integer`):

Hard cap on dataset rows, including free diagnostics. Only successful forecast periods incur the forecast_period event.

## `userAgent` (type: `string`):

Identify your application to NWS. Optionally add your own public website/contact information. Printable ASCII, 10-256 characters.

## Actor input object example

```json
{
  "latitude": 38.8894,
  "longitude": -77.0352,
  "maxItems": 6,
  "userAgent": "us-weather-forecast/1.0 (Apify coordinate forecast actor)"
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset items containing forecast periods, issued time, source URL and any diagnostic rows.

# 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 = {
    "latitude": 38.8894,
    "longitude": -77.0352,
    "maxItems": 6
};

// Run the Actor and wait for it to finish
const run = await client.actor("grit-77/us-weather-forecast").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 = {
    "latitude": 38.8894,
    "longitude": -77.0352,
    "maxItems": 6,
}

# Run the Actor and wait for it to finish
run = client.actor("grit-77/us-weather-forecast").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 '{
  "latitude": 38.8894,
  "longitude": -77.0352,
  "maxItems": 6
}' |
apify call grit-77/us-weather-forecast --silent --output-dataset

```

## MCP server setup

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

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/gj0sEHXO62q55faMO/builds/88S8QCR1GODeWgrKY/openapi.json
