UK Land Registry Sold House Prices Scraper avatar

UK Land Registry Sold House Prices Scraper

Pricing

from $6.80 / 1,000 results

Go to Apify Store
UK Land Registry Sold House Prices Scraper

UK Land Registry Sold House Prices Scraper

Scrape recorded UK house sale prices from HM Land Registry Price Paid Data for England and Wales. Get full address, price paid, sale date, property type, tenure, new-build flag and transaction category by postcode or town. Export to JSON, CSV or Excel.

Pricing

from $6.80 / 1,000 results

Rating

0.0

(0)

Developer

Scrapers Lat

Scrapers Lat

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

6 days ago

Last modified

Share

UK Land Registry Sold House Prices Scraper

UK Land Registry Sold House Prices Scraper

Here is one real result, with every field the actor returns:

{
"transactionId": "3B5CE841-9457-EE3A-E063-4804A8C0D6F1",
"pricePaid": 217750,
"transactionDate": "2025-06-30",
"propertyType": "Semi-detached",
"propertyTypeCode": "S",
"tenure": "Freehold",
"tenureCode": "F",
"newBuild": false,
"transactionCategory": "Standard price paid transaction",
"recordStatus": "Add",
"saon": null,
"paon": "104",
"street": "PATTINSON DRIVE",
"locality": "MAINSTONE",
"town": "PLYMOUTH",
"district": "CITY OF PLYMOUTH",
"county": "CITY OF PLYMOUTH",
"postcode": "PL6 8RU",
"addressFull": "104, PATTINSON DRIVE, MAINSTONE, PLYMOUTH, PL6 8RU",
"source": "HM Land Registry Price Paid Data",
"observedAt": "2026-08-10T14:31:28.743Z"
}

The most complete UK sold house prices scraper available. It returns every field HM Land Registry Price Paid Data exposes for each recorded sale, plus a single-line addressFull and normalized type and tenure codes, and gives you six filters to target exactly the sales you need.

📥 Input · 📤 Output · 💰 Pricing · ▶️ Examples

Apify Coverage Output Billing

Table of contents

What it does

The actor queries HM Land Registry Price Paid Data, applies the filters you pass as input (postcodes, towns, property types, price range, date range), paginates through the matching recorded sales, and writes one normalized record per sale to the run's dataset. Each record carries the full split address plus a single-line addressFull, the price paid, sale date normalized to YYYY-MM-DD, property type and tenure with both label and short code, a new-build flag and the transaction category. Missing source values are returned as null.

Data covers recorded residential property sales in England and Wales. It is the official price paid on registration, not asking prices or current listings.

Quickstart

Open the actor, paste this into the input, and press Run. It returns the most recent recorded sales at one postcode.

{
"postcodes": ["PL6 8RU"],
"maxRecords": 10
}

Provide at least one postcode or one town. Postcode searches are the fastest and most precise and are returned newest first. Town searches can return large volumes, so pair them with a date range and price range.

Input reference

FieldTypeRequiredDefaultDescription
postcodesstring[]conditional(none)One or more full UK postcodes, for example ["PL6 8RU", "SW1A 1AA"]. Each returns every recorded sale registered against it, newest first. Required unless you pass towns.
townsstring[]conditional(none)One or more town names, for example ["PLYMOUTH", "LONDON"]. Town searches can be large; pair with price and date filters. Required unless you pass postcodes.
propertyTypesstring[]no(all)Keep only these property types, by code: D (Detached), S (Semi-detached), T (Terraced), F (Flat / Maisonette), O (Other). Words like detached also work. Leave empty for all.
minPriceintegerno(none)Only return sales at or above this price paid, in GBP.
maxPriceintegerno(none)Only return sales at or below this price paid, in GBP.
fromDatestringno(none)Only return sales on or after this date (YYYY-MM-DD).
toDatestringno(none)Only return sales on or before this date (YYYY-MM-DD).
maxRecordsintegerno50Maximum number of recorded sales to collect across all searches.

At least one of postcodes or towns must be supplied. Filters combine with logical AND.

Output reference

One dataset item per recorded sale. Types: string, integer, boolean, or null when the source value is absent.

FieldTypeDescription
transactionIdstringHM Land Registry transaction identifier, unique per recorded sale.
pricePaidintegerPrice paid in GBP.
transactionDatestringDate of sale (YYYY-MM-DD).
propertyTypestringProperty type label: Detached, Semi-detached, Terraced, Flat / Maisonette or Other.
propertyTypeCodestringShort property type code: D, S, T, F or O.
tenurestringTenure: Freehold or Leasehold.
tenureCodestringShort tenure code: F or L.
newBuildbooleantrue if the sale was of a newly built property, false otherwise, null when unknown.
transactionCategorystringTransaction category, for example Standard price paid transaction.
recordStatusstringRecord status in Price Paid Data, for example Add or Change.
saonstringSecondary addressable object name (flat or unit), or null.
paonstringPrimary addressable object name (house number or name).
streetstringStreet name.
localitystringLocality, or null.
townstringTown or city.
districtstringLocal district.
countystringCounty.
postcodestringFull postcode.
addressFullstringThe non-empty address parts joined into one line.
sourcestringAlways HM Land Registry Price Paid Data.
observedAtstringISO 8601 timestamp of when the record was collected.
errorstringPresent only on a failed or empty run; a single item with this field is written instead of sales.

Example output record

Real record from a live run (input {"postcodes":["PL6 8RU"],"maxRecords":10}):

{
"transactionId": "3B5CE841-9457-EE3A-E063-4804A8C0D6F1",
"pricePaid": 217750,
"transactionDate": "2025-06-30",
"propertyType": "Semi-detached",
"propertyTypeCode": "S",
"tenure": "Freehold",
"tenureCode": "F",
"newBuild": false,
"transactionCategory": "Standard price paid transaction",
"recordStatus": "Add",
"saon": null,
"paon": "104",
"street": "PATTINSON DRIVE",
"locality": "MAINSTONE",
"town": "PLYMOUTH",
"district": "CITY OF PLYMOUTH",
"county": "CITY OF PLYMOUTH",
"postcode": "PL6 8RU",
"addressFull": "104, PATTINSON DRIVE, MAINSTONE, PLYMOUTH, PL6 8RU",
"source": "HM Land Registry Price Paid Data",
"observedAt": "2026-08-10T14:31:28.743Z"
}

Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace <TOKEN> with your Apify API token.

Run synchronously and get dataset items in one call:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~uk-land-registry-prices-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"postcodes":["PL6 8RU"],"maxRecords":25}'

Start a run asynchronously:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~uk-land-registry-prices-scraper/runs?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"towns":["PLYMOUTH"],"propertyTypes":["D"],"minPrice":300000,"fromDate":"2024-01-01","maxRecords":200}'

Apify CLI:

apify call scrapers_lat/uk-land-registry-prices-scraper \
--input '{"postcodes":["SW1A 1AA"]}'

Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing format:

# JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
# CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"
# Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"

<DATASET_ID> is returned as defaultDatasetId in the run object. Use offset and limit to page through large result sets. clean=true drops empty and internal fields.

Billing and limits

  • Pay per result. You are charged per recorded sale returned (result event). See the pricing tab for the current per-result price.
  • No charge on failure. If a run errors or matches nothing, the actor writes a single item with an error field and does not charge for it. Empty runs cost nothing.
  • Spend cap respected. Set maxTotalChargeUsd on the run; once reached, the actor stops emitting and charging further billable results.
  • Free Apify plans are capped at 10 records per run. Upgrade for a higher maxRecords.
  • Town searches are unsorted. Broad town queries are returned in source order (not sorted) because the source times out when sorting large result sets. Postcode searches are returned newest first. Pair town searches with price and date filters.

FAQ and troubleshooting

A run returned only an error record. Why? You ran with neither postcodes nor towns, or the search matched nothing. Add a postcode or a town. These cases are not charged.

How do I get the sale history of one property or street? Search by the full postcode. Every recorded sale registered against it is returned, newest first. Filter further with fromDate or minPrice if needed.

Why are saon or locality null? The Land Registry only records those when they apply (for example saon for a flat within a building). Missing source values are returned as null, never invented.

Does this include Scotland or Northern Ireland? No. Price Paid Data covers England and Wales only. Scotland and Northern Ireland maintain separate registers.

Are these asking prices? No. pricePaid is the actual price recorded on registration of the sale, not a listing or asking price.

Is this an official Land Registry tool? No. This actor is independent and has no affiliation with HM Land Registry. It reads only data published as open Price Paid Data. Use it in accordance with the Land Registry terms and the Open Government Licence.

More scrapers at scrapers.lat

Built and maintained by scrapers.lat, where we publish scrapers for US, UK, European and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at scrapers.lat.


Independent tool, not affiliated with HM Land Registry. Accesses only publicly available Price Paid Data. Use in accordance with the Land Registry terms and the Open Government Licence.