# UK Planning Scraper \[$5/1k💰] | Council Applications & Leads (`ahmed_jasarevic/uk-scraper`) Actor

Scrape UK planning applications from all 417 councils via PlanIt or single Idox PublicAccess portals: reference, address, proposal, status, applicant and agent data for pre-market development leads. From $0.005 per application.

- **URL**: https://apify.com/ahmed\_jasarevic/uk-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## UK Planning Scraper — Planning Application Data & Pre-Market Leads

Scrape **UK council planning applications** in two modes: one council's **Idox PublicAccess portal** for the deepest per-application record (documents list, all key dates), or a **nationwide sweep of all ~417 UK planning authorities** via the PlanIt aggregator — ideal for daily monitoring of new applications anywhere in England, Scotland and Wales. Extract reference, address, proposal, applicant/agent, status, decision, dates and documents. The cheapest planning-lead actor on the Store at **$0.005 per application**.

### Main Use Cases

- **Pre-market development leads** — new planning applications are public before any development is announced; capture applicant + agent contact details the day an application is validated.
- **Planning application monitoring** — daily "new applications anywhere in the UK" sweeps with filters by council, keyword, type, state and size.
- **Solar & energy project tracking** — keyword watch (e.g. `solar farm`, `wind turbine`) across all councils.
- **Property & construction market research** — application volumes, decisions and approval rates by council/region.
- **Address-level due diligence** — pull the full planning history of a specific site or postcode.

### How It Works

**Idox mode** drives the council's PublicAccess portal (e.g. `publicaccess.leeds.gov.uk/online-applications`) over plain HTTP: session cookie + CSRF token, advanced search, paged results, then all detail tabs (summary, details, dates, documents) fetched in parallel per application. **PlanIt mode** queries the public PlanIt aggregator API (`planit.org.uk/api/applics/json`) with council, keyword, type, state, size and date filters; results are deduplicated and optionally matched back to each council's docs tab. No browser, no Cloudflare wall — plain HTTP/JSON, so a nationwide daily sweep costs cents.

### Farm Pre-Market Development Deals With Applicant & Agent Data

Every row includes the **applicant and agent** (name, company, address) — the lead-generation gold — plus status, decision dates and documents. With `includeDocuments` on, application-form PDFs (which often contain direct contact details) are saved as rows in a separate per-run `documents` dataset, with the dataset ID published in the run's OUTPUT record.

### Monitor Every UK Council in One Run

The all-councils (PlanIt) mode sweeps ~417 planning authorities nationally — no need to know each portal's URL. Filter with `authorities` (e.g. Leeds, Cornwall), `searchQueries` (e.g. `solar`, `extension`), `appType`, `appState`, `appSize` and a rolling `recentDays` window for daily monitoring.

### Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `source` | select | No | `idox` | `idox` (single council portal) or `planit` (all ~417 councils nationwide). |
| `portalUrl` | string | Idox mode | — | Council's Idox portal base URL, e.g. `https://publicaccess.leeds.gov.uk/online-applications`. |
| `councilName` | string | No | — | Optional label for Idox rows. |
| `authorities` | array | No | `[]` | PlanIt mode — restrict to named councils; empty = all UK authorities. |
| `searchQueries` | array | No | `[]` | PlanIt mode — keywords vs proposal/type (e.g. `solar`, `extension`). |
| `appType` | select | No | — | Full, Outline, Amendment, Conditions, Trees, Advertising, Heritage, Listed, Telecoms, Certificate, Other. |
| `appState` | select | No | — | Undecided, Permitted, Rejected, Withdrawn, Conditions, Referred, Unresolved, Other. |
| `appSize` | select | No | — | Small, Medium, Large. |
| `recentDays` | integer | No | — | PlanIt — only applications from the last N days (newest first). |
| `startDate`/`endDate` | string | No | — | PlanIt — validated date range `YYYY-MM-DD`. |
| `caseType` | string | No | — | Idox development type code (FU, OT, RM, LI, DHH, COND, ADV, TR, MOD…). |
| `caseStatus` | select | No | — | Idox — Current, Decided, Unknown. |
| `caseDecision` | string | No | — | Idox decision code (A, R, GRA, REF…). |
| `validatedFrom`/`validatedTo` | string | No | — | Idox — validated date range `DD/MM/YYYY`. |
| `decisionFrom`/`decisionTo` | string | No | — | Idox — decision date range `DD/MM/YYYY`. |
| `address`, `description`, `applicantName`, `agent`, `reference`, `ward`, `parish` | string | No | — | Idox keyword filters. |
| `maxItems` | integer | No | `1000` | Max applications (free tier 10, hard max 5000). |
| `maxConcurrency` | integer | No | `10` | Detail pages fetched in parallel (max 50). |
| `includeDocuments` | boolean | No | `false` | Fetch + save each application's documents (one row per document). |
| `proxy` | object | No | off | Recommended for large all-councils runs. |

### Example Input

```json
{
  "source": "planit",
  "searchQueries": ["solar farm"],
  "recentDays": 7,
  "maxItems": 200
}
```

### Example Output

```json
{
  "source": "planit",
  "council": "North Northamptonshire",
  "reference": "26/02688/HFUL",
  "address": "14 Church Lane, Irthlingborough, NN29 7AW",
  "postcode": "NN29 7AW",
  "proposal": "Two-storey side extension and single-storey rear extension",
  "status": "Current",
  "decision": "",
  "applicationValidated": "2026-09-21",
  "applicationType": "Full Planning Application",
  "applicantName": "J. Smith",
  "appSize": "Small",
  "appState": "Undecided",
  "documentCount": 3,
  "url": "https://www.planit.org.uk/planapplic/..."
}
```

With `includeDocuments` on, each document is saved as its own row in a separate per-run `documents` dataset (`reference`, `applicationUrl`, `documentType`, `description`, `publicationDate`, `downloadUrl`), and the run's OUTPUT record always contains the dataset ID and URL.

### Key Dates & Documents for Due Diligence

`applicationValidated`, `determinationDeadline`, `decisionMadeDate`, `decisionIssuedDate`, plus ward/parish, app size band and coordinates. `includeDocuments` gives you every published document with type, date and direct PDF download link — usable for underwriting checks and planning-history research.

### Integrations & Automation

- **Apify API** — feed applications into a CRM, lead pipeline or monitoring dashboard.
- **Scheduling** — daily nationwide sweeps (`recentDays: 1`) or per-council daily checks with `validatedFrom`/`validatedTo`.
- **Webhooks** — alert on new applications in a council or keyword.
- **Export** — JSON, CSV, Excel, HTML.

*Recommended schedule:* daily with `recentDays: 1` (nationwide) or `validatedFrom` = yesterday (single council).

### Related Actors

- [UK Planning Applications (PlanIt)](https://apify.com/devon_gtme/uk-planning-applications-planit) — all-UK planning applications via the PlanIt aggregator.
- [UK Planning Applications Scraper – All Councils](https://apify.com/memo23/uk-planning-applications-scraper) — nationwide coverage with architect-firm extraction.
- [UK Council Planning Applications Monitor](https://apify.com/illehius/uk-planning-monitor) — scheduled Idox/Northgate monitoring with onlyNew dedupe.
- [Ireland Planning Applications](https://apify.com/devon_gtme/ireland-planning-applications) — all Irish planning authorities with full document index.
- [UK Planning Applications Scraper](https://apify.com/veluxwindow/uk-planning-applications-scraper) — 400+ council portals coverage.

### FAQ

#### Why use this actor instead of a UK planning API?

Paid planning APIs (e.g. PlanningAPI UK, PlanWire, Searchland) charge per lookup and require subscription contracts. The government's official Planning Data API (planning.data.gov.uk) covers **England only** and its planning-application dataset is still in development. This actor scrapes the public council portals and the PlanIt aggregator directly — no API key, no contract, England + Scotland + Wales in one run, at $0.005/application.

#### What are alternatives to this actor / planning data?

- [devon\_gtme/uk-planning-applications-planit](https://apify.com/devon_gtme/uk-planning-applications-planit) — PlanIt-based, $0.02/result.
- [memo23/uk-planning-applications-scraper](https://apify.com/memo23/uk-planning-applications-scraper) — all councils, $0.01/result.
- [illehius/uk-planning-monitor](https://apify.com/illehius/uk-planning-monitor) — scheduled monitoring actor.
- Paid APIs: PlanningAPI UK, PlanWire, Searchland; open data: planning.data.gov.uk (England).

#### How can I monitor one council daily?

Use `idox` mode with `portalUrl` set to your council's PublicAccess portal and schedule a daily run with `validatedFrom` = yesterday, `validatedTo` = today.

#### What is the best way to catch new solar farm applications?

Run `planit` mode with `searchQueries: ["solar farm"]` and `recentDays: 1` daily — every large-scale solar application lands in the dataset as it appears.

#### How do I get applicant contact details?

Enable `includeDocuments` — the application-form PDFs often contain the applicant/agent's contact details and are saved with direct download URLs in the documents dataset.

### SEO Keywords

uk planning applications, planning application scraper, uk planning portal, planning application data, idox publicaccess, pre-market development leads, planning leads, solar farm monitoring, planning permission tracker, uk council planning, construction lead generation, planning application monitor, planit api, planning history uk, applicant agent data, uk property development leads

### For AI Agents & LLM Apps

- **Purpose:** given a source (`idox` or `planit`), council/portal filters and an optional date window, returns one row per UK planning application with reference, address, proposal, status, dates and applicant/agent data; with `includeDocuments` on, each document is a separate row in a per-run `documents` dataset.
- **Minimal input:**

```json
{ "source": "planit", "recentDays": 7, "maxItems": 100 }
```

- **Variant — single council (Idox):**

```json
{ "source": "idox", "portalUrl": "https://publicaccess.leeds.gov.uk/online-applications", "validatedFrom": "01/09/2026", "validatedTo": "22/09/2026", "maxItems": 100 }
```

- **Variant — keyword watch with documents:**

```json
{ "source": "planit", "searchQueries": ["solar farm"], "includeDocuments": true, "maxItems": 200 }
```

- **Output field list (applications dataset):** `source`, `council`, `reference`, `address`, `postcode`, `proposal`, `status`, `decision`, `applicationValidated`, `applicationType`, `applicantName`, `agentName`, `agentCompanyName`, `agentAddress`, `ward`, `parish`, `determinationDeadline`, `decisionMadeDate`, `decisionIssuedDate`, `appSize`, `appState`, `lat`, `lng`, `documentCount`, `url`.
- **Documents dataset field list:** `reference`, `applicationUrl`, `documentType`, `description`, `publicationDate`, `downloadUrl`.

Behaviors an agent should know:

- `source: "idox"` requires `portalUrl`; `source: "planit"` ignores it and sweeps all councils unless `authorities` is set.
- `recentDays` **overrides** `startDate`/`endDate` in PlanIt mode.
- Hard cap: one keyword×authority combination is limited to ~5,000 PlanIt records — split wide queries by council or keyword.
- `includeDocuments` adds the separate `documents` dataset and triggers the `documents-fetched` billing event; the applications dataset always has `documentCount`.
- Some Idox portals reject broad searches ("Too many results") — narrow the date range.
- **Billing:** pay-per-event — `result` $0.005/application, `documents-fetched` $0.005/document (only with `includeDocuments`), + Actor Start ~$0.00005.

### Legal & Compliance Disclaimer

Planning applications are public records published by UK councils under the Town and Country Planning regime. This actor reads public data at normal volumes — no login bypass, no private systems. Users are responsible for respecting each council's terms and rate limits, and for complying with UK data-protection law when using applicant/agent contact data. Data should be used for legitimate business purposes (development research, lead generation, due diligence) in line with applicable law.

# Actor input Schema

## `source` (type: `string`):

idox: scrape a single council Idox PublicAccess portal directly (deepest data, documents). planit: nationwide sweep of all ~417 UK planning authorities via the PlanIt aggregator — ideal for 'all councils' runs.

## `portalUrl` (type: `string`):

Required for 'Council portal (Idox)' source. Base URL of the council's planning portal (Idox PublicAccess). Example: https://publicaccess.leeds.gov.uk/online-applications. To find yours, search '<council name> planning applications public access'.

## `councilName` (type: `string`):

Optional label for the Idox source, included in every output row. In PlanIt mode the council is taken automatically from the data.

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

Restrict the nationwide (PlanIt) sweep to these councils by name (e.g. Leeds, Cornwall, Wiltshire, Birmingham). Leave empty for ALL ~417 UK councils.

## `searchQueries` (type: `array`):

Free-text terms matched against the application description and type (e.g. 'solar', 'extension', 'wind turbine'). Each keyword runs its own search. Leave empty to return everything.

## `appType` (type: `string`):

One application type (PlanIt classification). Allowed: Full, Outline, Amendment, Conditions, Trees, Advertising, Heritage, Listed, Telecoms, Certificate, Other. Leave empty for all.

## `appState` (type: `string`):

One decision state (PlanIt classification). Allowed: Undecided, Permitted, Rejected, Withdrawn, Conditions, Referred, Unresolved, Other. Leave empty for all.

## `appSize` (type: `string`):

One size band (PlanIt classification): Small, Medium, Large. Leave empty for all.

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

Fast path for daily monitoring — only applications validated ('start\_date') in the last N days. Leave empty to use a date range or return everything.

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

Only applications validated on/after this date. Format YYYY-MM-DD. Ignored when 'last N days' is set.

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

Only applications validated on/before this date. Format YYYY-MM-DD. Ignored when 'last N days' is set.

## `caseType` (type: `string`):

Idox only. Filter by application type code. Common codes: FU (Full Planning Application), OT (Outline), RM (Reserved Matters), LI (Listed Building), DHH (Householder), COND (Discharge of Conditions), ADV (Adverts), TR (Tree Works), MOD (Non-material amendment). Leave empty for all types.

## `caseStatus` (type: `string`):

Idox only. Filter by application status.

## `caseDecision` (type: `string`):

Idox only. Filter by decision code. Common codes: A (Approved), R (Refused), GRA (Granted), REF (Refused). Leave empty for all decisions.

## `validatedFrom` (type: `string`):

Idox only. Earliest application validated date, format DD/MM/YYYY.

## `validatedTo` (type: `string`):

Idox only. Latest application validated date, format DD/MM/YYYY.

## `decisionFrom` (type: `string`):

Idox only. Earliest decision date, format DD/MM/YYYY.

## `decisionTo` (type: `string`):

Idox only. Latest decision date, format DD/MM/YYYY.

## `address` (type: `string`):

Idox only. Search by address keyword.

## `description` (type: `string`):

Idox only. Search by proposal/description keyword.

## `applicantName` (type: `string`):

Idox only. Search by applicant name.

## `agent` (type: `string`):

Idox only. Search by agent name.

## `reference` (type: `string`):

Idox only. Search by exact application reference.

## `ward` (type: `string`):

Idox only. Search by ward.

## `parish` (type: `string`):

Idox only. Search by parish.

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

Maximum number of applications to scrape. Free accounts are capped at 10 per run.

## `maxConcurrency` (type: `integer`):

Maximum number of applications/detail pages processed in parallel.

## `includeDocuments` (type: `boolean`):

Also fetch the documents list for each application. Each document is written as its own row in a separate 'documents' dataset, and billed via the 'documents-fetched' pay-per-event (shown as 'Document' in the store). Only Idox-backed councils publish a documents list (the majority of PlanIt councils).

## `proxy` (type: `object`):

Select proxies to be used by your crawler. Helpful for large nationwide runs (PlanIt rate-limits aggressive clients).

## Actor input object example

```json
{
  "source": "idox",
  "portalUrl": "https://publicaccess.leeds.gov.uk/online-applications",
  "authorities": [],
  "searchQueries": [],
  "maxItems": 1000,
  "maxConcurrency": 10,
  "includeDocuments": false,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `documents` (type: `string`):

Additional documents dataset: one row per document (when 'Include documents' is on).

# 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 = {
    "portalUrl": "https://publicaccess.leeds.gov.uk/online-applications",
    "authorities": [],
    "searchQueries": [],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/uk-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 = {
    "portalUrl": "https://publicaccess.leeds.gov.uk/online-applications",
    "authorities": [],
    "searchQueries": [],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/uk-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 '{
  "portalUrl": "https://publicaccess.leeds.gov.uk/online-applications",
  "authorities": [],
  "searchQueries": [],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/uk-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/uk-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/n4L0EKtV2fgwj2QsU/builds/R8gHsllJEdIF7ZQLo/openapi.json
