# Uk Solar Planning Leads (`devon_gtme/uk-solar-planning-leads`) Actor

Lead-gen for solar installers. Find solar panel, PV and battery-storage planning applications across 381 UK planning authorities: site addresses, applicant and agent contacts, decision status and council portal links. Filter by council, postcode radius, status and date. No API key needed.

- **URL**: https://apify.com/devon\_gtme/uk-solar-planning-leads.md
- **Developed by:** [Devon Kellar](https://apify.com/devon_gtme) (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

from $20.00 / 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.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Solar Panel Planning Applications — Installer Leads

Find **solar panel, solar PV, and battery storage planning applications** across **381 UK planning authorities** — every one a live buying signal. A homeowner or business that submits a planning application for solar is actively investing in an installation *right now*. A large solar farm application means a developer about to procure panels, mounting systems, inverters, batteries, and electrical contractors at scale.

This actor turns that public data into a lead list: site addresses, planning agent details where the council publishes them (~40% of records), decision status, and direct links to council portals. Export to CSV and start calling.

No API key needed. No login required. Just configure your region and run.

### Who this is for

- **Solar installers** — find homeowners and businesses in your service area with live or newly permitted solar applications. Undecided applications are prospects mid-decision; permitted ones are ready to build.
- **Battery & storage vendors** — battery storage applications (included in the default search terms) signal buyers speccing systems now.
- **Mounting & racking suppliers** — large solar array and solar farm applications mean bulk procurement is coming.
- **Electrical contractors** — every permitted solar install needs a qualified electrician. Target the postcode areas where permissions are being granted.
- **Renewables marketing agencies** — build regional demand maps and prospect lists for installer clients.
- **B2B suppliers to solar farms** — track Large applications to reach developers before they've chosen suppliers.

### Features

- **Solar search baked in** — preset terms `solar panel`, `solar pv`, `photovoltaic`, `solar array`, `battery storage`, fully editable (narrow to `solar farm` only, or add `heat pump`, `ev charging`)
- Search any council or go nationwide across all 381 planning authorities
- Filter by decision status (Undecided = live pipeline, Permitted = green-lit projects)
- Postcode radius search (find solar applications within X km of your base)
- Filter by application size (Small = householder installs, Large = solar farms)
- Extract the planning agent company and address where published (~40% and ~56% of records; applicant details are not published upstream)
- Monitor-friendly: designed for weekly scheduled runs per region

**Coverage:** 381 planning authorities across England, Scotland, Wales and Northern Ireland.

### Typical usage: weekly lead monitor per region

Set up a **weekly scheduled run** on Apify with your service area, and get a fresh lead list every Monday:

```json
{
    "postcode": "M1 1AD",
    "radiusKm": 40,
    "appState": ["Permitted", "Undecided"],
    "daysBack": 7,
    "maxResults": 200
}
```

Each run returns only the last 7 days of applications within 40 km of Manchester — new leads only, no repeats. Connect the dataset to Google Sheets, email, or your CRM via Apify integrations.

### Input parameters

The input of this scraper should be JSON containing the filter configuration for your search. Possible fields are:

**searchTerms**: (Optional) (String\[]) Solar/renewables terms to match in application descriptions. Terms are OR-combined — an application matching ANY term is returned. Multi-word terms match as exact phrases. Default is `["solar panel", "solar pv", "photovoltaic", "solar array", "battery storage"]`.

**councils**: (Optional) (String\[]) List of council names to search. Leave empty for a nationwide search across all 381 planning authorities. Type any UK council name — for example: `"Wiltshire"`, `"Cornwall"`, `"Manchester"`.

**appSize**: (Optional) (String\[]) Filter by development size. The values can be: `Large`, `Medium`, and `Small`. Leave empty for all sizes (recommended — most domestic solar installs are Small/householder, solar farms are Large). Default is all sizes.

**appState**: (Optional) (String\[]) Filter by decision status. The values can be: `Permitted`, `Undecided`, `Conditions`, `Rejected`, `Withdrawn`, `Referred`, and `Appeal`. Default is `["Permitted", "Undecided"]` — green-lit projects plus the live pipeline.

**daysBack**: (Optional) (Number) How many days back to search from today. For decided applications, this filters by decision date. For undecided applications, this filters by submission date. Range: 1–365. Default is `30`. Set to 7–14 for weekly scheduled runs.

**postcode**: (Optional) (String) UK postcode as the centre point for a radius search. Requires `radiusKm` to be set. Example: `"M1 1AD"`, `"BS1 4DJ"`.

**radiusKm**: (Optional) (Number) Search radius in kilometres from the postcode centre point. Only used when `postcode` is provided. Range: 1–100. Default is `10`.

**appTypes**: (Optional) (String\[]) Filter by application type. Leave empty for all types. Common values: `Full`, `Outline`, `Householder`. These match as substrings.

**maxResults**: (Optional) (Number) Maximum total results to return. The actor stops fetching once this cap is reached. Range: 1–5,000. Default is `500`.

### Input examples

#### Nationwide solar leads (last 30 days)

```json
{
    "appState": ["Permitted", "Undecided"],
    "daysBack": 30,
    "maxResults": 1000
}
```

#### Solar farms only (B2B suppliers)

```json
{
    "searchTerms": ["solar farm", "solar array", "photovoltaic park", "battery energy storage"],
    "appSize": ["Large"],
    "appState": ["Permitted", "Undecided"],
    "daysBack": 90,
    "maxResults": 500
}
```

#### Installer service area (specific councils)

```json
{
    "councils": ["Cornwall", "Devon", "Somerset"],
    "appState": ["Undecided"],
    "daysBack": 14,
    "maxResults": 300
}
```

### Tips

- **Undecided applications are the warmest leads for installers** — the applicant is planning an install but may not have committed to a contractor. Permitted applications are best for equipment suppliers and electricians.
- Leave `appSize` empty: domestic solar installs are classed `Small` and would be missed by the parent scraper's Large/Medium default.
- Start with a low `maxResults` (e.g. 20) and your own postcode to verify the data matches your patch before scaling up.
- Combine this actor with a contact enrichment actor — take the `agentCompany` and `address` fields and enrich them with phone numbers and emails. (The applicant/developer name is not published by the upstream source; see the note on contact details below.)
- Please keep in mind that multi-council or multi-status queries require a 62-second delay between each query to respect rate limits. The default (nationwide, 2 statuses) runs in ~2 minutes; a 3-council × 2-status query takes ~6 minutes.

### Developer and applicant contact details

Every record includes `portalUrl` - a direct link to the council's own page for that application. Most UK councils run Idox Public Access portals (roughly 70% of the country), and those pages publish the **applicant name, applicant address, agent name and case officer**.

This actor does not fetch them. It reads the PlanIt aggregator, which returns the literal string `"See source"` for those fields instead of the values - "see source" meaning the council's own portal. Rather than export placeholder text dressed up as data, the actor drops those fields entirely, so an empty field is honestly empty.

**If you need applicant and developer names at scale, we run that as a managed enrichment service.** It fetches each application's council portal page and returns the applicant/agent details, resolving on the majority of Idox-covered councils and returning null - never a guess - where a council does not publish them. Message me via my [Apify profile](https://apify.com/devon_gtme) with the councils, volume and fields you need.

You can of course do this yourself for small volumes: open `portalUrl` and read the Details tab.

### Compute unit consumption

Since the underlying data source enforces a rate limit of approximately 1 request per minute, compute unit consumption depends on the number of queries (councils × statuses × sizes):

- **Nationwide, default input:** ~2 minutes, ~0.05 compute units
- **3 councils × 2 statuses:** ~6 minutes, ~0.1 compute units
- **Weekly regional monitor (postcode radius):** ~2 minutes, ~0.05 compute units

### Scraped solar planning application data

Each dataset item is one planning application with 50+ fields (coverage varies by council):

```json
{
    "council": "Wiltshire",
    "address": "Manor Farm, Church Lane, Bishopstone, Salisbury",
    "postcode": "SP5 4DB",
    "description": "Installation of up to 22 solar panels on the roofs of the modern barns adjacent to the road.",
    "appType": "Full",
    "appSize": "Small",
    "appState": "Permitted",
    "decidedDate": "2026-07-02",
    "startDate": "2026-05-11",
    "agentCompany": "GreenSpark Renewables Ltd",
    "agentTel": "01722 000000",
    "latitude": 51.0742,
    "longitude": -1.8926,
    "portalUrl": "https://development.wiltshire.gov.uk/pr/s/planning-application/...",
    "planitUrl": "https://www.planit.org.uk/planapplic/Wiltshire/PL/2026/04321/",
    "reference": "PL/2026/04321",
    "planitId": "Wiltshire/PL/2026/04321"
}
```

Core fields: `council`, `address`, `postcode`, `description`, `appType`, `appSize`, `appState`, `decidedDate`, `startDate`, `agentCompany`, `agentTel`, `latitude`, `longitude`, `portalUrl`, `planitUrl`, `reference`, `planitId`.

Extended fields (where the council publishes them): `applicantAddress`, `agentAddress`, `applicationType`, `status`, `decision`, `decidedBy`, `dateReceived`, `dateValidated`, `targetDecisionDate`, `consultationStartDate`, `consultationEndDate`, `wardName`, `parish`, `district`, `nDocuments`, `nComments`, `docsUrl`, `commentUrl`, `mapUrl`, and more.

Export to **JSON**, **CSV**, or **Excel** in one click from the Apify Console, or pull via the [Apify API](https://docs.apify.com/api/v2).

### Bugs, fixes, updates, and changelog

This scraper is under active development. If you have any feature requests, you can raise an issue from the actor's Apify Store page.

### Need something more custom?

Need a different vertical (heat pumps, EV charging, wind), webhook alerts for new applications in your patch, or contact enrichment built in? Raise an issue from the actor's Apify Store page and tell us what you need — custom builds are usually turned around quickly.

### Data source

All data comes from [PlanIt](https://www.planit.org.uk), which aggregates publicly available planning data from UK local authority portals. The data is published by councils under statutory obligation — this actor provides structured, filterable access to it.

# Actor input Schema

## `searchTerms` (type: `array`):

Solar/renewables terms to match in application descriptions. Terms are OR-combined — an application matching ANY term is returned. Multi-word terms are matched as exact phrases. Edit to narrow (e.g. only 'solar farm') or widen (e.g. add 'heat pump', 'ev charging').

## `councils` (type: `array`):

Council names to search. Leave empty for nationwide search. Type any UK council name — suggestions show the most popular.

## `appSize` (type: `array`):

Filter by development size. Leave empty for all sizes (recommended — most domestic solar installs are Small/householder, solar farms are Large). Large = major developments (10+ dwellings or 1000+ sqm). Medium = minor. Small = householder.

## `appState` (type: `array`):

Filter by decision status. 'Undecided' = live pipeline (homeowner/business planning an install now). 'Permitted' = green-lit projects ready to buy equipment and hire contractors.

## `daysBack` (type: `integer`):

How many days back to search from today (based on decision date). For 'Undecided' apps, this filters by submission date. Set to 7-14 for weekly scheduled runs.

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

UK postcode for radius search. Requires Radius to be set. Example: M1 1AE. Note: PlanIt's radius search can time out server-side when combined with text search — if you get 0 results, filter by Councils instead.

## `radiusKm` (type: `number`):

Search radius in kilometres from the postcode centre point.

## `appTypes` (type: `array`):

Filter by application type substring. Leave empty for all types. Common values: Full, Outline, Reserved, Hybrid, Householder.

## `maxResults` (type: `integer`):

Maximum total results to return; the actor stops fetching once this cap is reached. PlanIt allows one request a minute, so this is really a budget in minutes rather than in rows: 300 is a single page and returns in seconds, and every further 300 costs another 62-second wait. Prefilled at 300 so a first run is immediate. Raise it freely -- 5,000 is supported, it simply takes about a quarter of an hour.

## Actor input object example

```json
{
  "searchTerms": [
    "solar panel",
    "solar pv",
    "photovoltaic",
    "solar array",
    "battery storage"
  ],
  "councils": [],
  "appSize": [],
  "appState": [
    "Permitted",
    "Undecided"
  ],
  "daysBack": 30,
  "radiusKm": 10,
  "appTypes": [],
  "maxResults": 300
}
```

# 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 = {
    "searchTerms": [
        "solar panel",
        "solar pv",
        "photovoltaic",
        "solar array",
        "battery storage"
    ],
    "councils": [],
    "appSize": [],
    "appState": [
        "Permitted",
        "Undecided"
    ],
    "daysBack": 30,
    "radiusKm": 10,
    "appTypes": [],
    "maxResults": 300
};

// Run the Actor and wait for it to finish
const run = await client.actor("devon_gtme/uk-solar-planning-leads").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 = {
    "searchTerms": [
        "solar panel",
        "solar pv",
        "photovoltaic",
        "solar array",
        "battery storage",
    ],
    "councils": [],
    "appSize": [],
    "appState": [
        "Permitted",
        "Undecided",
    ],
    "daysBack": 30,
    "radiusKm": 10,
    "appTypes": [],
    "maxResults": 300,
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "solar panel",
    "solar pv",
    "photovoltaic",
    "solar array",
    "battery storage"
  ],
  "councils": [],
  "appSize": [],
  "appState": [
    "Permitted",
    "Undecided"
  ],
  "daysBack": 30,
  "radiusKm": 10,
  "appTypes": [],
  "maxResults": 300
}' |
apify call devon_gtme/uk-solar-planning-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=devon_gtme/uk-solar-planning-leads",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AjXE7dNYakDNTwksS/builds/1AuzSyuttMOo2e33i/openapi.json
