A weather forecast for any location, pay per call

An agent planning logistics or energy dispatch needs a forecast for a point and a lead time, not a dashboard. One x402 call returns GFS — temperature, precipitation and wind — decoded from GRIB, no account.

An agent planning the next few days — routing a delivery, dispatching energy, deciding whether to spray a field — needs one forward-looking fact: what will the weather be at this point at this lead time? It does not need a dashboard, an account or an API key. One paid call — GET /weather/forecast — returns it: 2 m temperature, precipitation and 10 m wind for a GPS point and a forecast target, served from GFS and returned as plain JSON, billed per call through x402.

The problem: a forecast is a packed binary, not a fact a model knows

Numerical weather prediction is the honest source for “what will happen next.” The Global Forecast System (GFS), run by NOAA’s NCEP, is the public reference: a global model on a mesh of roughly 0.25 degrees, re-run on a fixed cycle, with forecast steps reaching out about 16 days. It is authoritative because it is a physical model — and, like reanalysis, it ships as GRIB, a packed binary with its own grids, cycles and lead-time bookkeeping.

A language model cannot decode GRIB, and it must not invent tomorrow’s temperature for a specific coordinate. The valuable work is mechanical: pick the right cycle, resolve the requested lead, find the grid cell nearest the point, read the variables, convert units, and return a clean answer with enough metadata that the agent can judge it. That is what this endpoint does.

The call: a point and a target

Give a latitude, a longitude, and exactly one way to name the forecast target — a lead time in hours (horizon_h) or an explicit instant (valid_time):

GET /weather/forecast?lat=48.8566&lon=2.3522&horizon_h=24
GET /weather/forecast?lat=48.8566&lon=2.3522&valid_time=2026-06-21T00:00:00Z

The response is a UnifiedResponse — a data block plus a provenance block — the same shape every Invoket endpoint returns:

FieldWhat the agent learns
temperature2 m temperature in Celsius
precipitationforecast precipitation total in millimetres
wind10 m wind speed (m/s) and meteorological direction (degrees)
gridthe cell that actually answered, and its distance from the point
leadresolved cycle, target instant and served model step
coveragewhether every requested variable had a value

The lead block is the forecast-specific honesty: whichever way you named the target, it echoes back the GFS cycle used, the resolved valid_time, the computed horizon_h, and the actual step_time served — so the agent knows which run and which step produced the number.

Honesty: a grid cell, a bounded horizon, and a freshness flag

This endpoint is deliberately scoped, and the response says so on every axis.

  • It is a grid value, not a station. GFS is a gridded model on about a 0.25° mesh; the answer is the nearest or interpolated cell, and grid returns that cell’s lat, lon and distance_km from the requested point.
  • The horizon is bounded. Forecast steps are discrete (commonly around three hours) and the public horizon reaches up to about 16 days (horizon_h 0 to 384). A target outside the available window is a 400 OUT_OF_RANGE, not a fabricated extrapolation.
  • Freshness is explicit. provenance.freshness.kind is live for a fresh cycle, or cached with an age_secs when a stale-but-covered cycle answers — so an agent can decide whether to trust the number or retry after the next run.

There is no batch variant of this endpoint: it answers one point and one target per call.

A concrete answer

{
  "data": {
    "lat": 48.8566,
    "lon": 2.3522,
    "horizon_h": 24,
    "temperature": { "celsius": 18.6 },
    "precipitation": { "total_mm": 0.4 },
    "wind": { "speed_ms": 6.1, "direction_deg": 242.3 },
    "grid": { "lat": 48.75, "lon": 2.25, "distance_km": 13.42 },
    "lead": {
      "cycle": "2026-06-20T00:00:00Z",
      "valid_time": "2026-06-21T00:00:00Z",
      "horizon_h": 24,
      "step_time": "2026-06-21T00:00:00Z"
    },
    "coverage": { "complete": true }
  },
  "provenance": {
    "source": "gfs-noaa",
    "freshness": { "kind": "live" }
  }
}

GFS data comes from NOAA and is public-domain U.S. government data.

The x402 golden rule, applied to a forecast

The agent pays for the answer to its question. A well-formed, covered request is a successful 200 — even when a variable is null because the grid cell has a gap, in which case coverage.complete: false names the missing family. Only requests the service genuinely cannot answer leave the 200 range: invalid coordinates or target (INVALID_COORDS, INVALID_TIME), a target past the horizon (OUT_OF_RANGE), or an unknown variable (INVALID_VARIABLE).

One state is deliberately not a paid answer: if no GFS cycle has been ingested yet, the service returns 503 NO_FORECAST_AVAILABLE — a transient, no-charge condition, not a partial answer the agent is billed for.

Where it fits in the x402 loop

Each paid call follows the same pattern as every Invoket endpoint. The Quickstart walks the whole discover → 402 → pay → replay cycle with runnable snippets, and For agents covers the discovery surfaces and the live /catalog. Price and accepted rails are not pinned in this article — they are served live by the catalog; see the endpoint reference for the current figure.

Forecast, not history

GET /weather/forecast is the future: what GFS expects to happen. Its twin, GET /climate/point, is the past — historical ERA5 reanalysis for a dated location (see Historical weather for any GPS point and date). Reach for the forecast when the decision is forward-looking — energy dispatch, logistics routing, short-term agricultural or risk planning; reach for the historical endpoint to enrich a claim or backtest a model.

Used for what it is — a reproducible grid-cell forecast from GFS, with the served cell, the resolved lead and the cycle freshness exposed honestly — GET /weather/forecast gives an agent a future weather signal without an account and without parsing GRIB. For the full field reference, lead semantics and error codes, see the GET /weather/forecast documentation.