Parametric weather triggers
A research-stage technical surface for parametric weather triggers, driven by the same scoring engine. Goable is not an insurer, MGA, reinsurer or actuary, and does not quote, bind, price or settle risk. These endpoints are a surface a licensed risk carrier could operate, not an insurance product Goable runs.
Where this sits
Not an insurance product. Parametric underwriting is an exploratory research direction, not a shipped product Goable operates. Goable is not an insurer, MGA, reinsurer, coverholder or actuary, and does not quote, bind, price or settle risk. What the endpoints below describe is a research-stage technical surface a licensed carrier could build on, resting on parts Goable genuinely does today: historical replay, forecast-skill measurement and SPC drift methodology. Pricing, issuance, binding and settlement of any real policy sit with a licensed carrier. For the research framing, see the parametric underwriting research overview.
The endpoints are gated to a contracted Scale tier. Goable makes no claim of conformance, readiness or compliance with any insurance regulatory regime; the surface is designed with parametric-risk model-governance frameworks in mind, nothing more. Talk to us about a research collaboration.
The contract
A policy on this surface is a parametric contract over a single spot or a 2-50-spot portfolio, each with its own fixed payout amount. The trigger is either a score threshold (scoreBelow) or a verdict threshold (verdictAtOrBelow), evaluated hourly across the recurring annual coverage window: each time the condition holds for consecutiveHours in a row (subject to a cooldownHours gap between events and an optional maxPayoutsPerYear cap), that spot's flat payout amount fires. The trigger is evaluated deterministically by the same historical-replay engine that priced it. Pricing, the decision to issue, and settlement of funds sit with a licensed carrier operating the surface, not with Goable.
POST /v1/underwriting/quote
Returns a technical premium figure for a single spot or a 2-50 spot portfolio (a research-stage signal, not an insurance quotation from Goable). The engine replays the covered window against the ERA5 historical archive, walks the trigger over each year to build the expected-payout distribution, applies the per-spot tier risk multiplier, and loads the figure by loadingFactor (default 15%). A licensed carrier's actuary would own any real tariff. Portfolios can mix currencies: each spot carries its own payout, and the response's expectedPremium.byCurrency breaks the figure down per currency (no FX conversion, each currency settles independently).
{
"portfolio": [
{ "point": { "lat": 36.013, "lng": -5.604 },
"activity": "kitesurfing",
"spotId": "tarifa-balneario", // optional, your own label
"payout": { "amount": 150, "currency": "EUR" }
},
… 1-49 additional spots
],
"coverageWindow": { "monthFrom": 6, "dayFrom": 1, "monthTo": 9, "dayTo": 30 }, // recurring calendar window, not a fixed date range
"trigger": { "kind": "scoreBelow", "scoreBelow": 55, "consecutiveHours": 4 },
"loadingFactor": 0.15
}trigger is a discriminated union: either { kind: "scoreBelow", scoreBelow: <0-100> } or { kind: "verdictAtOrBelow", verdict: "unsafe" | "not_feasible" | "poor" | "marginal" | "fair" | "favorable" | "excellent" }. Both accept optional consecutiveHours, cooldownHours, and maxPayoutsPerYear. There is no per-spot "limit" field: the payout schedule is driven entirely by the trigger plus the per-spot payout amount, walked across every hour in the coverage window that satisfies the trigger.
Response carries policy (the echoed + resolved terms, including each spot's tier/tierSource, see below), expectedPayouts.byCurrency (mean / p10 / p50 / p90 distribution), expectedPremium.byCurrency (fair + loaded + tierMultiplierWeightedAvg per currency), modelConfidence, advisoryLevel, issuable, and underlying (the historical score distribution the figure was priced against). There is no cryptographic cohort hash on the quote: reproducibility comes from the persisted policyTerms snapshot (see Settlement below), not a hash.
POST /v1/underwriting/policy/bind
Convert a quote into a bound policy record. Submit the quoteId from a recent quote (default TTL 24h) + coverageYear + premiumCollection (external / stripe / invoice_due). The response echoes the resolved policy (a snapshot of the priced terms, the reproducibility anchor for settlement) + the quoteId. Fires the underwriting.policy.bound webhook. Whether to bind, issue or price a real policy is a licensed carrier's decision, not Goable's.
Drift gate. The bind runs a live check against the concept-drift monitor for each covered cell. A watch-level event surfaces as a non-blocking driftAdvisories array on the successful response; a warning or critical event refuses the bind with 422 DRIFT_ACTIVE (SDK: DriftActiveError). The payload's detail.openDriftEvents lists the blocking cells so you can decide to re-quote after recalibration. This is a research-stage guardrail a carrier could adopt, not a live underwriting control Goable runs.
import { DriftActiveError } from "@goable-io/sdk" try { const policy = await goable.bindPolicy({ quoteId }) if (policy.driftAdvisories?.length) // watch-level, non-blocking console.warn("drift watch", policy.driftAdvisories) } catch (err) { if (err instanceof DriftActiveError) { // refused: cell has open warning/critical console.error(err.openDriftEvents) } }
curl -X POST https://api.goable.io/v1/underwriting/policy/bind
-H "X-Goable-Key: $GOABLE_KEY" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "e12b…",
"coverageYear": 2027,
"premiumCollection": "external",
"premiumPaid": 1750
}'Drift gate. The bind endpoint checks the SPC drift monitor for the resolved cell before persisting. If a warning or critical drift event is currently open on the cell, the endpoint refuses with a 422 DRIFT_ACTIVE and no policy record is created, the honest move while recalibration closes the loop. A watch-level event lets the bind through and surfaces a driftAdvisories array in the response so your integration can nudge the buyer without blocking.
The quote response, echoed on every policy read, surfaces the resolved tier per spot with a tierSource flag: "catalog" when the tier came from the versioned catalogue, "classifier"when the nightly data-driven classification overrode the catalogue at full confidence. Any tier > 1 lifts the tierMultiplierWeightedAvg above 1.0, see the tier multipliers section below.
Interactive playground. Prefer clicking through a quote then bind before wiring the endpoints? The tenant console at console.goable.io/portal/underwriting/quote runs the same request-response flow with a form, including portfolio mode. Scale-plan only.
POST /v1/underwriting/policy/:id/evaluate
Replays the bound policy's trigger against the historical provider (ERA5) and inserts new payout events into the policy record. Idempotent on repeat calls: the same event set surfaces twice with inserted: 0 the second time. Fires the underwriting.policy.triggered webhook only when new events land in a given evaluation. Response includes the up-to-date policy record + all payout events on the policy so far + the inserted and skipped counts for this call.
Tier multipliers
Sub-spot resolution matters for the pricing figure. A tier-1 spot (≥150 paired outcomes, calibrated) prices at the base multiplier; tier-2 (cluster-level) and tier-3 (regional fallback) carry uncertainty loadings. The tierMultiplierWeightedAvg in the quote response shows the portfolio-wide multiplier. Configure rates in apps/api/config/tier_risk_multipliers.yaml.
Settlement: POST /v1/underwriting/policy/:id/settle
Settlement is not automatic. A separate admin cron (POST /cron/expire-windows, platform_admin only) sweeps and marks stale untriggered policies as expired, but the payout math itself runs via POST /policy/:id/evaluate (replays the bound policy against the ERA5 historical archive, idempotently inserting new payout events). Settlement is finalized by whoever operates this surface as a licensed carrier, calling this endpoint with a settlementReference. It requires the platform_admin scope: recording a settlement is a carrier operation, not something a policyholder tenant does to its own policy, so clients never call it directly. Goable is not the carrier and does not settle risk. Fires the underwriting.policy.settled webhook.
For the full research framing (trigger model, where a licensed carrier fits, and open methodology), read the parametric underwriting research overview on the landing.