For insurance and InsureTech

Area risk inputs the actuary can audit, plus continuous drift detection.

Per-dimension scores with per-dimension confidence so the actuary sees the components, not a black box. Save your weighting recipe once and reference it as a preset_id on every quote. Track the insured-location book as a portfolio and detect material moves on demand with sample-size gating, signed-webhook delivery, and full lineage on every alert.

The problem

Black-box area scores die in actuarial review.

An underwriter’s area-risk view is a weighted blend the actuary owns: safety, flood, demographics, property volatility. The weights change with each pricing cycle. Off-the-shelf “area scores” are black-box composites with weights the vendor chose; useless inside an underwriting model because the actuary cannot see, let alone tune, the weighting. Sending the full weights map on every API call is also operationally painful: the weights live in the carrier’s codebase, not the vendor’s.

Once the book is written it drifts continuously. Median prices move, deprivation shifts neighbourhood by neighbourhood, crime patterns rebalance. Pricing teams need to know when a tracked LSOA has actually changed, not at renewal but ongoing, and the alert has to be auditable. The wrong way to know is a 47-percent swing on two sales lighting up the inbox.

On top of that, “risky” in absolute terms is rarely the right question. The right question is “risky relative to its peer group”: areas with similar demographic and built-environment signatures. That needs a stable peer definition and a relative score that follows the same methodology every quarter.

How it fits

Five integration points across rating + portfolio monitoring.

What an InsureTech or carrier integration actually looks like. Save the actuarial recipe once, score at quote time, watch the book continuously, comp against the peer group.

Step 01

Save the actuarial weighting once

Persist your weighting recipe as a per-org scoring profile (preset_id). Versioned with created_at and updated_at; references the base profile and the dimension weights. Owner or admin only.

POST /v1/orgs/:id/presets
{ "name": "Auto rating v3",
  "base_preset": "research",
  "weights": { "safety_crime": 35,
                "environment_quality": 25,
                "demographics_economy": 20,
                "transport_links": 10,
                "amenities_services": 10 } }
-> { "id": "spr_...", "created_at": "..." }
Step 02

Score at quote time

POST /v1/score with preset_id replaces the weights map on every call. The deterministic engine returns the per-dimension breakdown, weights, and per-dimension confidence so the actuary sees the components. NOT metered against the monthly report quota.

POST /v1/score
{ "area": "M1 1AE", "preset_id": "spr_..." }
-> { "score": 62,
     "dimensions": [
       { "key": "safety_crime", "score": 70,
         "weight": 35, "confidence": 0.9 } ],
     "weights_source": "custom",
     "engine_version": "2.0.2" }
Step 03

Save the insured book as a portfolio

Group the insured locations under one or more portfolios (postcodes or LSOAs). Bulk-enrich on intake. Static signals (deprivation, area type) produce zero change rows by design; only signals that actually move bite.

POST /v1/portfolios
{ "name": "Motor book Q2 2026" }
POST /v1/portfolios/:id/areas
{ "areas": [
   { "area": "M1 1AE", "label": "Pol #142" },
   { "area": "B1 1AA", "label": "Pol #143" } ] }
Step 04

Detect drift continuously

Run change detection on a cadence. baseline=previous catches month-over-month moves; baseline=first surfaces cumulative drift since onboarding. Sample-size gating (default 8 transactions) keeps a 2-sale swing from earning an alert. Material moves fire signal.changed webhooks signed Stripe-style HMAC-SHA256.

POST /v1/portfolios/:id/changes
{ "baseline": "previous",
  "threshold_pct": 5,
  "min_transactions": 8 }
# Webhook envelope:
X-OneGoodArea-Event:     signal.changed
X-OneGoodArea-Signature: t=...,v1=<sha256>
Step 05

Peer-relative anomaly screening

POST /v1/insights ranks LSOAs by absolute peer-relative z-score on a pre-materialised similarity graph. "Unusually high crime vs its peer group" rather than absolute terms. With Levers peer cohorts, pin a custom peer set (your insured universe) when the global graph is not tight enough.

POST /v1/insights
{ "signal_key": "crime.total_12m_peer_relative_z",
  "country":   "England",
  "min_abs_z": 2,
  "k":         50 }
-> [ { "geo_code": "E01...",
       "peer_relative_z": 4.12, "abs_z": 4.12 } ]
Products you reach for

Monitor leads. Scores backs underwriting. Intelligence handles the peer lens.

Signals is the data layer underneath all three. InsureTech rarely reads the raw catalog directly; the action is in the composite and the time-series.

§ 01

Monitor

See product →

Primary surface for InsureTech. Save the book as a portfolio, bulk-enrich on intake, detect material moves on demand. ChangeReport returns the exact period_from, period_to, value_from, value_to and pct_change per material row. Webhooks deliver signed Stripe-style HMAC-SHA256 envelopes to your registered HTTPS endpoint.

POST /v1/portfolios/:id/changes
-> { "material_count": 4,
     "changes": [ {
       "signal_key": "property.median_price",
       "area": "M1 1AE",
       "period_from": "2026-03",
       "period_to":   "2026-04",
       "pct_change":  7.6,
       "direction":   "up" } ] }
§ 02

Scores

See product →

Configurable composite scoring with per-org saved profiles. preset_id replaces the weights map on every call. Every response returns per-dimension components, weights, and per-dimension confidence so the actuary can audit the breakdown. Variance-aware confidence on property dimensions caps wide YoY swings at MEDIUM.

POST /v1/score
{ "area": "M1 1AE", "preset_id": "spr_..." }
-> { "score": 62,
     "dimensions": [...],
     "confidence": 0.82,
     "weights_source": "custom",
     "engine_version": "2.0.2" }
§ 03

Intelligence

See product →

Peer-relative anomaly screening. find_peers gives a stable, symmetric peer set (Euclidean dimension-mean-squared over normalised signals); find_insights ranks LSOAs by absolute peer-relative z-score. Pre-materialised peer graph (~840k assignments across 42k LSOAs). cohort_id lets you pin a custom peer universe.

POST /v1/peers
{ "target": { "postcode": "M1 1AE" },
  "country": "England", "k": 20 }
-> { "peers": [
     { "geo_code": "E01...", "distance": 0.045,
       "n_dims_used": 7 } ] }
What you can defend

Six properties an actuarial team will sign off.

The compliance + actuarial-audit pitch. Each property is documented on /methodology and stamped on every response.

§ 01

Configurable weights, transparent components

Every Scores response returns the 5 per-dimension scores, the weight applied to each, and per-dimension confidence. The actuary sees the components, not a black box. Custom weights or a saved preset_id; either way the breakdown is in the response.

§ 02

Variance-aware confidence

Confidence on property-backed dimensions caps wide YoY swings at MEDIUM rather than letting them present as HIGH. Honesty as a feature: the actuary gets a signal when volatility makes a value less trustworthy.

§ 03

Sample-size gated change detection

Monitor's diff core gates price moves on transaction count (default 8 in both periods). Static signals produce zero change rows by design. The system says when it cannot tell instead of hallucinating a move. The diff core is unit-tested without DB or network.

§ 04

Signed webhook delivery

Material changes fire signal.changed webhooks signed Stripe-style HMAC-SHA256. The signing secret is returned ONCE on subscription create. Webhook URLs must be public HTTPS; localhost and RFC 1918 ranges rejected at validation. 5-second delivery timeout.

§ 05

Peer-relative anomaly, not absolute

Intelligence find_peers gives a stable, symmetric similarity metric (Euclidean dimension-mean-squared over normalised signals, bounded in [0,1]). find_insights ranks LSOAs by abs(peer_relative_z) so the underwriter flags catchments that are 3 sigma from their peer group, not 3 sigma absolute.

§ 06

Methodology version pinning

Per-org engine_version pin honoured on every product response via X-Engine-Version header. Owner-only. Two API calls under the same pin return the same numbers across deploys. Audit-grade reproducibility for quarterly back-tests.

Frequently asked

Questions your actuarial + pricing teams ask first.

Can the actuary tune the weights without redeploying our codebase?

Yes. Save the weighting recipe as a per-org scoring profile via POST /v1/orgs/:id/presets and reference it as preset_id on every /v1/score call. The actuary updates the profile via the dashboard or a PATCH; new quotes pick it up immediately. The profile is versioned with created_at and updated_at so model risk can track what changed when.

What is the latency profile for inline rating engines?

Per-key rate limit is 30 requests per minute on /v1/score and /v1/area. Bearer-token auth over HTTPS, plain JSON. Typical pattern for rating engines is to cache the AreaProfile or score per postcode for a refresh window (monthly is the natural cadence; signals do not move faster than that). Async batch (portfolio_runs) is on the roadmap if your back-test runs need higher throughput.

How are webhook deliveries signed?

Stripe-style HMAC-SHA256 over the raw body, sent as X-OneGoodArea-Signature: t=<unix>,v1=<hex>. Header X-OneGoodArea-Event carries the event type (today change detection only fires signal.changed). The signing secret is returned ONCE on subscription create and never recoverable; you store it on receive side and verify before processing.

Can we use a custom peer set instead of the global similarity graph?

Yes, via Levers peer cohorts. POST /v1/orgs/:id/cohorts persists a named list of LSOA codes (your insured universe, or a regional underwriting band, etc.). Pass cohort_id on /v1/peers and the candidate set is constrained to the cohort. The target itself does not need to be in the cohort, which is intentional: 'areas like THIS one, but only from my universe'.

What happens during the renewal cycle when the engine version changes?

Pin the engine version per org via PUT /v1/orgs/:id/methodology (owner-only). Two quarterly back-tests at the same pin return the same numbers. When a new engine version ships, run a parallel back-test on a staging org pinned to the new version, validate against your loss-ratio model, then flip the prod pin via a single owner-only PUT. Supported pin window today is 2.0.0, 2.0.1, 2.0.2.

Do you support MGA or carrier-of-carriers setups with separate books?

Yes. Each org is multi-tenant capable: separate signal bundles, separate scoring profiles, separate methodology pins, separate peer cohorts, separate webhooks. The Levers stack is designed for the MGA / Lloyd's syndicate pattern where one entity holds multiple distinct books with different actuarial methodologies.

What gets stored about our insured locations?

Two tables: portfolios (id, name, owner) and portfolio_areas (postcode or LSOA, plus an optional label you supply). No PII, no policy data, no premium amounts. The label is opaque to us; carriers typically use it to map back to their internal policy id without exposing it.

Configurable. Auditable. Continuously monitored. Sample-size honest.

Score with weights the actuary owns, save the recipe as preset_id, watch the insured book drift continuously, get signed webhooks the day a tracked LSOA moves materially.