Historical weather for any GPS point and date

An agent often needs the weather that actually happened at a location on a date. One x402 call returns ERA5 reanalysis — temperature, precipitation and wind — decoded from GRIB, no account.

An agent enriching a claim, a backtest or a portfolio of sites often needs one fact it cannot regenerate from text: what was the weather at this exact place on this exact date? The honest source is reanalysis — and the honest format is GRIB, a binary the model cannot decode. One paid call — GET /climate/point — answers it: 2 m temperature, total precipitation and 10 m wind for a GPS point and a date, served from ERA5 and returned as plain JSON. No account, no key, pay per call through x402.

The problem: the real value is locked in GRIB

The weather that actually happened is not a search result; it lives in gridded reanalysis datasets. ERA5, produced by the Copernicus Climate Change Service (C3S) at ECMWF, is the reference: a globally consistent, hourly record on a mesh of roughly 0.25 degrees, reconstructed by blending observations with a physical model. It is authoritative precisely because it is not a guess — and it ships as GRIB, a packed binary format with its own grids, message headers and unit conventions.

A language model cannot decode GRIB, and it should not try to recall a specific day’s temperature from memory — that is exactly where it hallucinates. The work that has value is the boring part: pull the right grid, find the cell nearest the point, read the variables, convert units, and hand back a clean answer. That is what this endpoint does.

The call: one point, one date

Supply a latitude, a longitude and a UTC date. Optionally narrow the payload to the families you need:

GET /climate/point?lat=48.8566&lon=2.3522&date=2024-07-14
GET /climate/point?lat=48.8566&lon=2.3522&date=2024-07-14&variables=temperature,wind

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
precipitationdaily total precipitation in millimetres
wind10 m wind speed (m/s) and meteorological direction (degrees)
gridthe cell that actually answered, and its distance from the point
coveragewhether every requested variable had a value

The runtime lookup is local against a GRIB-decoded store, so a covered point resolves in milliseconds.

Honesty: it is a grid cell, not a station

This is the scope point that keeps the answer trustworthy. ERA5 is a gridded reanalysis, not a weather station reading. The value you get is the nearest or interpolated grid value for the served cell — on a mesh of about 0.25 degrees — and the response tells you so. The grid block returns the cell’s own lat, lon and distance_km from the requested point, so an agent can judge how representative the answer is rather than assuming pinpoint precision.

Two boundaries follow from the same honesty:

  • A covered date can still have a gap. If a grid cell is missing a value, the response is a 200 with that value null and coverage.complete: false naming the missing family. The agent paid for the answer to its question, and “there is a gap here” is the answer.
  • A date outside the window is a 400. The historical window is finite and moves with the ingested store. A date outside it returns 400 OUT_OF_RANGE — the service will not bill for a request it cannot answer.

This is the x402 golden rule applied to climate: a well-formed, covered request is a successful answer; only requests the service genuinely cannot process (invalid coordinates, invalid date, an uncovered date, an unknown variable) leave the 200 range.

A concrete answer

{
  "data": {
    "lat": 48.8566,
    "lon": 2.3522,
    "date": "2024-07-14",
    "temperature": { "celsius": 22.4 },
    "precipitation": { "total_mm": 1.2 },
    "wind": { "speed_ms": 4.8, "direction_deg": 216.9 },
    "grid": { "lat": 48.75, "lon": 2.25, "distance_km": 13.42 },
    "coverage": { "complete": true }
  },
  "provenance": {
    "source": "era5-copernicus",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-19T00:00:00Z" }
  }
}

provenance.freshness.as_of tells the agent which store production date backed the answer, so a reasoning loop can decide whether the snapshot is recent enough.

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.

Scoring a portfolio in one settlement

Enrichment is rarely one point. When an agent has a list of sites, parcels or assets to score for the same study, POST /climate/point/batch resolves many point-and-date pairs in a single call settled as one x402 payment instead of one settlement per point:

{
  "queries": [
    { "lat": 48.8566, "lon": 2.3522, "date": "2024-07-14" },
    { "lat": 40.7128, "lon": -74.006, "date": "2024-01-20" }
  ]
}

Results come back in input order, each item carrying its own grid and coverage, so a partially uncovered point is a verdict in the list — not a failure of the whole batch. The cap and the per-query pricing model live in the live /catalog.

Historical, not forecast

GET /climate/point is the past: what the reanalysis says happened. Its twin, GET /weather/forecast, answers the future — a point forecast from GFS for upcoming dates and lead times. Reach for the historical endpoint to enrich a claim, backtest an agricultural model or build a parametric-insurance baseline; reach for the forecast when the decision is forward-looking. When the question is a season rather than a day, GET /climate/aggregate summarises a window instead of returning a single date.

Used for what it is — a reproducible grid-cell value from ERA5, with the served cell and its coverage exposed honestly — GET /climate/point gives an agent the weather that actually happened, without an account and without parsing GRIB. For the full field reference, boundary semantics and error codes, see the GET /climate/point documentation.

ERA5 values are derived from Copernicus Climate Change Service (C3S) information.