# UK Planning Constraints Lookup (`piercing_wadi/uk-planning-constraints`) Actor

Screen any UK postcode or coordinate against official planning designations — conservation areas, listed buildings, flood risk, green belt, tree preservation orders and more. Data from planning.data.gov.uk under Open Government Licence v3.0.

- **URL**: https://apify.com/piercing\_wadi/uk-planning-constraints.md
- **Developed by:** [Angus Fong](https://apify.com/piercing_wadi) (community)
- **Categories:** Real estate, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 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 Planning Constraints Lookup

Screen any UK postcode or coordinate against official planning designations, and get back a short answer to the only question that matters: **what actually constrains what can be built here?**

Give it `BA1 1LZ` and it tells you the site sits on a scheduled monument (the Roman Baths) inside the City of Bath World Heritage Site. Give it `SW1A 1AA` and it flags an Article 4 direction removing permitted development rights for basements — the sort of thing that derails a scheme after money has been spent.

### Why not just query the government API directly?

You can — it is free and open. But a single central-London point returns **16 designations**, and eleven of them are noise: `border: England`, a ward name, a built-up-area polygon, a local resilience forum boundary. True of everywhere, useful to nobody.

This Actor does three things the raw API does not:

1. **Filters signal from noise.** Every designation is tiered `blocking` / `material` / `advisory` / `administrative`, so a 16-row response becomes "5 significant".
2. **Accepts postcodes.** The API only takes coordinates; postcodes are resolved automatically.
3. **Stays fast enough to be usable.** The API returns full boundary geometry by default — megabytes of `MULTIPOLYGON` per point, which times out on dense urban locations. Geometry is excluded unless you ask for it, taking a query from >90 seconds to under 10.

### Input

```json
{
  "locations": ["SW1A 1AA", "BA1 1LZ", "51.5074,-0.1276"],
  "datasets": [],
  "includeGeometry": false,
  "includeExpired": false,
  "maxConstraintsPerLocation": 100
}
```

| Field | Type | Notes |
|---|---|---|
| `locations` | array | **Required.** UK postcodes or `"latitude,longitude"` pairs (WGS84). |
| `datasets` | array | Restrict to named datasets, e.g. `conservation-area`, `flood-risk-zone`. Empty returns everything. |
| `includeGeometry` | boolean | Adds WKT boundaries. Large and slow — only for mapping. |
| `includeExpired` | boolean | Include designations whose end-date has passed. |
| `maxConstraintsPerLocation` | integer | Safety cap, default 100. |

### Output

One row per location:

```json
{
  "query": "BA1 1LZ",
  "postcode": "BA1 1LZ",
  "adminDistrict": "Bath and North East Somerset",
  "latitude": 51.38131,
  "longitude": -2.35931,
  "headline": "Significant constraints",
  "significantCount": 3,
  "totalDesignations": 13,
  "blocking": ["The Roman Baths and site of Roman town, Bath"],
  "material": ["City of Bath", "Bath"],
  "advisory": [],
  "constraints": [
    {
      "dataset": "scheduled-monument",
      "name": "The Roman Baths and site of Roman town, Bath",
      "description": null,
      "reference": "1006424",
      "materiality": "blocking",
      "startDate": "1950-06-13",
      "endDate": null,
      "documentationUrl": "https://historicengland.org.uk/listing/the-list/list-entry/1006424",
      "entityId": 1234567,
      "entityUrl": "https://www.planning.data.gov.uk/entity/1234567"
    }
  ],
  "truncated": false,
  "source": "planning.data.gov.uk (Open Government Licence v3.0)",
  "retrievedAt": "2026-07-26T18:42:00.000Z"
}
```

Failed locations return a row with an `error` field rather than aborting the run, so one bad postcode never costs you the batch.

#### Materiality tiers

| Tier | Meaning | Examples |
|---|---|---|
| `blocking` | Expect refusal or fundamental redesign | Green belt, SSSI, scheduled monument, ancient woodland |
| `material` | Achievable, but consents and conditions apply | Conservation area, listed building, flood risk zone, Article 4 direction, TPO |
| `advisory` | Worth knowing, rarely decisive alone | Air quality management area, agricultural land classification |
| `administrative` | Pure geography, excluded from the headline count | Ward, parish, built-up area, region |

Tiering is a coarse mapping by dataset and cannot see case-specific detail — flood risk in particular depends on the zone and the sequential test. **Treat this as a screening tool that tells you where to look, not as planning advice.**

### Use as an MCP tool

Every Apify Actor is exposed automatically through Apify's MCP server, so an AI agent can call this without any additional setup:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com"
    }
  }
}
```

The agent finds it with `search-actors` and runs it with `call-actor`. Typical prompts it handles well:

- *"Is 12 High Street, Bath in a conservation area?"*
- *"Screen these 40 postcodes and tell me which are in green belt."*
- *"What planning constraints apply at 51.5074,-0.1276?"*

### Data source and licence

All planning data comes from [planning.data.gov.uk](https://www.planning.data.gov.uk), published under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/), which permits commercial reuse. Postcode resolution uses [postcodes.io](https://postcodes.io), built on ONS Postcode Directory data under the same licence.

Requests are rate-limited politely, as the source asks. If you are screening hundreds of sites regularly, download the bulk datasets instead — that is what the publisher recommends, and it will be cheaper than paying per call.

### Limitations

- **England only.** planning.data.gov.uk does not cover Scotland, Wales or Northern Ireland. A Scottish postcode resolves but returns no designations, which reads misleadingly as "clear" — check `adminDistrict` before trusting an empty result.
- **Not planning applications.** This returns designations and constraints, not application histories or decisions.
- **Coverage varies by authority.** Datasets are contributed by local planning authorities at differing rates; an absent designation is not proof of absence.
- **Point-in-polygon only.** A site adjacent to a constraint — a listed building next door — will not be flagged. Use `includeGeometry` with a polygon query if you need proximity.

# Actor input Schema

## `locations` (type: `array`):

UK postcodes (e.g. 'SW1A 1AA') or 'latitude,longitude' coordinate pairs in WGS84 (e.g. '51.5074,-0.1276'). Each location is screened independently and produces one result row.

## `datasets` (type: `array`):

Optional. Restrict results to named planning datasets, e.g. 'conservation-area', 'listed-building-outline', 'flood-risk-zone', 'green-belt', 'tree-preservation-order', 'article-4-direction'. Leave empty to return every designation that applies — which is usually what you want for a site appraisal.

## `includeGeometry` (type: `boolean`):

Return the full WKT boundary polygon for each designation. Off by default: geometries are very large and make responses roughly a thousand times bigger, which will time out on dense urban locations. Only enable this if you are going to draw the boundaries on a map.

## `includeExpired` (type: `boolean`):

Include designations with an end-date in the past. Off by default, so you only see what is currently in force.

## `maxConstraintsPerLocation` (type: `integer`):

Safety cap on how many designations to return for a single location.

## Actor input object example

```json
{
  "locations": [
    "EC2R 8AH",
    "M1 1AE"
  ],
  "datasets": [],
  "includeGeometry": false,
  "includeExpired": false,
  "maxConstraintsPerLocation": 100
}
```

# 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 = {
    "locations": [
        "SW1A 1AA",
        "51.5074,-0.1276"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("piercing_wadi/uk-planning-constraints").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 = { "locations": [
        "SW1A 1AA",
        "51.5074,-0.1276",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("piercing_wadi/uk-planning-constraints").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 '{
  "locations": [
    "SW1A 1AA",
    "51.5074,-0.1276"
  ]
}' |
apify call piercing_wadi/uk-planning-constraints --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/M9JW1FVlmiAuoGX8c/builds/D9CjuNrZE5MOQPvqO/openapi.json
