Monitor: portfolios plus signed change detection.

Save a book of UK areas, enrich it on intake, and detect material moves across the monthly time-series on demand. Each move arrives as a structured row with the exact periods compared, the raw values before and after, and the percent change. Material alerts deliver as Stripe-style HMAC-SHA256 signed webhooks. Sample-size gated so a 47% swing on two sales never earns an alert.

Sample response

One portfolio. One change report. Sample-size honest.

Turn the knobs and watch material moves drop in or out. The baseline picks what “from” means; the threshold sets what counts as material; the sample gate keeps a 2-sale swing from earning an alert.

baseline
threshold_pct
min_transactions
POST/v1/portfolios/pf_demo_lender/changes

Demo lender book

areas 4checked 4material 2
M1 1AE · E01005207B1 1AA · E01033620LS1 4DT · E01011358NE1 7RU · E01008397

Material changes

baselinepreviousthreshold5%min_tx8
property.median_priceM1 1AE · E01005207
2026-032026-04
£182,500£196,300
+7.6%
crime.total_12mB1 1AA · E01033620
2026-032026-04
4,1084,512
+9.8%

Webhook delivery (per material row)

POST  https://api.example.com/oga/hook
X-OneGoodArea-Event:     signal.changed
X-OneGoodArea-Signature: t=1748736000,v1=<hmac-sha256-hex>
X-OneGoodArea-Delivery:  wd_a8s2k4m9q
Content-Type:            application/json
{ "event": "signal.changed", "data": { /* the SignalChange row above */ } }

Reading this view

baseline
What period_from means. previouscompares the latest period to the one before it (month over month); first compares the latest period to the oldest in the stored range (cumulative drift since you started watching).
threshold_pct
The absolute percent change a (area, signal) move must clear to count as material. Set it to 0 to see every move; set it to 10 to filter out small drift.
min_transactions
Sample-size gate. Price moves only count when both periods had at least N transactions. Default 8. Set it to 0 to disable; you will see a 47% swing on 2 sales appear. Set it back to 8 and the honest engine drops that row.
Static signals
Deprivation and other static signals produce zero change rows by design. They have one observed period; there is nothing to diff.

Demo portfolio with illustrative values. Real outputs vary per book, per refresh, per source release.

What Monitor actually watches.

Monitor diffs the monthly time-series store. Signals that move over time fire alerts; static signals (deprivation, area type) never trigger because there is nothing to compare.

Prices that actually move

Median sale price month over month, plus YoY against the same window a year ago. The signal that drives most lender and PropTech alerts.

How Backed by 24+ months of monthly history per LSOA.

Crime trend

Trailing-12-month total per area plus monthly counts. Watch areas where crime is rising or improving against their own past.

How Police.uk bulk archive, monthly cadence.

Derived YoY signals

Built-in derived signals like property.price_change_pct_yoy compose over the time-series store. No client-side rollup needed.

How Computed in-DB, refreshed monthly.

Save a book. Diff the time-series. Fire a signed webhook.

Four steps in a deterministic order. The diff core is pure code, unit-tested without a database. The webhook envelope is Stripe- style HMAC-SHA256 so receivers can verify authenticity.

STEP 01 · PORTFOLIOSTEP 02 · ENRICHcap 50 · concurrency 5STEP 03 · DETECT MOVESdiff time-seriesTHRESHOLD + SAMPLE GATESTOREsignal_timeseriesSTEP 04 · WEBHOOKHMAC-SHA256 signed
  • Step 01

    Save the book

    POST /v1/portfolios then /areas to add up to 200 areas per call, deduped on (portfolio_id, area). Areas can be postcodes or LSOA codes; the engine resolves both to LSOAs.

  • Step 02

    Bulk enrich

    /enrich runs the deterministic scoring engine over every tracked area. Synchronous, cap 50 per call, concurrency 5. Per-area failures captured, never fatal.

  • Step 03

    Detect material moves

    /changes diffs each (area, signal) series against the chosen baseline. Threshold filters small drift; min_transactions filters noisy low-volume price swings.

  • Step 04

    Signed webhook delivery

    Material rows fire signal.changed events to your registered HTTPS endpoint. HMAC-SHA256 over the raw body, secret returned once on subscription create. 5-second delivery timeout.

Five endpoints. One signed event catalog.

Portfolios CRUD plus enrich plus change detection plus webhook subscriptions. Plain JSON over HTTPS, Bearer-token auth with the oga_ prefix, all paths under /v1/.

Create a new portfolio (an empty book). Pair with POST /:id/areas to populate it. Portfolios are scoped to the api-key's user_id today; org-scoping ships with the Levers re-scope.

Parameters

  • namestringRequired

    Portfolio name, trimmed, max 200 chars.

Response

201 Portfolio: { id: 'pf_...', name, area_count: 0 }.

Status codes

201
Created.
400
Missing or oversized name.
401
Missing or invalid Bearer oga_… API key.
404
Signals API dark flag off.

One book. Five buyer workflows.

Same portfolio. Same change-detection mechanics. Different questions each buyer is trying to answer with the alert.

Insurance and InsureTech

The problem

An insurer's book of insured locations drifts continuously. Median prices move; deprivation context shifts neighbourhood by neighbourhood; crime patterns rebalance. Pricing teams need to know when the assumed risk profile of a tracked LSOA has actually changed, not at renewal but ongoing, and they need the alert to be auditable.

Why Monitor

Save the insured-location book as a portfolio. Enrich on intake. Run change detection on a cadence. Material moves arrive as signed signal.changed webhooks with the exact signal_key, periods, raw values, and percent change. Sample-size gating is exactly the de-noising an actuarial team needs.

Their value

Exposure drift detected continuously, not at renewal. Every alert is auditable: raw values, periods, threshold, sample gate all in the same envelope. HMAC-SHA256 signing means it is fit for automated pricing or referral workflows.

Sign your insured-location book up as a portfolio. Get HMAC-signed alerts the day a tracked LSOA's risk signal materially moves.

Lenders

The problem

A residential or commercial lender's book is geographically concentrated. The questions are where location-risk has drifted and which LSOAs have moved enough to retrigger LTV stress. Manual re-screening at portfolio scale is impossible; spreadsheet-based reviews lag actual moves by quarters.

Why Monitor

Store the book once, bulk-enrich on intake (sync up to 50, concurrency 5), then run change detection ad hoc or on a schedule. baseline=first surfaces cumulative drift since onboarding; baseline=previous surfaces month-over-month moves. Both report exact value_from, value_to, pct_change per tracked LSOA-signal pair.

Their value

Risk teams can prove 'we knew on date X' for every material move. period_from, period_to, threshold and sample gate are in the response and on the signed webhook. The full loop is one HTTP surface behind one API key.

Track location-risk drift across the lending book with sample-size-gated change alerts that you can audit row-by-row.

PropTech

The problem

PropTech platforms surface portfolio dashboards, alerts and what-changed-this-month digests to landlords, agents and asset managers. They have the UI; they do not have a deterministic, signed source of area-level change to ship to customers without owning a data team.

Why Monitor

Attach a portfolio to each customer's book and call /v1/portfolios/:id/changes on a cadence. The output is shaped for UI: one row per (area, signal) with period_from/to, value_from/to, pct_change, direction, material. Feed it into a movers panel. Webhooks turn it into push notifications.

Their value

Ship a portfolio-intelligence feature on top of OneGoodArea instead of building one. Customers get area-level signal moves with stamped engine_version and lineage, not vibes. Sample-size gating means they do not embarrass themselves with a 47% move on 2 sales.

Attach a OneGoodArea portfolio to every customer book, ship a movers feed without a data team.

CRE and site selection

The problem

A site-selection or CRE team carries a watchlist of candidate locations: shortlisted development sites, tenant catchments, comparable hold areas. They want to know when a watched area's price or trend signal has moved enough to revisit the underwriting, without re-running ad-hoc reports every week.

Why Monitor

A watchlist is a portfolio. Candidates are areas. /v1/portfolios/:id/changes with baseline=first tells you which watched LSOAs have moved since you started watching. Threshold_pct tunes what material means for their underwriting hurdle.

Their value

The team stops re-running area reports manually. Material moves arrive as a list or webhook, with exact pct_change and from/to periods needed to retrigger an underwriting review. Static signals correctly do nothing; only signals that actually move trigger.

Your watchlist as a portfolio. Tunable change-detection tells you which sites have moved enough to revisit.

Public sector

The problem

Local authority and central-gov analytical teams hold lists of priority LSOAs (regen targets, levelling-up wards, intervention catchments) and need a defensible, lineage-stamped record of how their tracked areas have moved over time. The honest answer is often that sample size is too small; the system needs to say so, not hallucinate a move.

Why Monitor

Monitor is honest by construction. A single-period signal (deprivation) produces no change row. A price move on 2 sales is filtered by min_transactions=8. The ChangeReport carries baseline, threshold_pct, and min_transactions, so a published 'areas that moved' note has the methodology stamped inside the artifact.

Their value

A reproducible, lineage-stamped record of which tracked areas moved between two periods, with gating decisions visible in the artifact. The diff core is documented on /methodology and unit-tested.

Track priority LSOAs as a portfolio. Get a lineage-stamped change report with honest sample-size gating built in.

Monitor your book of UK areas. Sample-size honest by default.

Save areas, bulk-enrich, run change detection, get signed webhooks when something material shifts. The diff core is unit-tested, the envelope is HMAC-SHA256 signed, and a 47% swing on 2 sales never earns an alert.