# UK Property Valuation API - AVM and Comparables (`nabeelbaghoor/uk-property-valuation-api`) Actor

UK residential valuation and comparable evidence: automated sale and rental valuations with confidence bands, comparable properties by postcode, radius or polygon filtered on beds, floor area, tenure, value and rent, with current and last transacted prices, EPC ratings and listings.

- **URL**: https://apify.com/nabeelbaghoor/uk-property-valuation-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Real estate, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $14.00 / 1,000 comparable property 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 Valuation API - AVM and Comparables

Value a UK home, and pull the comparable evidence that supports the number.

### What it collects

- **Automated valuations** for an address: estimated sale value with lower and upper bounds and a confidence band, estimated monthly rent with its own bounds and its own confidence band, the effective date of each, and any flags the provider raises on the valuation.
- **Comparable properties** around a postcode, a radius from a point, or inside a polygon, filtered on bedrooms, floor area, year built, property type, tenure, current value, last sale value, last sale date and current rent.
- **Evidence per comparable**: UPRN, address and coordinates, property type and sub type, bedrooms, bathrooms and receptions, new build flag, year built, tenure, floor area in square feet with whether it came from an EPC or a survey, current value and value per square foot, last recorded sale with its type, date and source, current and last rent, and EPC rating and efficiency.
- **Value history** on a single property lookup: every recorded sale and rent value with its type, date and source.
- **Listings**: the latest marketing record the provider holds against a UPRN.
- **Broker records**: valuations and orders already on your account, with their status.

### FAQ

#### How do I get an automated valuation for a UK property?

Run the automated valuation mode with the address and your account ID. Write each line as the address ending in the postcode, or as "address|postcode". The row comes back with an estimated sale value, its lower and upper bounds, a confidence band, an estimated monthly rent with its own band, and any flags on the valuation.

#### What is a confidence band and why does it matter?

It is the provider's own grading of how reliable a given automated valuation is, and it is what separates a valuation a lender will accept from one it will not. Sale and rental valuations are graded independently, so each keeps its own band rather than sharing one.

#### How do I find comparable sales near a property?

Comparables search takes a postcode, a centre point with a radius in metres, or a GeoJSON polygon, and returns every property the provider holds in that area. Criteria are additive, so bedrooms, floor area, year built, type, tenure, value and rent filters all have to match at once. Set the area type to say which form your lines are in.

#### What units are the measurements in?

Imperial. The provider publishes floor areas in square feet and per unit values per square foot, and nothing is converted here, because a converted number with no label is worse than an unconverted one with a label. Every row carries its floor area unit and its currency explicitly.

#### What is the difference between current value and last value?

A current value is what the provider estimates the property is worth today. A last value is what actually happened, and it carries its own type saying whether that was an asking price, a completed sale or a valuation. They keep separate columns, because merging them would turn an aspiration into a transaction. Where the provider distinguishes a transaction outright, the last transaction value, date and source travel too.

#### Which credential do I need?

That depends on the product, and this API has three. The comparables and listings products use an OAuth2 client ID and secret exchanged for a bearer token. The broker product uses a gateway subscription key. The automated valuation product uses the subscription key plus a separate valuation API key exchanged for a short lived token. Most accounts hold one product, so the actor checks only the credential the chosen mode actually needs, and names the one that is missing.

#### Can this actor place a valuation order or spend money?

No. The broker product can place orders, which costs money and instructs work, so the route that does it is not wired up at all rather than merely unused. Every route this actor calls reads. A scheduled run cannot spend anything or start anything.

#### Can I check the service before using a credential?

Yes. The service status mode calls a route that needs no credential at all, so you can confirm the valuation service is reachable before committing a run to it.

#### What does it cost?

Pay per result. An automated valuation costs the most, a comparable slightly less, a listing and a broker record less again, and the credential-free status check is priced as low as the platform allows. Platform usage is included. Subjects the provider has no record for are never charged.

### Example output

```json
{
  "recordType": "comparable",
  "requested": "SW1A 0AA",
  "found": true,
  "uprn": "1024047438",
  "propertyType": "Terraced",
  "propertySubType": "Mid Terrace House",
  "bedrooms": 3,
  "bathrooms": 2,
  "receptions": 1,
  "yearBuilt": 1930,
  "tenure": "Freehold",
  "floorAreaSqFt": 120,
  "floorAreaSource": "EPC",
  "floorAreaUnit": "sqft",
  "saleCurrentValue": 512000,
  "saleLastValue": 465000,
  "saleLastValueType": "Sale",
  "saleLastValueDate": "2022-06-14",
  "rentCurrentValue": 2150,
  "epcRating": "C",
  "epcEfficiency": 68,
  "currency": "GBP"
}
```

### Keyword map

UK property valuation API, automated valuation model API, AVM API UK, property comparables API, sold price comparables, rental comparables API, UPRN property lookup, EPC rating data API, house price estimate API, mortgage valuation data, surveyor comparable evidence, postcode property search API, property floor area square feet, confidence band valuation, UK residential market data.

### Notes

Bring your own key. Read only by construction: no order-placing route is wired up. Token exchange, expiry and re-exchange are handled for you, including the provider's warning that the token response is cached and its stated lifetime is not reliable, so expiry is read from the token itself. Rate limiting and retries are handled too, and missing or refused credentials end the run cleanly with an explanation rather than failing it.

# Actor input Schema

## `mode` (type: `string`):

Comparables search finds properties around a postcode, a point or inside a polygon and filters them. Comparable lookup reads one property by UPRN with its value history. Listing lookup reads the latest listing on a UPRN. Automated valuation values a property from its address. The broker modes read valuations and orders already on your account. Service status checks the valuation service is up without using a credential.

## `subjects` (type: `array`):

One subject per line. A postcode, a "latitude,longitude" pair or a GeoJSON polygon for comparables search, depending on the area type. A UPRN for the lookup modes. An address, optionally written as "address|postcode", for automated valuation. A valuation or order ID for the broker modes.

## `areaType` (type: `string`):

How to read each line in comparables search. The provider accepts exactly one area form per search, so this decides which one the lines are interpreted as.

## `radiusMetres` (type: `integer`):

How far around each centre point to search, in metres, when the area type is radius.

## `propertyType` (type: `array`):

Only return comparables of these types. The provider's values are case sensitive, and the actor corrects the case for you so a lowercase entry still filters instead of silently doing nothing.

## `tenure` (type: `array`):

Only return comparables held on these tenures.

## `minBedrooms` (type: `integer`):

Only return comparables with at least this many bedrooms.

## `maxBedrooms` (type: `integer`):

Only return comparables with no more than this many bedrooms.

## `minFloorAreaSqFt` (type: `integer`):

Only return comparables at least this large. This API is imperial throughout, so the unit is square feet rather than square metres.

## `maxFloorAreaSqFt` (type: `integer`):

Only return comparables no larger than this, in square feet.

## `minYearBuilt` (type: `integer`):

Only return comparables built in or after this year. The provider may estimate the year for older stock.

## `maxYearBuilt` (type: `integer`):

Only return comparables built in or before this year.

## `minCurrentValue` (type: `integer`):

Only return comparables the provider currently values at or above this, in pounds.

## `maxCurrentValue` (type: `integer`):

Only return comparables the provider currently values at or below this, in pounds.

## `minLastValue` (type: `integer`):

Only return comparables whose last recorded sale value is at or above this. This is what happened rather than what the provider estimates today.

## `maxLastValue` (type: `integer`):

Only return comparables whose last recorded sale value is at or below this.

## `lastValueDateFrom` (type: `string`):

Only return comparables whose last recorded sale value is dated on or after this day.

## `lastValueDateTo` (type: `string`):

Only return comparables whose last recorded sale value is dated on or before this day.

## `lastValueType` (type: `array`):

Which kinds of last value to accept. An asking price is what somebody wanted, a sale is what was paid, and a valuation is the provider's own estimate, so these are three different pieces of evidence.

## `minCurrentRent` (type: `integer`):

Only return comparables the provider currently values at or above this monthly rent.

## `maxCurrentRent` (type: `integer`):

Only return comparables the provider currently values at or below this monthly rent.

## `includePriceHistory` (type: `boolean`):

Adds the full sale and rent value history to each comparable lookup row, each entry with its value, type, date and source. Off by default because a history inside a spreadsheet cell is unreadable, and the summary figures are on every row regardless.

## `accountId` (type: `string`):

Your provider account ID, which the automated valuation product addresses in the request path. Not a credential: it says which account to value against, not who you are.

## `postcode` (type: `string`):

Postcode to use for every address in automated valuation, when the address lines do not carry one.

## `valuationPropertyType` (type: `string`):

The property type to send with every automated valuation, in the provider's own wording, for example "end terrace house". Leave empty to let the provider infer it.

## `valuationBedrooms` (type: `integer`):

Bedroom count to send with every automated valuation. Leave empty to let the provider infer it.

## `valuationReceptions` (type: `integer`):

Reception room count to send with every automated valuation. Leave empty to let the provider infer it.

## `valuationReference` (type: `string`):

Your own reference, echoed back on every valuation row so a batch can be reconciled against your records.

## `maxResults` (type: `integer`):

Stop after this many rows. Counts every row: comparables, listings, valuations and broker records alike.

## `requestsPerMinute` (type: `integer`):

How fast to call the provider. The default of 120 is two a second. Raise it if your contract allows more.

## `clientId` (type: `string`):

Your own OAuth2 client ID, for the comparables and listings products. Stored encrypted and never written into the dataset. Can also be supplied as the DATA\_API\_CLIENT\_ID environment secret.

## `clientSecret` (type: `string`):

The client secret issued with the client ID. Both are needed: the pair is exchanged for a bearer token that lasts an hour. Stored encrypted and never written into the dataset. Can also be supplied as the DATA\_API\_CLIENT\_SECRET environment secret.

## `apiKey` (type: `string`):

Your own gateway subscription key, for the valuation and broker products. A different credential from the OAuth pair above, and most accounts hold one or the other rather than both. Stored encrypted and never written into the dataset. Can also be supplied as the DATA\_API\_KEY environment secret.

## `valuationApiKey` (type: `string`):

Your own valuation API key, which the automated valuation product exchanges for a token that lasts five minutes. Needed alongside the subscription key for that mode only. Stored encrypted and never written into the dataset. Can also be supplied as the DATA\_API\_VALUATION\_KEY environment secret.

## `dataServicesUrl` (type: `string`):

Overrides the host the comparables and listings products are called on. Leave empty unless the provider has given you a different one.

## `valuationUrl` (type: `string`):

Overrides the host the valuation and broker products are called on. Leave empty unless the provider has given you a different one.

## Actor input object example

```json
{
  "mode": "comparablesSearch",
  "areaType": "postcode",
  "radiusMetres": 500,
  "includePriceHistory": false,
  "maxResults": 100,
  "requestsPerMinute": 120
}
```

# Actor output Schema

## `records` (type: `string`):

One row per record, alongside the postcode, point, polygon, UPRN, address or identifier that produced it.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/uk-property-valuation-api").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/uk-property-valuation-api").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 '{}' |
apify call nabeelbaghoor/uk-property-valuation-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/uk-property-valuation-api"
        }
    }
}
```

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/7ffYVGjGqsHCsgbYu/builds/6RTzAvZehWm3JIVNL/openapi.json
