Planning Radar AI avatar

Planning Radar AI

Pricing

from $12.00 / 1,000 application returned with summaries

Go to Apify Store
Planning Radar AI

Planning Radar AI

Real UK planning applications near a postcode — proximity-matched, classified, status-change tracked, and synthesized into plain-English summaries from real government data. Not raw council search — the diff/alert/explain layer on top of it.

Pricing

from $12.00 / 1,000 application returned with summaries

Rating

0.0

(0)

Developer

joseph fadero

joseph fadero

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

The diff/alert/explain layer on top of UK planning data — not another raw extraction tool. A May 2026 analysis scraping 2.6 million UK planning decisions found real, actionable variance between councils — approval-rate differences exceeding 20 percentage points and worsening decision times. The one existing Apify actor for UK planning data has 2 total users and functions as raw extraction. This is explicitly scoped as a Type 3 intelligence actor: real proximity matching, real status-change tracking, real classification, and plain-English synthesis — from real UK government data.

No master index existed for this — designed as I built, documented for reuse

This is the first actor in a new "Radar" series (build order 1 of 4); the PRD referenced a shared "Radar architecture" master index that didn't exist yet. Per the user's direction, that shared diff/classify/explain pipeline was designed here and is meant to be reused by Actors 38-40 the same way deltaStore.ts (see below) has been reused across 5 actors now — not rebuilt from scratch each time.

Phase 1 research — a real finding that reshaped scope

planning.data.gov.uk — the UK government's own official national planning-data aggregator (Department for Levelling Up, Housing and Communities) — turned out to be the right primary source: confirmed live, genuinely free and keyless, real per-application records (100,627 real rows at build time), with a documented organisation_entity filter and (for councils that provide it) real point geometry. Cross-validated live: a real Camden application's own embedded coordinates matched postcodes.io's independent geocode for the same postcode almost exactly.

Coverage varies significantly by council — confirmed live by sampling across the full dataset, not assumed: some councils (e.g. Doncaster) have 0% of records with real point/geometry data; others (Camden, Worthing) had 100% real point data across every sample checked. This actor covers the councils confirmed to have real, usable geometry — 2 at launch (Camden, Worthing) — not presented as national coverage. Adding a council means verifying its real point-data completeness first, the same way these two were checked.

The finding that changed the PRD's "killer feature"

The PRD's central differentiator was developer entity resolution — a "repeat developer" signal from applicant/developer name matching. Checked three real paths, live, and applicant/developer identity is not available from any of them:

  1. The national dataset's own field specification (digital-land.github.io/specification/dataset/planning-application) — 21 defined fields, none of them applicant/developer/agent name.
  2. A real council's own bulk open-data export (Wigan's 2025 planning CSV, the PRD's own cited example) — same gap, no applicant field.
  3. Free-text pattern matching against real application descriptions for company-name-like strings (e.g. "... Ltd", "... Developments") — tested against a real 100-record sample, zero matches.

This is very likely a real, structural, GDPR-driven choice by UK councils (individual applicants' names are personal data) rather than an oversight — but the practical result is the same: applicantOrDeveloper and developerRepeatCount are always null in this build's output, kept in the schema rather than removed so the gap is visible, not silently absent. developer_lookup mode from the original spec is dropped for the same reason — it would have nothing real to search on. The genuine differentiator that remains, and that this actor delivers in full, is the diff/proximity/classify/explain layer itself — which the existing 2-user competitor doesn't do at all.

"AI" in the name — what it actually means here

plainEnglishSummary is generated by a real, deterministic, rule-based sentence generator built from real extracted facts (type, status, distance, scale, status-change) — not a call to an external LLM. No actor in this build program has wired in an LLM API (a real API-key/budget decision outside any single actor's scope), and this one doesn't either. "AI" refers to the intelligence layer — proximity matching, status-change detection, classification, synthesis — not literally an AI model writing the sentence. Said plainly here rather than left ambiguous.

The shared "Radar" architecture (for Actors 38-40 to reuse)

  • Diff: src/shared/deltaStore.ts — reused wholesale, unmodified, from Actor 26 (now used by 5 actors across two separate build programs: 26, 27, 34, 35, and this one).
  • Classify: keyword-based classification against real free-text (src/processors/classifier.ts) — order-sensitive checks (specific phrases before generic ones), a lesson learned the hard way in a previous actor where the wrong order silently filtered out every active record.
  • Explain: rule-based summary generation (src/processors/summaryGenerator.ts) — real facts in, readable sentences out, no external API.
  • Proximity: standard haversine distance (src/processors/geoDistance.ts) against a free, keyless UK geocoder.

Modes

ModeBehavior
area_snapshotReal applications within radiusMiles of postcode, right now
property_watchSame, plus statusChangedSinceLastRun from this actor's own stored history

A real, honest classification note

In a first real test (0.5 miles around a central Bloomsbury/Camden postcode), 76% of matched applications classified as other. Checked directly against the real description text before assuming a bug: these are genuinely minor works (dormer windows, condition discharges, satellite dish installations, listed-building refurbishment) in a historic, listed-building-dense area — an accurate reflection of that area's real planning activity, not a classifier defect. Confirmed by reading actual descriptions, not assumed.

Output schema

{
"applicationId": "string",
"councilArea": "string",
"applicantOrDeveloper": "null (see above)",
"developerRepeatCount": "null (see above)",
"developmentType": "residential | commercial | mixed_use | change_of_use | other",
"status": "submitted | approved | refused | under_review | appealed | withdrawn | null",
"unitsOrScale": "string | null",
"address": "string",
"latitude": "number | null",
"longitude": "number | null",
"distanceFromWatchedPointMiles": "number | null",
"policyReferences": ["string"],
"statusChangedSinceLastRun": "boolean | null",
"plainEnglishSummary": "string",
"sourceUrl": "string",
"checkedAt": "ISO timestamp",
"fetchStatus": "success | failed",
"errorMessage": "string | null"
}

status includes withdrawn — a real, common status this source returns that the original spec's 5-value enum didn't anticipate; kept rather than forced into a misleading nearby category.

Setup note

No browser needed — both real sources (planning.data.gov.uk, postcodes.io) work over plain HTTP. Each council fetch is capped at 2,000 most-recent records (paginated) — this is a recent-activity radar, not a full historical archive; capped and documented, not silently incomplete.

Pricing

Pay-per-event (PPE). Prices are configured in the Apify Console; event names below are the real ones this actor charges.

EventFires when
apify-actor-startBuilt-in, auto-billed on every run start.
application-returned-basicAn application is returned to the dataset. This is the actual charge for every successfully-returned application in this build — see note below.
status-change-detected(property_watch mode only) An application's status changed since this actor's last run against the same postcode/council.
application-not-in-radiusAn application was found and evaluated but fell outside the requested radiusMiles.
developer-pattern-identifiedNot currently reachable — see note below.
apify-default-dataset-itemBuilt-in default dataset-item event. Not currently reachable in this build — see note below.

Note on application-returned-basic vs the built-in apify-default-dataset-item: the fully-enriched criteria for the built-in event (plain-English summary and developer repeat count both populated) can never be met by this actor today, because no verified free UK planning source exposes applicant/developer identity (see applicantOrDeveloper/developerRepeatCount, always null, above). Every successfully-returned application is therefore charged as application-returned-basic instead. If developer-entity resolution is ever added on top of a new data source, the fully-enriched branch (and developer-pattern-identified, charged when a developer is resolved across 3+ applications) becomes reachable without further code changes to the branching logic itself — only the developer-resolution step would need to be built.

Failed geocoding or a council-level fetch failure is never charged.

n8n integration

  • Workflow A (trigger): scheduled weekly run against a watched property/postcode list.
  • Workflow B (processing): alert on statusChangedSinceLastRun: true or a new application entering the watched radius, using plainEnglishSummary as the alert body.