Zoopla property API
Search UK homes for sale or to rent on Zoopla, or open Zoopla property pages. Each home comes back as one record.
- Record types
property- Fields
- 46
- From
- $1.40 per 1,000 records
What you can request
Set mode in the request body to choose what comes back; without it the request runs as search. Each mode reads the inputs listed next to it.
| Mode | What comes back | Inputs | Billed as |
|---|---|---|---|
search | One record per listing in the results for each location or search URL. With | locations searchUrls listingType | property |
property | The full detail page for each property URL. | propertyUrls | property-detail |
Every request also takes maxItems (records for the whole request) and maxItemsPerInput (records per search, URL or name).
Example request and record
The request below is the one this example record answers. The names, usernames, photos and contact details of people in it are fictional. Long values in the record are shortened.
curl
curl -X POST https://api.urakimon.com/records/zoopla \
-H "x-api-key: $URAKIMON_API_KEY" \
-H "content-type: application/json" \
-d '{
"mode": "property",
"propertyUrls": [
"https://www.zoopla.co.uk/for-sale/details/74288252/",
"https://www.zoopla.co.uk/for-sale/details/74285103/"
]
}'Python
import os
import requests
res = requests.post(
"https://api.urakimon.com/records/zoopla",
headers={"x-api-key": os.environ["URAKIMON_API_KEY"]},
json={
"mode": "property",
"propertyUrls": [
"https://www.zoopla.co.uk/for-sale/details/74288252/",
"https://www.zoopla.co.uk/for-sale/details/74285103/"
]
},
)
res.raise_for_status()
records = res.json()["records"]Node
const res = await fetch("https://api.urakimon.com/records/zoopla", {
method: "POST",
headers: {
"x-api-key": process.env.URAKIMON_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"mode": "property",
"propertyUrls": [
"https://www.zoopla.co.uk/for-sale/details/74288252/",
"https://www.zoopla.co.uk/for-sale/details/74285103/"
]
}),
});
const { records } = await res.json();{ "source": "zoopla", "type": "property", "portal": "zoopla", "id": "74288252", "url": "https://www.zoopla.co.uk/for-sale/details/74288252/", "listingType": "for-sale", "category": "residential", "status": "Just added", "price": 250000, "priceText": "£250,000", "priceQualifier": "Guide price", "pricePerSqFt": null, "currency": "GBP", "isAuction": false, "bedrooms": 1, "bathrooms": 1, "livingRooms": 1, "propertyType": "flat", "tenure": null, "address": { "displayAddress": "Argyle Road, Ilford, Essex IG1", "street": "Argyle Road", "outcode": "IG1", "incode": "3BQ", "postalCode": "IG1 3BQ", "region": "East of England", "country": "GB", "uprn": null }, "coordinates": { "lat": 51.560598, "lng": 0.067208 }, "description": "This is a first floor converted flat with shared driveway. The flat has plenty of space, high ceilings and has retained some of the…", "keyFeatures": [ "Open House this Wednesday (23rd Sept) - by appointment only", "First floor converted flat", "Shared Driveway" ], "size": null, "photoCount": 7, "photos": [ "https://lid.zoocdn.com/u/1024/768/2eb9716d8a8ae5dd402db1821071d6c8c138f038.jpg", "https://lid.zoocdn.com/u/1024/768/b267542c236d42e87746817723e7789197e862a0.jpg", "https://lid.zoocdn.com/u/1024/768/cb594b789d65c926e772cd59738b139e25843c8e.jpg" ], "photoCaptions": [ { "url": "https://lid.zoocdn.com/u/1024/768/2eb9716d8a8ae5dd402db1821071d6c8c138f038.jpg", "caption": "Front Elevation" }, { "url": "https://lid.zoocdn.com/u/1024/768/b267542c236d42e87746817723e7789197e862a0.jpg", "caption": "Kitchen" }, { "url": "https://lid.zoocdn.com/u/1024/768/cb594b789d65c926e772cd59738b139e25843c8e.jpg", "caption": "Bedroom" } ], "floorplan": [ "https://lid.zoocdn.com/u/1024/768/e93670f2e1952eaed74d6acf655acb216ca30a88.png" ], "epc": { "rating": null, "imageUrl": null }, "publishedAt": "2026-09-19T23:40:58.000Z", "listingUpdatedAt": "2026-09-19T23:40:58.000Z", "status_label": "Just added", "priceHistory": [], "agent": { "name": "Jordan Example", "branchId": 2449, "phone": "(555) 010-0001", "logoUrl": "https://st.zoocdn.com/zoopla_static_agent_logo_(743530).png", "url": "https://example.com/people/1", "isDeveloper": false }, "chainFree": false, "sharedOwnership": false, "materialInfo": [], "utilities": [], "nearbyStations": [ "Ilford", "Manor Park", "Gants Hill" ], "event": "property-detail", "collectedAt": "2026-09-20T19:48:53.643Z"}Fields
Every record starts with the same envelope: source, type, event, id, url, collectedAt. What the envelope means. The tables below list the fields after it, read from real Zoopla records. Where a field does not apply to an item it is null or an empty list, not left out. "Present on" names the billed events a field comes with when it is not on every record of that type.
property records
One UK property listing on Zoopla, from a search result or a property detail page. Billed as property or property-detail.
| Field | Type | What it holds | Present on |
|---|---|---|---|
portal | string | The portal the record was read from: zoopla. | All |
listingType | null | string | The listing's section as Zoopla names it, for example for-sale or to-rent, or null. | All |
category | string | Zoopla's listing category as Zoopla names it, or null; only on detail records. | Only property-detail |
status | null | string | The listing's status label as Zoopla shows it (for example Just added), or null; only on detail records. | Only property-detail |
price | integer | The price as a number; currency is given by currency, display format by priceText. | All |
priceText | string | The price exactly as displayed on the site. | All |
priceQualifier | null | string | A short qualifier shown with the price (for example Guide price), or null. | All |
pricePerSqFt | null | string | Price per square foot exactly as displayed on the site, or null; only on detail records. | Only property-detail |
currency | string | ISO 4217 currency code for price, defaulting to GBP when the source states none. | All |
isAuction | boolean | Whether the listing is an auction listing; only on detail records. | Only property-detail |
bedrooms | integer | null | Number of bedrooms, or null. | All |
bathrooms | integer | null | Number of bathrooms, or null. | All |
livingRooms | integer | null | Number of reception rooms, or null. | All |
propertyType | string | The property type, for example flat or detached. | All |
tenure | null | string | The tenure, for example Freehold or Leasehold, or null. | All |
address | object | The address, with keys displayAddress, outcode, incode, postalCode and country; detail records add street, region and uprn. | All |
coordinates | object | The location, with keys lat and lng, both null when neither is available. | All |
description | string | The listing's description text; only on detail records, null otherwise. | Only property-detail |
keyFeatures | array | List of bullet point feature strings; always empty on search records. | All |
size | null | object | The floor size, with keys value and unit (detail records add a label); null when not published. | All |
photoCount | integer | Number of photos for the listing, or null. | All |
photos | array | List of photo URLs for the listing; empty when none are available. | All |
photoCaptions | array | Each photo paired with its caption: a list of objects with keys url and caption; only on detail records. | Only property-detail |
floorplan | array | List of floorplan image URLs; only on detail records. | Only property-detail |
epc | object | Energy performance data: an object with keys rating and imageUrl; only on detail records. | Only property-detail |
publishedAt | null | string | ISO 8601 timestamp the listing was published, or null. | All |
listingUpdatedAt | null | string | ISO 8601 timestamp the listing was published or last updated, or null. | All |
status_label | null | string | Zoopla's raw status label text, duplicating status; only on detail records. | Only property-detail |
priceHistory | array | List of past price changes, each with keys date, price and event; only on detail records. | Only property-detail |
agent | object | The listing agent or branch; keys vary by event, always including name, branchId, phone and logoUrl. | All |
chainFree | boolean | Whether the property is chain free; only on detail records. | Only property-detail |
sharedOwnership | boolean | Zoopla's shared ownership details, kept as given, or null; only on detail records. | Only property-detail |
materialInfo | array | Council tax, service charge, ground rent and tenure facts: a list of objects with keys key, label and value; only on detail records. | Only property-detail |
utilities | array | Utilities, broadband and parking facts: a list of objects with keys key, label and value; only on detail records. | Only property-detail |
nearbyStations | array | List of nearby station name strings; only on detail records. | Only property-detail |
displayType | string | Zoopla's display type for the listing card, or null; from the search result. | All |
summary | string | A short summary text for the listing; from the search result. | All |
title | string | The listing's title text; from the search result. | All |
image | string | URL of one representative photo; from the search result. | All |
floorplanCount | integer | Number of floorplans for the listing; from the search result. | All |
publishedOnText | string | The listing's publish date exactly as displayed on the site, or null; from the search result. | All |
isPremium | boolean | Whether the listing is a premium listing; from the search result. | All |
isUnderOffer | boolean | Whether the listing is under offer; from the search result. | All |
priceDrop | null | object | Zoopla's raw price drop details for the listing, or null; from the search result. | All |
searchLocation | null | The search location text the run searched for that produced this record; null when not run from a location search. | All |
totalResultCount | integer | Total number of results for the search that produced this record, or null; from the search result. | All |
Zoopla data pricing
You pay once for each record you receive, at the price of the event it carries. A request that returns nothing costs nothing.
| Event | Per 1,000 records | Per record |
|---|---|---|
property | $1.40 | $0.00140 |
property-detail | $2.70 | $0.00270 |
Freshness and limits
- Records are collected when you send the request. Each one carries
collectedAt, the UTC time it was read. POST /records/zooplareturns up to 500 records in one response. Ask for more and it answers413; send the same body toPOST /jobs/zooplainstead.- A request without
maxItemsreturns up to 100 records. - Your key's rate limit and quotas apply to every source.