# ETCCDI climate indices for parametric-insurance triggers > A parametric policy pays on a measured threshold — frost days, a one-day rainfall max, a wind gust. One paid call returns standard ETCCDI climate indices from ERA5, with the thresholds it applied. Published 2026-06-28 · Updated 2026-08-16 · HTML version: https://invoket.com/blog/parametric-insurance-triggers-for-any-location --- 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`](/docs/api/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: ```http 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: | Selector | Unit | Definition | |-------------------|------|------------------------------------------------------------------| | `frost_days` | days | daily **minimum** temperature below 0 °C (fixed threshold) | | `summer_days` | days | daily **maximum** above `hot_threshold` (default 25 °C) | | `tropical_nights` | days | daily **minimum** above 20 °C (fixed threshold) | | `max_dry_spell` | days | longest run of days with precipitation below `dry_mm` (default 1)| | `heavy_rain_days` | days | days with precipitation at or above `heavy_mm` (default 10) | | `rx1day` | mm | maximum single-day precipitation in the window | | `prcptot` | mm | total precipitation over the window | | `max_gust` | m/s | maximum 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**. ```json { "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](/docs/quickstart) walks the discover → `402` → pay → replay cycle with runnable snippets, and [For agents](/docs/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](https://api.invoket.com/catalog); see the [endpoint reference](/docs/api/climate-indices) 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: - [`GET /climate/point`](/docs/api/climate-point) — the underlying daily values for a single date (see [Historical weather for any GPS point and date, from ERA5](/blog/historical-weather-for-any-gps-point)). - [`GET /climate/aggregate`](/docs/api/climate-aggregate) — period means, totals and daily-mean extremes when you need a balance rather than an event count. - [`GET /climate/anomaly`](/docs/api/climate-anomaly) — how far a value sat from the 1991–2020 normal. - [`GET /climate/return-period`](/docs/api/climate-return-period) — how rare a season's value was, empirically — the natural next question after a trigger. 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](/docs/api/climate-indices). ERA5 values are derived from Copernicus Climate Change Service (C3S) information.