# UK Planning Applications Scraper — All Councils (`scrapersdelight/uk-planning-applications-scraper`) Actor

Scrape UK planning applications from every council in one run: site address with postcode and GPS, proposal text, application type, size, status, decision and dates, plus the agent firm behind the application. Filter by council, date range, keyword or postcode radius.

- **URL**: https://apify.com/scrapersdelight/uk-planning-applications-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 per application returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🏗️ UK Planning Applications Scraper — every council, one feed

Get UK planning applications from **every planning authority in the country** in a single run: site
address with postcode and GPS, the proposal text, application type and size, status, decision and
dates — plus the **agent firm** (architect or planning consultant) behind the application.

No council-by-council setup. No login. No API key.

### What does this actor do?

- 🏠 **`address`, `postcode`, `ward`, `parish`, `latitude`, `longitude`** — where the work is
- 📝 **`description`** — the proposal in the applicant's own words
- 🗂️ **`applicationType`** (Full, Outline, Trees, Listed Building…), **`applicationSize`** (Small / Medium / Large)
- 🚦 **`status`**, **`decision`**, **`decidedBy`**, **`decidedDate`**
- 📅 **`startDate`, `receivedDate`, `validatedDate`, `consultationStart`, `targetDecisionDate`**
- 🏢 **`agentCompany`, `agentAddress`** — the firm that filed it
- 🏛️ **`council`** and deep links: **`planitUrl`**, **`councilUrl`**, `documentsUrl`, `commentUrl`

### Example input

```json
{
  "authorities": ["Cornwall", "Bristol"],
  "searchText": "extension",
  "recentDays": 7,
  "requireAgent": true,
  "maxItems": 1000
}
```

Run that daily and you have a live feed of new work in your patch, filtered to the rows that name a
firm you can contact.

### Read this first: the source redacts personal names

This is the most important thing about the data, and it is measured, not assumed. On a 100-record
sample:

| Field | Present | Actually usable |
|---|---|---|
| `applicant_name` (source field) | 90% | **0%** — every value is the literal string "See source" |
| `agent_name` (source field) | 69% | **0%** — same |
| `case_officer` (source field) | 66% | **0%** — same |
| **`agentCompany`** | — | **38%** real |
| **`agentAddress`** | — | **59%** real |
| `applicantAddress` | — | 24% real |

The aggregator strips **personal names** and keeps **organisations and addresses**. So this actor
does not pretend to give you a named individual — it gives you the **firm**. Those placeholder
strings are returned as `null` rather than as text, so the fill rate you see is the truth, and the
run log tells you how many were redacted.

If you need the named applicant, the row carries `councilUrl` — a deep link straight to that
application on the council's own portal.

### Field coverage — measured

From a real 120-application run (last 7 days, all councils):

| Field | Fill |
|---|---|
| `reference`, `council`, `address`, `status`, `startDate`, `planitUrl`, `councilUrl`, `lastChanged` | **100%** |
| `applicationSubType` 98% · `description` 97% · `latitude`/`longitude` 95% · `validatedDate` 94% | **95–98%** |
| `receivedDate` 92% · `applicationSize` 88% · `postcode` 85% · `ward` 83% · `documentCount` 81% | **80–92%** |
| `agentAddress` 59% · `agentCompany` 38% | the lead fields |
| `decision` 10% · `decidedDate` 2% | **on a recent-7-days run** — see below |

**Decision fields look empty on a recent run because recent applications have not been decided yet.**
Filtered to `applicationState: "Permitted"` over June–July, the same fields read **decision 90%,
decidedDate 96%, decidedBy 80%**. Nothing is broken; you are choosing which half of the pipeline to
look at.

`dwellings` is ~2% because only major housing schemes report a unit count.

### Who is this for?

Construction suppliers and trades prospecting new work, architects and surveyors tracking
competitors, conveyancers, property investors, and anyone who needs a national view without wiring
up 400 council portals.

### Honest limits

- **The aggregator rate-limits.** It replies with an explicit "try again in N seconds" and this
  actor waits exactly that long rather than hammering. A very large run will pause occasionally —
  that is the actor being polite, not stuck.
- **Coverage follows the aggregator**, which scrapes council portals on its own schedule. A brand
  new application may take a day to appear.
- **Council fields vary.** Some publish a case officer, ward, constraint count and document links;
  others publish the bare minimum. That is the council's choice, not a gap here.
- **Personal data.** Agent firms and addresses are published as part of the statutory planning
  record. UK GDPR still applies to what you do with them.

### Pricing

| What | Price |
|---|---|
| Per application returned | **$0.004** |

A 5,000-application month costs **$20**. Filtered rows cost nothing — `requireAgent` drops
non-leads before you are charged.

### FAQ

**Which councils are covered?**
All UK planning authorities the aggregator indexes — English, Welsh, Scottish and Northern Irish.
Leave `authorities` empty to search every one at once.

**Can I run it daily for new applications?**
Yes — set `recentDays: 1` and schedule it. That is the intended use.

**Can I search by postcode?**
Set `postcode` plus `radiusKm` for a radius search.

**How do I get only big schemes?**
Set `applicationSize: "Large"`.

**How do I get approvals rather than the live pipeline?**
Set `applicationState: "Permitted"` with a date range — that fills the decision fields.

**Why is the applicant's name missing?**
The source redacts personal names. You get the agent firm plus a direct link to the council's own
page for the application. See the section above.

**Do I need a proxy?**
No. Leave it empty.

**Is there a limit per run?**
The API returns 100 per page and this actor paginates for you; `maxItems: 0` means unlimited.

**Is this legal?**
Planning applications are a statutory public register, published so the public can inspect and
comment on them. Only the public aggregator API is read, and its rate limits are honoured.

### Data source and fair use

Data comes from PlanIt (planit.org.uk), a public aggregator of UK planning-authority registers. No
login or paywall is involved, the documented rate limits are respected, and each row links back to
both the aggregator and the originating council page.

# Actor input Schema

## `authorities` (type: `array`):

Planning authority names, e.g. Cornwall, Southwark, Leeds. Leave empty for every UK council at once.

## `searchText` (type: `string`):

Match the proposal text, e.g. "extension", "solar", "demolition", "change of use".

## `recentDays` (type: `integer`):

Applications from the last N days. The simplest way to run this daily. 0 = use the date range instead.

## `startDate` (type: `string`):

YYYY-MM-DD. Use with "To date" for a fixed window.

## `endDate` (type: `string`):

YYYY-MM-DD.

## `applicationType` (type: `string`):

e.g. Full, Outline, Trees, Listed Building, Advertising, Conditions, Heritage.

## `applicationState` (type: `string`):

e.g. Undecided, Permitted, Rejected, Withdrawn. Undecided is the live pipeline; Permitted gives you approved schemes with a decision date.

## `applicationSize` (type: `string`):

Small, Medium or Large. Large filters to major schemes.

## `postcode` (type: `string`):

Centre of a radius search, e.g. BS1 1AA. Needs "Radius km" as well.

## `radiusKm` (type: `integer`):

Kilometres around the postcode. 0 = not a radius search.

## `requireAgent` (type: `boolean`):

Keep only applications where the agent firm or its address is published — the rows that are actually leads. Dropped rows are not charged.

## `maxItems` (type: `integer`):

Stop after this many. 0 = unlimited.

## `proxyConfiguration` (type: `object`):

Optional. PlanIt is an open aggregator with no anti-bot, so a proxy is not needed.

## Actor input object example

```json
{
  "authorities": [],
  "searchText": "",
  "recentDays": 7,
  "startDate": "",
  "endDate": "",
  "applicationType": "",
  "applicationState": "",
  "applicationSize": "",
  "postcode": "",
  "radiusKm": 0,
  "requireAgent": false,
  "maxItems": 100
}
```

# Actor output Schema

## `applications` (type: `string`):

The dataset of scraped planning applications.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "recentDays": 7,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/uk-planning-applications-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "recentDays": 7,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/uk-planning-applications-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "recentDays": 7,
  "maxItems": 100
}' |
apify call scrapersdelight/uk-planning-applications-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/uk-planning-applications-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6bWnKhHagi4OhqyYw/builds/YuaTsbYErdi5SvRq2/openapi.json
