Screen investments · Use case
How do I find properties priced below the area's market value?
To find properties priced below an area's market value, benchmark the area's asking price per m² with Area Insights (ma_get_time_series_data, ma_get_price_distribution). Then search Property Sourcing with POST /api/v2/properties/search and price_per_sqm_to under that benchmark. Confirm each candidate with comps_get-comparables by comparing its asking price with estimated_prices.fair_market_price. The biggest spread marks the strongest candidate.
Products: Area Insights, References, Property Sourcing, Comparables & Valuation
Short answer
Work as a three-step funnel:
- Benchmark. Get the area's average asking price per m² from Area Insights.
- Search. Look in the property graph for properties asking less than that per m², with the type, bedrooms and condition you want.
- Confirm. Run Comparables & Valuation on each candidate. Compare its asking price with
estimated_prices.fair_market_pricefromcomps_get-comparables, and check whether it is flaggedis_outlier.
The graph keeps one record per property. A property advertised by several agencies and portals counts once in the benchmark and appears once in the search. See The property graph.
Steps
Benchmark: ma_get_time_series_data with avg_price_psqm (latest period) and ma_get_price_distribution
Resolve the place name with
ma_get_location_typeahead. Thelocation_namemust be in English, for exampleLisbon. When several places share a name, pick the rightlocation_idfrombreadcrumbsandadministrative_level.Call
ma_get_time_series_datawith theserequest_datafields:type_group:apartmentorhousebusiness_type:salealias: a name for the segmentcustom_location_boundary:location_ids(1 to 10 ids) or acircle(distancein meters, 50 to 50000)data_point:avg_price_psqmdate_interval: for examplemonthdate_range.min
Add
bedrooms_rangeandconditionsto match the segment you will search. Thevalueof the latestdate_startis your benchmark.Call
ma_get_price_distributionwith the same boundary and filters. Each bucket returnslower_bound,upper_bound,properties_countandis_mean. Together they show how total prices spread and which bucket holds the mean, so you can tell whether the cheap end of the area is thin or crowded.
Search: POST /api/v2/properties/search with location_ids and price_per_sqm_to below the benchmark, plus type, bedrooms and condition
Call
POST /api/v2/properties/searchwith:search_operations: salelocation_ids: documented as the ids returned byPOST /api/v1/references/locations, so resolve them thereprice_per_sqm_to: below the benchmark, for example benchmark × 0.85 for 15% undertypesbedrooms_fromandbedrooms_toconditions
Leave
ruinout ofconditionsso run-down properties do not look like bargains. Other useful filters aretotal_area_from/total_area_to,days_on_market_from/days_on_market_toandprivate. The response schema is on the operation page.
Confirm: comps_get-comparables on each candidate with exclude_outliers false; compare asking price with fair_market_price and look at is_outlier
- For each candidate, call
comps_get-comparableswith:location_boundary.circle.target_point: the candidate'scoordinatesoraddressdistance: in kilometers. The tool suggests 0.5 to 1 km in urban areas and 2 to 5 km in rural ones.operation:salecomparables_types: types from one type group onlycomparables_count: 1 to 50- the candidate's
bedrooms,condition,floorsandtotal_area exclude_outliers:false
- Read
estimated_prices.fair_market_price,fair_market_price_per_sqm,fast_sell_priceandout_of_market_price. Then find the candidate inresultsbyproperty_idand read itsis_outlierandsimilarity_score.
Sort by the spread
- For each candidate, compute spread = (
fair_market_price− asking price) /fair_market_price, and sort from largest to smallest.- Take the asking price from the search response, or from
sale_priceif the candidate appears in the comparablesresults. - Keep
casafari_link(the Comparative Market Analysis page) andvaluation_id(persistent, expires in a year) for your shortlist.
- Take the asking price from the search response, or from
Example: apartments in Lisbon under the area price per m²
A person asks their assistant: "Find 2 to 3-bedroom apartments in Lisbon asking at least 15% under the area price per m², and leave out ruins."
The assistant calls list_servers, then ma_get_location_typeahead with Lisbon. It then calls ma_get_time_series_data with type_group apartment, business_type sale, data_point avg_price_psqm, date_interval month and bedrooms_range 2 to 3. Call the latest value B. The threshold is T = 0.85 × B. ma_get_price_distribution on the same boundary shows how many properties sit in each price bucket.
The search step runs over REST, from your own integration with a Casafari client account:
{
"search_operations": ["sale"],
"location_ids": ["<LOCATION_ID>"],
"types": ["apartment"],
"price_per_sqm_to": "<T>",
"bedrooms_from": 2,
"bedrooms_to": 3,
"conditions": ["used", "very-good", "new"]
}Replace the placeholders with numbers, and check value formats on the operation page. For each candidate, the assistant then calls comps_get-comparables:
{
"comparables_count": 20,
"location_boundary": {"circle": {"target_point": {"address": "Avenida da Liberdade, Lisbon"}, "distance": 1}},
"operation": "sale",
"comparables_types": ["apartment"],
"bedrooms": 2,
"exclude_outliers": false
}If a candidate asks P and fair_market_price is F, its spread is (F − P) / F. The assistant ranks candidates by that spread and reports casafari_link for each. All figures come from the responses; this page gives no market numbers.
How to read the result
Outliers are excluded by default: turn exclude_outliers off on purpose
exclude_outliers defaults to true in comps_get-comparables and in the Area Insights tools. It removes properties that are significantly underpriced or overpriced compared to similar ones, which are exactly the properties you are hunting.
- Benchmark: keep it on, so extreme values do not pull the average.
- Comparables call: turn it off, so the candidate stays visible.
A candidate with is_outlier true is priced far from similar properties. That makes it either a real bargain or a case with a reason behind the price, so verify it before acting.
A low price may reflect condition, floor or ruin status: read the fields
Before calling a property underpriced, read these fields:
condition(ruin,used,very-good,new,other)floor_numberandfeatures.floor(no_floor,ground,middle,top)features.orientationenergy_ratingtotal_areaagainstliving_areafeatures.characteristics: values such asrented_out,life_annuityorno_elevatorcan explain a lower asking price that is not a discount to market value
total_sale_price_change and last_sale_price_reduction show whether the price got there through cuts.
Limits
The search step needs a Casafari client account
What each step needs:
- MCP access: the Area Insights tools and
comps_get-comparablesare available to Casafari clients with MCP access, using their Casafari account. - Casafari client accounts:
POST /api/v2/properties/searchis a REST operation for Casafari client accounts. It is not offered over Casafari MCP (details). - Self-serve access for new users is coming soon, for these tools and for the search.
Without it, start from a property you already know (an address, coordinates or, in Spain only, a cadastral reference) and use comparables (example).
Coverage limits:
- The API's permissions list 16 markets.
- The cadastral-reference input of
comps_get-comparablesis Spain only. ma_get_location_typeaheadexpects English place names.- The Area Insights tools take
type_groupapartmentorhouseonly. - Other tools name no market.
The sources give no figures for pricing, quotas, rate limits or data refresh frequency; ask Casafari.
The spread is computed by you from the returned fields
No tool returns a discount or spread field: you compute it from the asking price and estimated_prices. The estimates are calculated from the comparables found, so they depend on the boundary and filters you set.
The data cannot tell you a property's interior state beyond condition, its legal situation, or why the seller asks what they ask. Inspect before you buy.
Questions
Can an AI assistant run this whole funnel for me?
An AI assistant connected to Casafari MCP can run the benchmark and the confirmation steps itself, with ma_get_location_typeahead, ma_get_time_series_data, ma_get_price_distribution and comps_get-comparables. The search step is POST /api/v2/properties/search, which is REST only and not offered over Casafari MCP. Run it from your own integration with a Casafari client account, or give the assistant candidate addresses to check.
How do I add price cuts as a second signal?
Each comps_get-comparables result carries price-cut fields: total_sale_price_change, last_sale_price_reduction and sale_price_last_change. At area level, ma_get_time_series_data with data_point price_down counts price decreases per period. Casafari client accounts can read a property's sale_price_history with GET /api/v1/properties/search/{property_id}. New Market Leads alert feeds follow price cuts as they happen.
Can I do this for houses and plots?
You can do this for houses throughout, because the Area Insights tools accept type_group house and comps_get-comparables takes house types such as villa or townhouse. Plots are only partly supported. The Area Insights MCP tools take apartment or house only, so there is no plot benchmark there. comps_get-comparables accepts urban_plot and rural_plot, but then requires plot_area unless you give a cadastral reference.
Does fair_market_price account for condition and floor?
fair_market_price is calculated from the comparables found, so it reflects condition and floor as far as your request filters the comparable set by them. Pass condition, floors or floor_number, and characteristics in the comps_get-comparables call to get comparables that match. The docs do not describe how the estimate weights each attribute, so read similarity_score on each result.