Parametric-insurance triggers for any location

A parametric policy pays on a measured threshold — frost days, a one-day rainfall max, a wind gust. One x402 call returns standard ETCCDI climate indices from ERA5, with the thresholds it applied.

A parametric insurance policy does not pay on a loss adjuster’s visit — it pays on a measured index crossing a threshold: so many frost days, a one-day rainfall above X mm, a wind gust above Y m/s. An agent pricing or settling such a trigger needs that index computed the standard way, on the right source variable, with the threshold stated. One paid call — GET /climate/indices — returns event indices for a GPS point and a window, using the standard ETCCDI / Climdex definitions and echoing back the thresholds it applied.

The problem: a trigger is only as good as its definition

“Number of frost days” sounds unambiguous and is not, unless you pin three things: the source variable (true daily minimum temperature, not a daily-mean approximation), the threshold (below 0 °C), and what happens when the data needed is missing. A policy whose index is computed on the wrong basis is a dispute waiting to happen.

GET /climate/indices computes the temperature indices on the true daily Tmin/Tmax, follows the ETCCDI conventions, and reports the threshold values it used — so the trigger an agent reasons over matches the trigger written into the contract.

The call: a point, a window, a set of indices

Give a latitude, a longitude, an inclusive date range, and optionally the indices and configurable thresholds you want:

GET /climate/indices?lat=48.8566&lon=2.3522&from=2024-01-01&to=2024-12-31&indices=frost_days,summer_days

The window [from, to] is the unit of the product, capped at 366 days per call. The available selectors and their ETCCDI definitions:

SelectorUnitDefinition
frost_daysdaysdaily minimum temperature below 0 °C (fixed threshold)
summer_daysdaysdaily maximum above hot_threshold (default 25 °C)
tropical_nightsdaysdaily minimum above 20 °C (fixed threshold)
max_dry_spelldayslongest run of days with precipitation below dry_mm (default 1)
heavy_rain_daysdaysdays with precipitation at or above heavy_mm (default 10)
rx1daymmmaximum single-day precipitation in the window
prcptotmmtotal precipitation over the window
max_gustm/smaximum daily wind gust in the window

Honesty: which thresholds are fixed, which you set

This is the scope point that makes the index defensible. The frost (0 °C) and tropical-night (20 °C) thresholds are fixed by the ETCCDI definitions and cannot be changed. Only three are configurable — the summer-day temperature (hot_threshold), the dry-day ceiling (dry_mm) and the heavy-rain floor (heavy_mm) — and whatever values were actually applied come back in data.thresholds. There is no guessing about what the number means.

Two further honesty notes:

  • Temperature indices use true Tmin/Tmax, never a daily-mean stand-in: frost_days and tropical_nights on the daily minimum, summer_days on the daily maximum.
  • It is a grid value, not a station. ERA5 is a gridded reanalysis on a mesh of about 0.25 degrees; grid.distance_km exposes how far the served cell sits from the requested point.

A missing source variable is null, never invented

The cleanest honesty rule for a trigger: if the store does not carry the source variable an index needs, that index comes back null with coverage.complete: false and a reason naming the field and its underlying variable — the rest of the answer is still served, at 200.

{
  "data": {
    "lat": 48.8566, "lon": 2.3522,
    "from": "2024-01-01", "to": "2024-12-31",
    "days_counted": 366,
    "indices": { "heavy_rain_days": 9, "rx1day_mm": 38.4, "max_gust_ms": null },
    "thresholds": { "hot_celsius": 25, "dry_mm": 1, "heavy_mm": 10 },
    "grid": { "lat": 48.75, "lon": 2.25, "distance_km": 13.42 },
    "coverage": { "complete": false, "reason": "no source data for: max_gust_ms (gust)" }
  },
  "provenance": {
    "source": "era5-copernicus",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-19T00:00:00Z" }
  }
}

This matters for a settlement agent: a null index is “we cannot compute this trigger,” not “the trigger did not fire.” Read the index value and coverage before acting. Per the x402 golden rule, 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 index (INVALID_INDEX), an out-of-range threshold (INVALID_THRESHOLD), 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.

From a raw value to a trigger to a probability

Indices are the trigger layer. They sit between the raw series and the probabilistic questions a risk model asks:

Reach for indices specifically when the deliverable is a threshold event count: parametric insurance triggers, agriculture and construction planning.

Used for what it is — standard ETCCDI indices from ERA5, computed on the true source variables, with the applied thresholds and the coverage exposed honestly — GET /climate/indices gives a trigger agent a number it can defend, without an account and without computing indices from GRIB. For the full selector list, definitions and error codes, see the GET /climate/indices documentation.

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