Platform
Get started

Casafari is the AI agent-native real estate data intelligence platform. The most complete property index in Europe: a deduplicated, cleaned property graph of residential and commercial property, for sale and for rent, in 16 countries.The most complete property index in Europe: a deduplicated, cleaned property graph.

How the graph is built

Understand an area · Use case

What does a 2-bedroom apartment cost in this area, and how are prices spread?

Casafari Area Insights answers both questions over MCP. ma_get_bedrooms_distribution returns properties_count, average_price and average_price_per_sqm for each bedroom count in an area, so you read the 2-bedroom row directly. ma_get_price_distribution returns the number of properties in each price interval, with is_mean marking the band that holds the mean price.

Products: Area Insights

Short answer

Two Area Insights tools answer this question.

ma_get_bedrooms_distribution returns one row per bedroom count, with:

  • bedrooms (a label).
  • properties_count.
  • average_price.
  • average_price_per_sqm.

ma_get_price_distribution returns one row per price interval, with:

  • lower_bound and upper_bound.
  • properties_count.
  • is_mean, which is true for the band that holds the mean price.

Together they give the going price for each bedroom count and show where supply sits across price bands.

Steps

Resolve the area

  1. Call ma_get_location_typeahead with an English place name, for example Malaga, and keep the location_id. Use the breadcrumbs to make sure it is the city you mean.

Call ma_get_bedrooms_distribution with type_group, business_type, bedrooms_range (0 to 10)

  1. Call ma_get_bedrooms_distribution with a request_data object.
    • Required: type_group (apartment or house), business_type (sale or rent) and custom_location_boundary.
    • Optional: bedrooms_range (min and max from 0 to 10), plus price_range, total_area_range, conditions and exclude_outliers (default true).

Call ma_get_price_distribution with the same boundary and an optional price_range

  1. Call ma_get_price_distribution with the same type_group, business_type and custom_location_boundary. Add a price_range to focus on one window, for example 200,000 to 300,000.

Over REST, POST /market-analytics-api/distributions/properties for the properties distribution

  1. Over REST, send POST /market-analytics-api/distributions/properties. Its body takes:

    • types, business_type and custom_location_boundary.
    • Range filters (price_range, price_per_sqm_range, rooms_range, bedrooms_range, bathrooms_range, total_area_range, plot_area_range, construction_year_range).
    • characteristics, conditions, private, bank, auction and exclude_outliers.

    Its response fields are documented on the operation page.

Example: apartments for sale in Málaga

Prompt to the assistant: "What does a 2-bedroom apartment for sale in Málaga cost, and how many apartments are priced between 200,000 and 300,000?"

The assistant calls ma_get_location_typeahead (Malaga), then ma_get_bedrooms_distribution:

json
{
  "request_data": {
    "type_group": "apartment",
    "business_type": "sale",
    "custom_location_boundary": {"location_ids": [MALAGA_LOCATION_ID]},
    "bedrooms_range": {"min": 1, "max": 4}
  }
}

Then it calls ma_get_price_distribution:

json
{
  "request_data": {
    "type_group": "apartment",
    "business_type": "sale",
    "custom_location_boundary": {"location_ids": [MALAGA_LOCATION_ID]},
    "price_range": {"min": 200000, "max": 300000}
  }
}

For the cost question, it reads the row where bedrooms is 2: average_price and average_price_per_sqm, with properties_count as the sample size. For the count question, it sums properties_count across the returned bands and notes which band has is_mean set. The figures come from the live calls; these docs publish none.

How to read the result

Bedroom rows for segmentation and unit mix

Use the bedroom rows in two ways:

  • Pricing: compare a property's asking price per m² with average_price_per_sqm for its bedroom count.
  • Supply mix: properties_count by bedroom count shows the mix of stock on offer. Developers can compare that mix with the units they plan.

Price bands: where supply concentrates and where the mean sits

The bands with the highest properties_count are where competition for buyers is strongest. The band with is_mean true holds the mean price. A property priced far above it competes with less, and usually different, stock. An upper_bound of null marks the open top band.

Limits

Availability:

  • Both MCP tools are available to Casafari clients with MCP access, using their Casafari account.
  • Self-serve access for new users is coming soon.
  • POST /market-analytics-api/distributions/properties is REST only, for Casafari client accounts.

Coverage:

  • The tool descriptions name no specific market.
  • Only the apartment and house type groups are accepted.

Pricing and quotas:

  • The sources give no figures for pricing or quotas. Ask Casafari.

bedrooms_range in the bedrooms distribution is capped at 10

In ma_get_bedrooms_distribution, bedrooms_range.min and bedrooms_range.max accept 0 to 10. Other Area Insights tools accept higher values.

Boundaries are location ids (up to 10) or a circle

custom_location_boundary takes either location_ids (1 to 10) or a circle. A circle has a target_point and a distance of 50 to 50,000 metres. Polygons are not accepted by these MCP tools. See location ids.

Questions

Can I get the distribution for rentals?

Yes. Set business_type to rent in ma_get_bedrooms_distribution or ma_get_price_distribution. The bedroom rows then show average_price and average_price_per_sqm as asking rents, and the price bands group properties by rent level. Each request covers either sale or rent, so compare the two markets with two requests that use identical boundaries and filters.

Can I limit to new or very-good condition properties?

Yes. Both tools accept conditions, a list with at least one value from used, ruin, very-good, new and other, as returned by GET /api/v1/references/conditions. For example, ["new", "very-good"] keeps only properties in those conditions. Condition is a property attribute; it is not a new-development flag.

Can I use a polygon as the boundary?

Not with the Area Insights MCP tools. Their custom_location_boundary takes up to 10 location ids or a circle of 50 to 50,000 metres. The REST distribution operations also take a custom_location_boundary, and its accepted shapes are on each operation page. If you need comparables inside an exact polygon, comps_get-comparables accepts a closed polygon of at least 4 points.

How do I compare two cities?

Send one request per city, with identical type_group, business_type and filters, and change only custom_location_boundary. Putting both cities' ids in one location_ids list would return a single combined distribution. Then compare the bedroom rows, for example average_price_per_sqm for 2 bedrooms, and the position of the is_mean band in each city.

All use cases

Tip: add .md to any URL to read it as Markdown.