Founder & Lead Engineer, RAITHub
A useful property pricing tool does not hand back one magic number. It produces a defensible range from comparable sales and shows its working. Build it as an explainable comparables method: pick similar recently-sold properties, adjust each for the differences, and present a range. The hard part is not the maths; it is the data you are allowed to use and the trust the output must earn.
This is general engineering guidance, not property valuation advice; a formal valuation needs a qualified valuer. If you would rather have the tool built and tested for you, see how RAITHub would build this below.
What kind of valuation tool can you realistically build?
There are two broad approaches. A full automated valuation model (AVM) trains on large volumes of sold-price data and is only as good as that data, which is usually licensed and, in many markets, not freely available. A comparable-sales tool works from a set of recently-sold properties you already have the right to use, applies transparent adjustments, and shows its reasoning. For most agencies and PropTech products, the comparable-sales tool is the honest and buildable choice: explainable, defensible to a client, and not dependent on a data feed you may not be licensed for.
Where does the sold-price data come from, honestly?
From data you are entitled to use: your own transaction history, an open government price register where one exists, or a licensed provider's feed. It does not come from scraping a portal or from an MLS you have no access to. Portal and MLS feeds are licensed, and RAITHub does not integrate an MLS it has no access to (the realities are set out in the MLS and IDX integration guide). Decide the data source first, because it caps what the tool can claim.
How does an explainable comparables method work?
Select, adjust, aggregate. First, select comparables: same area, similar type, similar size, sold recently. Then adjust each comparable's price for its differences from the subject property, floor area, bedrooms, condition, so you are comparing like with like. Finally, aggregate the adjusted prices into a range, not a single figure, and keep every adjustment visible.
| Step | What it does | Shown to the user |
|---|---|---|
| Select | Finds recent, nearby, similar sales | The comparables chosen, and why |
| Adjust | Corrects each comparable for its differences | Each adjustment, line by line |
| Aggregate | Combines into a range with a midpoint | Low, mid and high, with confidence |
| Confidence | Flags thin or stale data | A plain warning when comparables are weak |
What does the adjustment logic look like in code?
Keep adjustments as explicit, named rules with per-unit rates you can review and change, not hidden coefficients. Store money as integer minor units to avoid rounding drift.
// Adjust a comparable's sold price toward the subject property.
type Property = { areaSqm: number; beds: number; condition: number }
interface Rates {
perSqm: number // minor units per square metre of difference
perBed: number // minor units per extra/fewer bedroom
perCondition: number // minor units per condition point (1-5 scale)
}
function adjustComparable(comp: Property, compPrice: number, subject: Property, r: Rates) {
const adjustments = [
{ label: 'Floor area', delta: Math.round((subject.areaSqm - comp.areaSqm) * r.perSqm) },
{ label: 'Bedrooms', delta: (subject.beds - comp.beds) * r.perBed },
{ label: 'Condition', delta: (subject.condition - comp.condition) * r.perCondition },
]
const adjusted = adjustments.reduce((sum, a) => sum + a.delta, compPrice)
return { adjusted, adjustments } // return the working, not just the number
}
Returning the list of adjustments, not just the total, is what makes the tool trustworthy: an agent can defend the figure to a seller line by line. Hold the rates as data an admin can tune per market, rather than constants buried in code.
How do you keep the output honest?
Show a range, never one number. State the comparables used and when they sold. Warn when the data is thin (few comparables, all old, or far away), because a confident number from weak data is worse than an honest "not enough recent sales nearby". And label the output clearly as an estimate for guidance, not a formal valuation, which a qualified valuer provides. The no-superlatives rule applies to the product too: it is a pricing estimate, not "the most accurate" anything.
How do you test a pricing tool?
Pin the behaviour with golden cases and property-based checks. A golden case is a fixed subject property plus fixed comparables with a known, hand-checked expected range; it fails the build if the number drifts. Property-based checks assert invariants that must always hold: an identical comparable needs zero adjustment, a larger subject property should adjust upward, and the midpoint must sit inside the low-high range.
// tests/pricing/invariants.spec.ts
import { test, expect } from 'vitest'
import { adjustComparable } from '@/lib/pricing'
test('an identical comparable needs no adjustment', () => {
const p = { areaSqm: 80, beds: 2, condition: 3 }
const { adjusted } = adjustComparable(p, 500000_00, p, { perSqm: 1000_00, perBed: 10000_00, perCondition: 5000_00 })
expect(adjusted).toBe(500000_00)
})
Buy, build or hire?
| Option | What you get | Choose this when |
|---|---|---|
| A third-party AVM or data provider | An estimate from their model and data | You can license their feed and accept a number you can't fully explain |
| A spreadsheet of comparables | Manual, but transparent | Low volume and an agent does the adjustments by hand |
| A custom comparable-sales tool | Your data, explainable adjustments, a defensible range inside your product | Pricing is part of your workflow and the output must be trusted |
| A managed QA team on your build | Golden-case and invariant suites gated in CI | You have the tool but its numbers aren't pinned against drift |
How long does it take to build yourself?
A first version with the select-adjust-aggregate pipeline, explainable output and golden-case tests is roughly a week once the data source is settled; tuning the rates per market and building the admin screens add more. The main risk of doing it yourself is overclaiming: shipping a single confident number from thin data invites a dispute, and labelling it a "valuation" invites a bigger one.
Why RAITHub for this
RAITHub built BlockEstate, a multi-tenant listing and inquiry platform, in a 6-week MVP, and handles money correctly in integer minor units across TheSkinProof (the founder's own venture, 217 endpoints, 750+ tests). The data model and build approach sit inside PropTech software development and the SaaS development service. See the real-estate industry page.
When you don't need us
- A licensed AVM feed fits and you trust it. Buy the feed and surface it.
- Volume is low. A well-made spreadsheet of comparables may be enough.
- You need a formal valuation. That is a qualified valuer's job, not a software tool's.
How RAITHub would build this
- Scope: a comparables data model from a data source you are entitled to use, an explainable select-adjust-aggregate method, a range with confidence, admin-tunable rates, and clear "estimate, not valuation" labelling.
- Timeline: a focused first version in the 4 to 6-week fixed-scope range; data-integration and tuning work sits in the 6 to 12-week range, in phases.
- What you receive: golden-case and invariant suites gated in CI, runbooks, the product on accounts you own, IP assigned to you and an NDA as standard.
- Ways to buy it: a fixed-scope build, a dedicated monthly team, or a QA plan if you only need the pricing test suite.
- Next step: a free 15-minute technical audit, then a fixed written quote.
See the QA as a Service page, or book the free 15-minute audit. This is general guidance, not valuation advice; a formal valuation needs a qualified valuer.
Documentation checked on 10 October 2026.
Frequently asked questions
How does a property valuation tool work?
A comparable-sales tool selects recently-sold properties similar to the subject, adjusts each for differences such as floor area, bedrooms and condition, then aggregates the adjusted prices into a range. Showing each adjustment makes the figure explainable and defensible to a client.
Can you build an automated valuation model (AVM)?
A full AVM needs large volumes of sold-price data, which is usually licensed and not freely available in many markets. A comparable-sales tool built on data you are entitled to use is more honest and more buildable for most agencies and PropTech products.
Where does the sold-price data come from?
From data you have the right to use: your own transaction history, an open government price register where one exists, or a licensed provider's feed. It does not come from scraping a portal or from an MLS you have no access to, since those feeds are licensed.
Should the tool return one number or a range?
A range, with the midpoint and a confidence flag. A single confident figure from thin or stale data invites a dispute. Warn plainly when there are few recent nearby comparables, because an honest "not enough data" beats a precise-looking wrong answer.
Is this the same as a formal property valuation?
No. A pricing tool produces an estimate for guidance; a formal valuation is produced by a qualified valuer and carries professional responsibility. Label the tool's output as an estimate, and confirm any formal valuation requirement with your adviser.
Related posts
Ready to discuss your project?
Book a free 15-minute technical audit with our engineering team.