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:
| Field | What the agent learns |
|---|---|
temperature | 2 m temperature in Celsius |
precipitation | forecast precipitation total in millimetres |
wind | 10 m wind speed (m/s) and meteorological direction (degrees) |
grid | the cell that actually answered, and its distance from the point |
lead | resolved cycle, target instant and served model step |
coverage | whether 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
gridreturns that cell’slat,lonanddistance_kmfrom 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_h0to384). A target outside the available window is a 400OUT_OF_RANGE, not a fabricated extrapolation. - Freshness is explicit.
provenance.freshness.kindislivefor a fresh cycle, orcachedwith anage_secswhen 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.