Planning Radar AI
Pricing
from $12.00 / 1,000 application returned with summaries
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
Maintained by CommunityActor 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:
- 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. - 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.
- 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
| Mode | Behavior |
|---|---|
area_snapshot | Real applications within radiusMiles of postcode, right now |
property_watch | Same, 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.
| Event | Fires when |
|---|---|
apify-actor-start | Built-in, auto-billed on every run start. |
application-returned-basic | An 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-radius | An application was found and evaluated but fell outside the requested radiusMiles. |
developer-pattern-identified | Not currently reachable — see note below. |
apify-default-dataset-item | Built-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: trueor a new application entering the watched radius, usingplainEnglishSummaryas the alert body.