Blog / Web data by industry

UK Sold House Price Data: What Listing Sites Add

For UK sold house prices, start with HM Land Registry's Price Paid Data: it is free, covers residential sales in England and Wales, and is the authoritative record of what was paid. Listing sites add what the register leaves out: the asking price and how it changed, the agent, rooms and size, and valuation history. The useful dataset joins the two, and since August 2026 Land Registry publishes a UPRN for new sales, which makes that join exact.

Where should UK sold prices come from?

From HM Land Registry, for England and Wales. Its Price Paid Data covers residential property sold for value and lodged for registration, is free to use for commercial and non-commercial purposes under the Open Government Licence, and is updated monthly (HM Land Registry, 2026). It is the register, so it is the figure to use for "what did this sell for".

Each row has a transaction ID, the price from the transfer deed, the completion date, the postcode and address parts, a property type code (D detached, S semi-detached, T terraced, F flat, O other), an Old/New flag (Y for a new build), a duration (F freehold or L leasehold) and a PPD category (A for standard sales, B for additional types such as repossessions and buy-to-lets). The files have no header row; the columns come in that documented order.

It has limits worth knowing before you build on it. The two most recent months are incomplete, because the gap between a sale and its registration typically runs from two weeks to two months. Prices are transaction prices, not market values: a transfer within a family can be fixed far from market value. And it covers England and Wales only, so Scotland and Northern Ireland need other sources.

What do listing sites add to sold prices?

The context around the sale. Land Registry records the end of the process, the price paid. A listing site records the process itself: what the seller asked, when the property was listed, whether the price was cut, who the agent was, and the rooms and size buyers saw. Zoopla also exposes valuation history and nearby sales for a property by its UPRN. The table maps each question to the source that answers it.

Question Best source Endpoint or field
What did it sell for, and when? HM Land Registry Price, Date of Transfer
What was the asking price? Rightmove, Zoopla listings price.amount on Rightmove search; /v1/zoopla/listing
Was the price reduced? Rightmove addedOrReduced, listingUpdate.listingUpdateReason
Which agent handled it? Rightmove, Zoopla customer.branchDisplayName; /v1/zoopla/property-agents
Bedrooms, size, tenure Rightmove bedrooms, displaySize, tenure.tenureType
How has its estimated value moved? Zoopla /v1/zoopla/property-valuation-history by uprn
What sold nearby? Zoopla, Rightmove /v1/zoopla/property-nearby-sold; /v1/rightmove/sold-properties

Rightmove's sold-properties endpoint filters by postcode, property_type (DETACHED, FLAT, TERRACED, SEMI_DETACHED), tenure and sold_in (3, 6, 12, 24 or 120 months). Zoopla's sold endpoint takes a location and sale-date bounds. Both are listing-site views of completed sales, useful for joining to listings; for the price itself, the register wins.

Which listing fields are worth keeping?

Keep the fields that explain a price, and the ones you need to match records. Our recorded Rightmove search for location=London&channel=BUY shows the asking side. This excerpt is its first listing, trimmed with …:

{
  "id": 90486465,
  "bedrooms": 3,
  "bathrooms": 2,
  "displayAddress": "Cavaye Place, Chelsea, London, SW10",
  "location": { "latitude": 51.486678, "longitude": -0.180225 },
  "propertySubType": "Apartment",
  "tenure": { "tenureType": "LEASEHOLD" },
  "listingUpdate": { "listingUpdateReason": "new", "listingUpdateDate": "2026-07-03T22:30:31Z" },
  "price": { "amount": 1495000, "currencyCode": "GBP", … },
  "customer": { "branchId": 298991, "branchDisplayName": "OB Private, Mayfair", … },
  "displaySize": "1,285 sq. ft.",
  "channel": "BUY",
  "addedOrReduced": "Added on 03/07/2026",
  …
}
Field Keep it because Watch out for
price.amount The asking price, numeric It's what the seller wants, not what the buyer paid
listingUpdate.listingUpdateReason, listingUpdateDate Why and when the listing last changed (new in the recording) Store every observation to see changes over time
addedOrReduced The site's own text, such as Added on 03/07/2026 Display text; parse the date carefully
bedrooms, bathrooms Explain price differences within a type Land Registry has no room counts to check against
displaySize Floor area when the agent gives it Text, sometimes empty
tenure.tenureType Matches Land Registry's F/L duration Leasehold length isn't in either excerpt
propertySubType Maps roughly to D, S, T, F "Apartment" and "Flat" both map to F
customer.branchDisplayName, branchId Agent share and agent-level analysis A branch, not a person
channel Filters out commercial stock The same response has a COMMERCIAL_BUY listing
location Distance to sales and to each other Use it for distance, not to identify an address

Two details from the same recording matter for sold-price work. The second listing in it is Land at 65000000 with channel COMMERCIAL_BUY, inside a residential BUY search, so filter on channel and propertySubType before computing anything. And two of the three displayAddress values stop at the street and outcode (SW10, W1W), which is too coarse to match one listing to one Land Registry sale.

How do you join a sale to a listing?

By UPRN where you can, by address where you must. HM Land Registry now publishes a lookup from Price Paid transaction IDs to UPRNs. It was first published on 28 August 2026, isn't back-dated, includes a UPRN only where Land Registry can reliably link the title address to an addressable location, and carries its own licence conditions and an Ordnance Survey attribution (HM Land Registry, 2026).

With a UPRN, every Zoopla property endpoint is one call: /v1/zoopla/property, property-valuation-history, property-agents and property-nearby-sold each take uprn and cost 1 credit. That turns a bare sale row into a sale with its valuation history and agents. We don't have a recorded Zoopla response, so check which fields each returns in the playground on the Zoopla API page before you design your tables.

For older sales, or for Rightmove, match on address. Normalise the postcode (upper case, single space), the house number or name (PAON), the flat (SAON) and the street, and treat a match as certain only when all of them agree. The article on deduplicating listings across sources covers the matching method. Where the listing address stops at the outcode, don't force a property-level match; use the aggregate comparison below instead.

How do you measure the asking-to-sold gap for an area?

Compare like with like at area level: median asking price from current listings against median sold price from the register, for the same outcode and property type. This works without any property-level match. It measures the market, not individual negotiations, so it's a first look rather than a precise discount. The script reads a Price Paid CSV by column position, which follows Land Registry's documented order, and pages a Rightmove search for one outcode.

import csv
import os
import statistics
import requests

OUTCODE, LR_TYPE, RM_TYPES = "SW10", "F", {"Flat", "Apartment"}

# Land Registry Price Paid Data: no header row; columns in documented order.
sold = []
with open("pp-2026.csv", newline="") as f:
    for row in csv.reader(f):
        price, postcode, ptype, category = int(row[1]), row[3], row[4], row[14]
        if postcode.split(" ")[0] == OUTCODE and ptype == LR_TYPE and category == "A":
            sold.append(price)

asking, credits = [], 0
for page in range(1, 6):
    r = requests.get("https://api.perceptlayer.com/v1/rightmove/search",
                     params={"location": OUTCODE, "channel": "BUY", "page": page},
                     headers={"X-API-Key": os.environ["API_KEY"]}, timeout=60)
    if r.status_code != 200:
        break
    credits += int(r.headers["X-Credits-Used"])
    data = r.json()["data"]
    for p in data["properties"]:
        if p["channel"] == "BUY" and p.get("propertySubType") in RM_TYPES:
            asking.append(p["price"]["amount"])
    if not data.get("has_next_page"):
        break

if sold and asking:
    s, a = statistics.median(sold), statistics.median(asking)
    print(f"{OUTCODE} flats: median sold {s:,.0f} (n={len(sold)}), "
          f"median asking {a:,.0f} (n={len(asking)}), gap {(s - a) / a:+.1%}")
print("credits used:", credits)

We tested the script on a sample row and the recorded Rightmove fields, not against live calls. It keeps only category A sales, which drops repossessions and other non-standard transfers, and only BUY listings of flats. Read the result with its sample sizes. The two sets differ in timing (sales completed months ago against today's asking prices) and in mix (which flats happen to be listed now), so a gap of a few per cent can be noise. Run it monthly per outcode and watch the trend.

What does the listing side cost?

Land Registry's data is free. Each listing-site call is 1 credit on success and 0 on failure, so the cost is pages and lookups. The script above reads up to 5 Rightmove pages per outcode: 20 outcodes monthly is at most 20 × 5 = 100 credits. Adding Zoopla valuation history and agents for 200 sales with a UPRN is 200 × 2 = 400 credits.

Step Calls a month Credits
Rightmove search, 20 outcodes × 5 pages 100 100
Zoopla property-valuation-history + property-agents, 200 UPRNs 400 400
Total 500 500

That's 500 credits, inside the 1,000 free credits every verified account gets each month. The credits docs explain the balance and pricing has what packs cost. The Rightmove API guide covers search paging and its record cap; to start, run a sold-properties call for your own postcode in the playground on the Rightmove API page.

APIs in this post

Frequently asked questions

Is HM Land Registry sold price data free?

Yes. Price Paid Data is free to download and use, for commercial or non-commercial purposes, under the Open Government Licence, with an attribution statement. It covers residential sales in England and Wales sold for value and is updated monthly. The transaction-to-UPRN lookup has its own licence conditions, so read those before you use it.

Why are the latest months missing sales?

Price Paid Data follows registration, not completion. HM Land Registry says the gap between a sale and its registration typically runs from two weeks to two months, so the two most recent months are incomplete. Don't read a drop in recent volumes as a market change until those months fill in.

Can listing sites tell me the actual sold price?

They show completed sales, and Rightmove's sold-properties and Zoopla's sold endpoints return them, but the authoritative price for England and Wales is the Land Registry record. Use listing-site sold data to join a sale to its listing, agent and valuation history, and the register for the price itself.

How do I match a Rightmove listing to a Land Registry sale?

Only when both have the full address. The recorded Rightmove search shows some displayAddress values with only the street and outcode, which can't identify one property. Match on normalised postcode, house number or name, flat and street when they're all present; otherwise compare at outcode level by property type.

What does it cost to add listing data to Land Registry sales?

Land Registry data costs nothing. Listing calls are 1 credit each when they succeed and nothing when they fail: 100 Rightmove search pages and 400 Zoopla UPRN lookups a month is 500 credits, inside the 1,000 free monthly credits. The pricing page has what credit packs cost beyond that.

  1. Job Posting Data for Labour-Market Research

    Which Indeed posting fields support trend analysis, where postings mislead versus hires, and a weekly collection plan that costs 3,000 credits a month.

  2. Salary Data from Job Sites: Reading Ranges Without Bias

    Glassdoor's salaries endpoint returns p10 to p90 total pay, a currency and a national count. How to read those ranges and the biases of self-reported pay.

  3. Software Review Data Analysis for Competitive Research

    What Capterra, Trustpilot and Google Play reviews can and can't tell you about a competitor, which fields to keep, the sampling bias, and a worked rating tally.

Start with 1,000 free credits

No password to set. We email you a sign-in link, and your key works on every API.

No credit card. 1,000 free credits a month.