Blog / API guides

Zoopla API: UK Listings and Sold Prices as JSON

Zoopla's own API access is for its member agents and approved partners, not for anyone with a key. To read Zoopla listings, sold prices and valuation history as JSON, the Perceptlayer Zoopla API has 17 GET endpoints at 1 credit per successful call. Resolve a place with /v1/zoopla/locations, search it with /v1/zoopla/search, then pull sold records with /v1/zoopla/sold and a single property's history by its UPRN.

Is there an official Zoopla API?

Not one you can sign up for and use to read listings. The APIs Zoopla documents are for its members' products, such as Premium Listings and Featured Properties, and its authentication guide describes OAuth 2.0 client credentials that Zoopla issues and revokes through your technical contact (Zoopla tech documentation, 2023). The site's terms of use say you may not use its content for commercial purposes without a licence from Zoopla, and they name developing an AI system as one such use (2026).

That gives you two routes. If you're building a commercial product on Zoopla's data, such as a valuation tool you sell, ask Zoopla for a licence: it's the only route that gives you the rights to redistribute. If you need structured Zoopla data for analysis, research or an internal tool, the Zoopla API returns it as JSON with one key. Whether your use is allowed still depends on Zoopla's terms and UK law, and Perceptlayer can't advise on that.

What can the Zoopla API return?

Seventeen endpoints cover three jobs: finding listings in an area, reading sold prices and market statistics, and looking up one property by its Unique Property Reference Number (UPRN). Every endpoint is a GET request, returns JSON and costs 1 credit when it succeeds. The table groups them by what you pass in, which is the order you'll call them.

You have Endpoint Required Credits
A place name or outcode /v1/zoopla/locations query 1
A location /v1/zoopla/search, /v1/zoopla/search-count location 1
A location /v1/zoopla/sold location 1
Location paths /v1/zoopla/sold-summary paths[] 1
An outcode /v1/zoopla/market-insights outcode 1
A geography /v1/zoopla/market-activity geo 1
A postcode /v1/zoopla/addresses postcode 1
A UPRN property, property-valuation-history, property-nearby-sold, property-similar, property-demand, property-agents, market-local-stats uprn 1 each
A listing ID /v1/zoopla/listing listingId 1
A branch ID /v1/zoopla/agent branchId 1

The UPRN endpoints are the part a listings search can't give you. A UPRN identifies the property rather than a listing, so it stays the same across sales and lettings, and it is the key to join Zoopla records to your own address data.

How do you search Zoopla listings?

Call GET /v1/zoopla/search with a location and, optionally, a section and a page. The location can be an outcode such as sw1a; if you start from a place name, call /v1/zoopla/locations with it first and use what it returns. section picks the listing type: for-sale, to-rent or new-homes. This request asks for the first page of homes for sale in SW1A:

curl "https://api.perceptlayer.com/v1/zoopla/search?location=sw1a&section=for-sale&page=1" \
  -H "X-API-Key: $API_KEY"

Keys start with sk_live_ and go in the X-API-Key header; get a free API key and see the authentication docs for the rest.

These are all the search parameters. Nothing else about them is documented, so don't rely on a default sort or page size.

Parameter Type Required Notes
location string yes Up to 32 characters, such as an outcode
section string no for-sale, to-rent or new-homes
page integer no Results page

GET /v1/zoopla/search-count takes the same location and section and returns the count for that search, which tells you how many pages to expect before you spend credits on them. We don't have a recorded Zoopla response to show here, so run the call in the playground on the Zoopla API page to see the fields for yourself.

How do you get Zoopla sold prices?

Use GET /v1/zoopla/sold for sold records in an area. It takes a required location and four optional parameters: from_last_sale_date and to_last_sale_date bound the sale dates, and first and after page through the results. The names follow the usual cursor pattern, where first is how many records to return and after is the cursor from the previous page. Check the response in the playground for where the cursor appears.

curl "https://api.perceptlayer.com/v1/zoopla/sold?location=sw1a&first=50" \
  -H "X-API-Key: $API_KEY"
Parameter Type Required Notes
location string yes Up to 32 characters
first integer no Records per page
after string no Cursor from the previous page, up to 255 characters
from_last_sale_date string no Earliest last sale date
to_last_sale_date string no Latest last sale date

For an aggregate rather than a list, GET /v1/zoopla/sold-summary takes one or more paths[] values, each up to 120 characters, with optional section and location. GET /v1/zoopla/market-activity gives market activity for a geo (up to 32 characters), with range_months from THREE_MONTHS to ALL and house_type of ALL, DETACHED, SEMI_DETACHED, FLAT or TERRACED.

How do you get a property's valuation history by UPRN?

Pass the UPRN to GET /v1/zoopla/property-valuation-history. Every per-property endpoint takes the same single uprn parameter, so once you have it, the property record, its valuation history, nearby sold homes, similar homes, demand and agents are each one more call. If you only have an address, call GET /v1/zoopla/addresses with the postcode to find the property among the addresses listed there.

curl "https://api.perceptlayer.com/v1/zoopla/addresses?postcode=SW1A%202EP" \
  -H "X-API-Key: $API_KEY"

curl "https://api.perceptlayer.com/v1/zoopla/property-valuation-history?uprn=100023337105" \
  -H "X-API-Key: $API_KEY"

property-agents also takes an optional transaction_type of SALE or RENT. Note the space in the postcode is URL-encoded as %20.

A short Python loop runs the same lookups for a list of UPRNs and saves each response as it comes, so a failure halfway through doesn't lose the rest:

import json
import os
import requests

BASE = "https://api.perceptlayer.com/v1/zoopla"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}
UPRNS = ["100023337105"]  # your list

for uprn in UPRNS:
    for endpoint in ("property", "property-valuation-history", "property-nearby-sold"):
        r = requests.get(f"{BASE}/{endpoint}", params={"uprn": uprn}, headers=HEADERS, timeout=60)
        if r.status_code != 200:
            print(uprn, endpoint, r.status_code, r.json()["error"]["code"])
            continue
        with open(f"{uprn}-{endpoint}.json", "w") as f:
            json.dump(r.json(), f)
        print(uprn, endpoint, "credits used:", r.headers["X-Credits-Used"])

We haven't run this script against the live API for this article. Each successful call prints credits used: 1. A failed one prints its error code, such as not_found or invalid_parameters, and costs nothing. The errors docs list every code.

What does a postcode sweep cost?

Every Zoopla endpoint costs 1 credit per successful call, so the cost of a sweep is the number of calls. Take 20 outcodes. For each one, a search-count call, 5 pages of search and 4 pages of sold is 10 calls, so 20 × 10 = 200 credits. Valuing 300 of the properties you found, with property-valuation-history and property-nearby-sold for each, adds 300 × 2 = 600 credits.

Step Calls Credits
search-count, one per outcode 20 20
search, 5 pages per outcode 100 100
sold, 4 pages per outcode 80 80
Two UPRN lookups for 300 properties 600 600
Total 800 800

That's 800 credits, inside the 1,000 free credits every verified account gets each month. Run it weekly and it's 800 × 4 = 3,200 credits a month, within the Starter pack's 10,000. Failed calls return X-Credits-Used: 0, so retries after an error don't add to it. The credits docs explain the balance, and pricing has what packs cost.

When is HM Land Registry data the better source?

For completed sale prices in England and Wales, start with HM Land Registry. Its Price Paid Data covers residential sales in England and Wales sold for value and lodged for registration, is updated monthly, and is free to use for commercial or non-commercial purposes under the Open Government Licence (HM Land Registry, 2026). It is the register, so it is the authoritative price.

It has gaps a listing site fills. The two most recent months are incomplete because registration lags the sale, and it records the price paid, not the asking price, the agent or how a valuation moved over time. Zoopla's endpoints add live listings, asking prices, agents and valuation history by UPRN. A common split is Land Registry for the sold price and Zoopla for everything around it. For Scotland and Northern Ireland, which the Price Paid Data doesn't cover, listing sites matter more. The Rightmove API covers the other large UK portal if you want a second source for the same areas.

To try it now, run a search for your own outcode in the playground on the Zoopla API page.

APIs in this post

Frequently asked questions

How much does the Zoopla API cost?

Each of the 17 Zoopla endpoints costs 1 credit per successful call, and failed calls cost nothing. Every verified account gets 1,000 free credits a month, enough for 1,000 searches or property lookups. Beyond that, credits come in prepaid packs from 10,000 credits, and the pricing page has what they cost.

Do I need a Zoopla developer account?

No. One Perceptlayer key in the X-API-Key header works for Zoopla and every other API in the catalogue. Zoopla's own credentials are issued to its members and partners for their integrations. If you need a licence to republish Zoopla's data commercially, that has to come from Zoopla itself.

What is a UPRN and where do I get one?

A UPRN is a Unique Property Reference Number, an identifier for an addressable property rather than for one listing of it. Nine Zoopla endpoints take it as uprn. If you start from an address, call /v1/zoopla/addresses with the postcode and pick the property from the addresses it returns.

Does the sold endpoint cover all UK sales?

It returns the sold records Zoopla shows for the location you ask for, as found at the time of the call. For the authoritative record of England and Wales sale prices, use HM Land Registry's free Price Paid Data, and treat Zoopla's sold data as a way to join prices to listings, agents and valuation history.

What happens if I send a location Zoopla doesn't recognise?

The call fails with an error code and a message in a JSON body, and X-Credits-Used is 0, so a bad location costs nothing. Values over the length limits, such as a location longer than 32 characters, fail with invalid_parameters (422). The errors docs list every code.

  1. Rightmove API: Get UK Property Listings and Sold Prices

    Pull Rightmove UK listings, sold prices and agents as JSON with 8 endpoints at 1 credit per call, with a real London search response and cURL examples.

  2. Redfin API: Search Homes, Then Property and Valuation

    Four Redfin endpoints at 1 credit each: find a region, search homes with a real JSON response, then call property and valuation by property_id.

  3. Realestate.com.au API: Australian Listings as JSON

    Search realestate.com.au by location and channel (buy, rent, sold), then open each listing by URL. Parameters, a recorded Sydney response and the cost.

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.