# UK Property Sold Prices + EPC: Land Registry + Energy Ratings (`transparent_meteorite/uk-property-sold-prices-epc`) Actor

Look up UK sold house prices from HM Land Registry and get the official EPC energy rating, score, floor area and price per m2 for each sale, matched by address. Search by postcode, town, district or county. Median stats and a new-sales monitor included. Official open data, no login. Beta.

- **URL**: https://apify.com/transparent_meteorite/uk-property-sold-prices-epc.md
- **Developed by:** [Detroit Web Agent - Open Data](https://apify.com/transparent_meteorite) (community)
- **Categories:** Real estate, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 sale record 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?

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 Property Sold Prices + EPC: Land Registry Data With Energy Ratings

Use this to get UK sold house prices from HM Land Registry with the energy performance certificate (EPC) of the same property attached: energy rating, score, floor area in square metres, price per square metre, built form, construction age, heating and more, in one run and one dataset.

New to Apify? [Create a free account](https://console.apify.com/sign-up?fpr=rnmakg) and run this Actor in under a minute. Some links are affiliate links.

**Beta.** Verify any figure you act on at the linked official record. The sales come from the official HM Land Registry open endpoint and the certificates from the official Energy Performance of Buildings Register. Matching is done on postcode and address, and rows the actor cannot match with confidence are returned with empty EPC fields instead of a guess. Open an issue on the Issues tab if a field looks wrong and we fix it fast.

### Run in 30 seconds

1. Open the **Input** tab. The prefilled input is one Manchester postcode, `M1 1AE`, with a limit of 5 sales.
2. Press **Start**. The first rows appear within about a minute.
3. Open the **Output** tab. Every row is a sale with its price, date and address, plus `epcRating`, `epcScore`, `floorAreaM2` and `pricePerM2` where a certificate was matched.
4. Download as JSON, CSV or Excel, or call the dataset through the Apify API.
5. To scale up, replace the postcode with a list of postcodes, or use a town, district or county, and raise the limit. Add `"epcOnly": true` to receive only sales that have a certificate.

There is nothing to configure. You do not need an EPC register account, a token or an API key: the actor carries its own access to the register, so you only supply the places you care about.

### What it does

Every row is a completed UK property sale from the HM Land Registry Price Paid Data (England and Wales). For each sale the actor looks up the certificates lodged for that postcode in the national EPC register, finds the certificate that belongs to the same address, and adds the energy and building facts to the sale row.

- **One run, one dataset.** Sold price and building facts arrive together, so you can compute price per square metre without joining two files yourself.
- **The right certificate for the sale.** When a property has several certificates over the years, the actor prefers the one that was in force at the date of sale (the newest lodged on or before the transfer). If none predates the sale it uses the newest and says so in the `epcBasis` field.
- **Honest matching.** Addresses are compared after normalising abbreviations (RD, ST, AVE), flat and apartment words, leading zeros, and town or county names. If two different properties could match one sale the row is marked `ambiguous` and no EPC data is attached. A wrong match is worse than an empty one.
- **Filters on the energy side.** Keep only certain rating bands (for example E, F and G for retrofit leads, or A and B for green-premium studies), or only sales that have a certificate at all.
- **Free summary rows.** One summary row per place with count, median price, EPC coverage, median score, median floor area, median price per square metre and the rating mix. Summary rows are never charged.
- **Monitor mode.** Turn on new-sales monitoring and schedule the actor. Each run delivers only sales not seen before, already enriched with their EPC data. A run with nothing new charges nothing.

### Why this one

Measured against the actors that currently cover this ground in the Apify Store (checked 2026-10-29):

| | This actor | Sold-price actors without EPC | Property portal scrapers |
|---|---|---|---|
| Sold price and date | Yes | Yes | Yes, via scraping |
| EPC rating and score on the same row | Yes | No | Partial, listings only |
| Floor area and price per m2 | Yes, from the certificate | No | Sometimes, from listing text |
| Certificate in force at the sale date | Yes (`epcBasis`) | No | No |
| Rating filter | Yes | No | No |
| Output fields | about 45 | 10 to 15 | 20 to 60, listings oriented |
| Source | Two official open registers | One official register | Scraped web pages |
| Runs per property with sale and EPC | 1 | 2 actors plus your own join | 1, but scraping breakage risk |
| Price per row, EPC included | $0.001 | $0.001 or more, then a second actor for EPC | $0.001 to $0.00345 plus start fees up to $0.005 |

On price: this actor costs a flat **$0.001 per sale record (about $1 per 1,000), with the EPC energy data included at no extra charge**, plus a $0.00005 start fee per run. We checked the live Store prices through the Apify API on 2026-10-29: the Zoopla scraper by SMD charges $0.001 per result plus a $0.001 start fee, the Zoopla scraper by memo23 charges $0.001 per result plus a $0.005 start fee (and another $0.001 for its additional-data event), and the Rightmove scraper by automation-lab charges $0.00345 per property plus a $0.005 start fee. None of them returns Land Registry sold prices joined to the EPC register, so with any of them you would pay at least the same per row and still need a second actor and your own address matching to get what this actor returns in one row. You are never charged for the free summary rows or for already-seen sales in monitor mode.

Third-party figures change; run a small test on any alternative and compare cost per usable row, not headline price.

### Things to know

- Town, district and county names are matched **exactly** as HM Land Registry records them (case-insensitive), for example `GREATER MANCHESTER` or `CITY OF WESTMINSTER`. A misspelt name returns no rows.
- Results are newest first. Property type, new build and price filters are applied after fetching. For very large areas add a date range so matching sales are found quickly.
- With `epcOnly` or a rating filter the actor looks through up to eight times as many sales as the number you asked for, to find enough rows that have a certificate.
- Registration lags completion: sales usually appear a few weeks to a couple of months after the sale date.
- The sales data covers England and Wales only. Scotland and Northern Ireland are not in the Price Paid Data.
- Not every property has a certificate. Certificates are lodged when a property is built, sold or let, so older sales and some flats have none. The summary row shows your coverage.
- If the EPC register is down or refuses access, the actor still delivers the sales, with empty EPC fields and `epcStatus` set to `epc-unavailable`, and it tells you in the run status message. You are only charged the sale event for such rows.

### Use cases

- **Estate agents, valuers and investors:** comparable sold prices with floor area, so every comparable has a price per square metre instead of a bare price.
- **Retrofit, insulation, solar and heat pump installers:** find recent buyers of homes rated E, F or G, with the wall, roof, window and heating description for a tailored pitch. Buyers who have just moved are the most likely to renovate.
- **Mortgage and green-finance lenders:** attach an energy band to recent completions to study the link between rating and price.
- **Property data teams and analysts:** build a price-per-square-metre series by postcode, rating band and construction era.
- **Proptech products:** feed a valuation model or a dashboard with sold prices and building attributes from two official sources through one API call.
- **Researchers and journalists:** measure the energy-rating premium or discount in a town, with a repeatable method and a named source.
- **Lead generation for movers, removals and home services:** fresh completions in a postcode or town, filtered by the kind of property they bought.

### Example input

```json
{ "postcodes": ["M1 1AE"], "maxItems": 12 }
```

Retrofit leads: detached and semi-detached homes rated E to G in Leeds, last three years:

```json
{ "towns": ["LEEDS"], "propertyTypes": ["detached", "semi-detached"], "yearsBack": 3, "epcRatings": ["E", "F", "G"], "maxItems": 200 }
```

Monitor new sales weekly with EPC data attached:

```json
{ "counties": ["WEST YORKSHIRE"], "monitorNewSales": true, "epcOnly": true, "maxItems": 500 }
```

### Output sample

Each result is one dataset item (JSON, CSV, Excel or API). Shape taken from the actor dataset schema; field names and meanings below, not live data:

| Field | Meaning |
|---|---|
| `recordType` | `sale`, or `summary` for the free per-place statistics row |
| `dateOfTransfer`, `price` | Sale date and price paid |
| `address`, `postcode`, `propertyType`, `newBuild`, `tenure` | Land Registry address and property attributes |
| `epcMatched`, `epcStatus` | Whether a certificate was matched: `matched`, `no-certificate`, `ambiguous`, `filtered-out`, `epc-unavailable` |
| `epcBasis` | `in-force-at-sale` or `latest-lodged` |
| `epcRating`, `epcScore` | Current energy band (A to G) and SAP score |
| `epcPotentialRating`, `epcPotentialScore` | Band and score after the recommended improvements |
| `floorAreaM2`, `pricePerM2` | Total floor area and price divided by floor area |
| `epcPropertyType`, `epcBuiltForm` | House, flat, bungalow and detached, semi, terrace |
| `constructionAgeBand` | Construction era such as 1930-1949 |
| `mainHeating`, `mainHeatingControls` | Heating system and controls |
| `wallsDescription`, `roofDescription`, `windowsDescription` | Fabric descriptions |
| `habitableRooms` | Number of habitable rooms |
| `co2TonnesPerYear`, `energyUseKwhPerM2` | Modelled emissions and energy use |
| `estimatedAnnualEnergyCostGbp` | Heating, hot water and lighting cost estimate |
| `epcLodgementDate`, `epcInspectionDate`, `epcAgeYears` | When the certificate was lodged and how old it is |
| `epcLodgedBeforeSale` | True when the certificate predates the sale |
| `uprn` | Unique property reference number, for joining to your own data |
| `epcCertificateNumber`, `epcSource`, `epcLicence` | Provenance for audit |
| `sourceUrl` | Link to the authoritative Land Registry record |
| `medianPrice`, `averagePrice`, `count`, `epcMatchedCount`, `epcCoveragePct`, `medianEpcScore`, `medianFloorAreaM2`, `medianPricePerM2`, `epcRatingMix` | Summary row statistics |

Every EPC field is nullable. If a sale has no certificate, all of them are present and `null`, so your CSV columns and schemas stay stable from row to row.

### Pricing

Pay per event. $0.001 per sale record returned (about $1 per 1,000), with the matched EPC certificate included in that price. Actor start $0.00005. Summary rows and already-seen sales are never charged. Set Maximum cost per run to cap spend; the actor stops cleanly when the cap is reached and keeps everything it has already delivered.

A quick estimate: 1,000 sales cost about $1.00 whether or not each one has a matching certificate.

### Licence and privacy

Sales: Contains HM Land Registry data (c) Crown copyright and database right, licensed under the Open Government Licence v3.0. The dataset has no buyer or seller names.

Energy certificates: Contains public sector information from the Ministry of Housing, Communities and Local Government (MHCLG) Energy Performance of Buildings Register, licensed under the Open Government Licence v3.0. The non-address certificate fields (ratings, scores, floor area, construction, heating and so on) are open data.

Address notice: the register address data is licensed under Ordnance Survey and Royal Mail terms for energy-efficiency purposes. For that reason this actor uses the certificate address only to match a certificate to a sale and does not output it; the addresses in the output come from HM Land Registry. Any use you make of the output remains your responsibility. If you share address-level data downstream, check that your purpose is covered by those terms and include the notices above.

Personal data: a property address can be personal data under UK GDPR when it is linked to a person. This dataset links no names, but you should have a lawful basis for the way you use address-level data, particularly for direct marketing.

### FAQ

**How do I try it quickly?** Press Start with the prefilled input. It is a small run of 5 sales that finishes in about a minute.

**Do I need an EPC account or token?** No. The actor carries its own access to the register.

**How accurate is the address matching?** On live postcodes across Manchester and Leeds the actor matched about 92% of sales to a certificate. Unmatched rows are mostly properties that have never had a certificate lodged. Ambiguous addresses are never guessed.

**Why does my row show a certificate older than the sale?** That is deliberate. The certificate in force at the sale date describes the property as it was sold. `epcBasis` and `epcLodgedBeforeSale` tell you which case applies.

**Why is a floor area missing on a matched row?** Very occasionally the register detail record cannot be fetched. The rating band from the search is still returned and the remaining fields are null.

**How is it priced?** Pay per event; see the Pricing section or the Pricing tab. A small run costs very little.

**Can it run on a schedule?** Yes. Use Apify schedules or the API, ideally with new-sales monitoring switched on.

**What if the source is slow or fails?** Failed or rate-limited requests (HTTP 429 or 5xx, network errors) are retried up to 4 attempts with growing waits. If a source stays unavailable the run ends cleanly with a status message instead of crashing, and nothing is charged for rows you did not receive.

**Does it cover Scotland?** Not the sales side. The Land Registry Price Paid Data covers England and Wales only.

**Is the data legal to use?** The sales and the non-address certificate data are published under the Open Government Licence v3.0, which permits commercial reuse with attribution. See the licence notice above for the address-data terms. You are responsible for using the results in line with applicable law.

**Can I use it through the API or an AI agent?** Yes. Call the actor through the Apify API, or use the MCP server below.

### Use with the Apify MCP server

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?actors=transparent_meteorite/uk-property-sold-prices-epc",
      "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
    }
  }
}
```

### Related actors

Other public-data actors from the same publisher that pair well with this one:

- [UK House Sold Prices: Land Registry Data](https://apify.com/transparent_meteorite/uk-land-registry-sold-prices)
- [Business Entity Search: US State Registries](https://apify.com/transparent_meteorite/business-entity-search)

### Alternatives to UK Property Sold Prices + EPC

Other ways to get similar data, so you can choose what fits:

- **Downloading the Price Paid Data and EPC bulk files yourself**: free, but you must write the address matching and keep both files fresh
- **Property portal scrapers**: wide listing coverage, but scraped pages break and sold-price depth varies
- **Commercial property data platforms**: broad coverage and valuation models at subscription prices
- **A sold-price actor plus a separate EPC actor**: works, but two runs, two bills and your own join

This actor edge is one run that returns the sale and its certificate together, a certificate chosen as of the sale date, an energy-rating filter, and pay-per-result pricing with no login. Compare on a small test run before you commit.

### Changelog

- **0.1** (2026-10-29): first release. Land Registry sales joined to the EPC register by postcode and address, rating filter, price per square metre, EPC summary statistics and new-sales monitor.

# Actor input Schema

## `postcodes` (type: `array`):

Full UK postcodes, e.g. M1 1AE. One search per postcode. If given, towns, districts and counties are ignored.

## `towns` (type: `array`):

Town names as recorded by HM Land Registry, e.g. LEEDS. Exact match.

## `districts` (type: `array`):

Local authority district names, e.g. CITY OF WESTMINSTER. Exact match.

## `counties` (type: `array`):

County names, e.g. WEST YORKSHIRE or GREATER LONDON. Exact match.

## `street` (type: `string`):

Narrow the area to one street name, e.g. NEWTON STREET. Exact match, combined with the town, district, county or postcode.

## `yearsBack` (type: `integer`):

Only sales in the last N years. Ignored if Date from is set.

## `dateFrom` (type: `string`):

Earliest transfer date, e.g. 2024-01-01.

## `dateTo` (type: `string`):

Latest transfer date.

## `propertyTypes` (type: `array`):

Leave empty for all types.

## `newBuild` (type: `string`):

Filter by the new-build flag.

## `minPrice` (type: `integer`):

Optional lower price bound.

## `maxPrice` (type: `integer`):

Optional upper price bound.

## `epcOnly` (type: `boolean`):

Deliver (and charge for) only sales that were matched to an EPC certificate, looking further back through the sales list to find them. Without it, unmatched sales are still returned with empty EPC fields and charged only the sale price.

## `epcRatings` (type: `array`):

Only sales whose matched EPC energy band is one of these (A is best, G is worst). Implies 'Only sales with an EPC'. Leave empty for all.

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

Cap on sale records delivered (and charged) this run, split evenly across the places searched. Most recent first.

## `includeStats` (type: `boolean`):

Adds one free summary row per place: count, median, average, min, max, breakdown by property type, plus EPC coverage, median EPC score, median floor area, median price per m2 and the rating mix.

## `monitorNewSales` (type: `boolean`):

Skip sales delivered in a previous run (tracked in a named key-value store). Schedule the actor daily or weekly to be told about new sales with their EPC data. A repeat run with nothing new delivers and charges nothing.

## `stateStoreName` (type: `string`):

Named key-value store that remembers delivered sales. Change it to keep separate monitors or reset it.

## Actor input object example

```json
{
  "postcodes": [
    "M1 1AE"
  ],
  "newBuild": "any",
  "epcOnly": false,
  "maxItems": 5,
  "includeStats": true,
  "monitorNewSales": false,
  "stateStoreName": "uk-sold-prices-epc-seen"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "postcodes": [
        "M1 1AE"
    ],
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("transparent_meteorite/uk-property-sold-prices-epc").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 = {
    "postcodes": ["M1 1AE"],
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("transparent_meteorite/uk-property-sold-prices-epc").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 '{
  "postcodes": [
    "M1 1AE"
  ],
  "maxItems": 5
}' |
apify call transparent_meteorite/uk-property-sold-prices-epc --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,transparent_meteorite/uk-property-sold-prices-epc"
        }
    }
}
```

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/tjVtQhgJLw2T7EYJz/builds/GDqUKBojACVroDrx4/openapi.json
