Season summaries for any GPS point
A reporting agent needs the climate balance of a month or season — mean temperature, total rainfall, mean wind — not 90 daily lookups to roll up itself. One x402 call returns it from ERA5.
An agent writing a monthly or seasonal report needs the balance of a window at
a point: how warm it was on average, how much rain fell in total, how the wind
sat. Assembling that yourself means 30 to 90 individual daily lookups and a
roll-up that has to use the right convention for each variable. One paid call —
GET /climate/aggregate — returns the summary
directly: mean temperature with its daily extremes, total precipitation and mean
wind over a date range, computed from ERA5.
The problem: each variable aggregates differently
The trap in a season summary is that “average it” is wrong for half the variables. Precipitation has to be a total, not a mean — a month of rain is a sum, not an average daily figure. Wind direction cannot be averaged as plain degrees (the mean of 350° and 10° is not 180°). And “the min and max” is ambiguous: extremes of daily means are a different number from hourly Tmin/Tmax.
Get any of those conventions wrong and the report is quietly misleading.
GET /climate/aggregate applies the convention that fits each family and tells
you which one it used.
The call: a point and a window
Give a latitude, a longitude, an inclusive date range, and optionally the families you want:
GET /climate/aggregate?lat=48.8566&lon=2.3522&from=2024-06-01&to=2024-08-31
GET /climate/aggregate?lat=48.8566&lon=2.3522&from=2024-06-01&to=2024-08-31&variables=temperature
The window [from, to] is the unit of the product, capped at 366 days per
call. The response is a UnifiedResponse carrying one aggregate per requested
family:
| Field | What the agent learns |
|---|---|
temperature | mean_celsius, plus min_celsius / max_celsius of the daily means |
precipitation | total_mm — the sum over the window |
wind | mean_speed_ms and mean_direction_deg |
days_counted | how many covered days contributed |
grid | the cell that answered, and its distance_km from the point |
coverage | whether every day had a usable value for each family |
Honesty: the conventions are explicit
This is the scope that keeps a summary trustworthy:
- Precipitation is a total, not a mean.
total_mmadds the daily totals over the covered days. - Temperature and wind are means over the covered days. Wind direction is averaged as a vector, not as a naive scalar mean of degrees, so the near-north wrap-around does not corrupt it.
min_celsius/max_celsiusare extremes of the daily means — the coldest and warmest days in the window, not the lowest and highest instantaneous readings. For true daily Tmin/Tmax extremes, useGET /climate/indices.- It is a grid value, not a station. ERA5 is a gridded reanalysis on a mesh
of about 0.25 degrees;
grid.distance_kmexposes how far the served cell sits from the requested point, so the agent can judge how representative it is.
Partial coverage is still an answer
When some days in the window have no grid value, they are dropped:
days_counted reflects the covered days, a sum like total_mm is the total over
those days only, and a requested family with no data comes back null — all at
200, with coverage.complete: false explaining the gap.
{
"data": {
"lat": 48.8566, "lon": 2.3522,
"from": "2024-06-01", "to": "2024-06-30",
"days_counted": 28,
"temperature": { "mean_celsius": 19.7, "min_celsius": 12.1, "max_celsius": 27.0 },
"precipitation": { "total_mm": 41.2 },
"wind": null,
"grid": { "lat": 48.75, "lon": 2.25, "distance_km": 13.42 },
"coverage": { "complete": false, "reason": "no wind data at this grid cell; 2 days in the window have no value" }
},
"provenance": {
"source": "era5-copernicus",
"freshness": { "kind": "snapshot", "as_of": "2026-06-19T00:00:00Z" }
}
}
This is the x402 golden rule: the agent pays for the answer to its question, and
a partial-but-honest summary is a valid answer — read days_counted and
coverage before trusting it. Only requests the service genuinely cannot answer
leave the 200 range: invalid coordinates (INVALID_COORDS), a bad or over-long
period (INVALID_PERIOD), an unknown family (INVALID_VARIABLE), or a window
with no covered day at all (OUT_OF_RANGE).
Where it fits in the x402 loop
Each paid call follows the same pattern as every Invoket endpoint. The
Quickstart walks the 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.
One window, many questions
GET /climate/aggregate is the summary layer over the daily series. It pairs
with the rest of the climate family depending on the question:
GET /climate/point— the underlying daily values for a single date (see Historical weather for any GPS point and date).GET /climate/anomaly— how far this window sat from the long-term normal.GET /climate/return-period— how rare a season’s value was, empirically.
Reach for the aggregate when the deliverable is the season’s balance itself — analytics, reporting, energy operations.
Used for what it is — a reproducible period summary from ERA5, with each
variable aggregated by its correct convention and the served cell and coverage
exposed honestly — GET /climate/aggregate gives a reporting agent the month or
season in one call, without an account and without rolling up GRIB. For the full
field reference, aggregation conventions and error codes, see the
GET /climate/aggregate documentation.
ERA5 values are derived from Copernicus Climate Change Service (C3S) information.