# Which districts of a city are the most expensive, the busiest or growing fastest?

> **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. Every property is one record with its full price and market history. [How the property graph is built](/docs/property-graph).

Casafari Area Insights compares every district of a city in one MCP call. `ma_get_heatmap` takes the city's `location_id` and returns one value per child location for the `data_point` you choose, such as `avg_price_psqm`, `available_on_market`, `new` or `price_down`. Then measure growth in the leading districts with `ma_get_time_series_operations` (`cagr`, `delta_pct`).

Products: [Area Insights](/docs/area-insights).

## Short answer

`ma_get_heatmap` takes a parent `location_id`, for example a city. It returns one row per child location, for example each district, with `location_id`, `location_name` and `value`.

The value is the `data_point` you choose:

- `avg_price`
- `avg_price_psqm`
- `available_on_market`
- `new`
- `sold_or_rented`
- `price_up`
- `price_down`

Sort the rows to see which districts are the most expensive, have the most supply or face the most price cuts. Then measure growth per district with `ma_get_time_series_operations`.

## Steps

### Resolve the city with ma_get_location_typeahead

1. Call `ma_get_location_typeahead` with the English name, for example `Lisbon`. Check `administrative_level` and `breadcrumbs` to make sure you have the city, not a district or region with the same name.

### Call ma_get_heatmap with type_group, business_type, location_id, data_point and date_range

2. Call `ma_get_heatmap` with a `request_data` object.
   - Required: `type_group` (`apartment` or `house`), `business_type` (`sale` or `rent`), `location_id` (the parent), `data_point` and `date_range` (`min` is required).
   - Optional filters: `price_range`, `price_per_sqm_range`, `bedrooms_range`, `bathrooms_range`, `total_area_range`, `construction_year_range`, `characteristics`, `conditions`, `private`, `bank`, `auction` and `exclude_outliers` (default `true`).

### Repeat with data_point available_on_market, new or price_down for other views

3. Keep every other field the same and change only `data_point`:
   - `available_on_market` for supply.
   - `new` for newly advertised properties.
   - `price_down` for price cuts.

### Rank growth per district with ma_get_time_series_operations (cagr, delta_pct) on the top districts

4. Take the child `location_id` values from the heatmap rows. Call `ma_get_time_series_operations` once per district with:
   - `custom_location_boundary.location_ids` set to that district.
   - `data_point` `avg_price_psqm`, plus a `date_interval`, a `date_range` and an `alias`.
   - `operations` `["cagr", "delta_pct"]`.

   Then sort the districts by `cagr`.

## Example: Lisbon districts by avg_price_psqm

Prompt to the assistant: *"Compare Lisbon's districts by average asking price per m² for apartments for sale. Then tell me which of the five most expensive grew fastest since 2022."*

The assistant calls `ma_get_location_typeahead` (`Lisbon`), then `ma_get_current_datetime`, then `ma_get_heatmap`:

```json
{
  "request_data": {
    "type_group": "apartment",
    "business_type": "sale",
    "location_id": LISBON_LOCATION_ID,
    "data_point": "avg_price_psqm",
    "date_range": {"min": "YYYY-MM-DD"}
  }
}
```

The response has this shape:

```json
{"result": [{"location_id": <child id>, "location_name": "<district>", "value": <number or null>}]}
```

The assistant sorts the rows by `value` and keeps the top five. For each one it calls `ma_get_time_series_operations` with `cagr` and `delta_pct` from `2022-01-01`, then reports the districts in order of growth. The figures come from the live calls; these docs publish none.

## How to read the result

### Only active properties are counted

The tool aggregates active properties only, in each child location. A heatmap is a snapshot of the market across space. For how a district changed over time, use `ma_get_time_series_data` or `ma_get_time_series_operations`.

### A null value means no matching data in that child location

`value` can be null. Treat a null as "no properties matched your filters there", not as zero. If no data matches in any child location, the tool raises a `ToolError`.

### Use breadcrumbs from the typeahead to pick the right parent level

The heatmap returns the children of the location you pass.

- Pass a city to compare its districts or neighbourhoods.
- To compare larger units, pass a higher level taken from the typeahead's `breadcrumbs`.

## Limits

Availability:

- `ma_get_heatmap` is available to Casafari clients with MCP access, using their Casafari account.
- Self-serve access for new users is coming soon.
- It exists over MCP only; there is no REST equivalent. See [MCP-only and REST-only](/docs/faq/mcp-only-and-rest-only).

Coverage:

- The tool description names no specific market.

Pricing and quotas:

- The sources give no figures for pricing or quotas. Ask [Casafari](https://www.casafari.com/).

### Children are resolved automatically; you cannot pass your own list

The tool finds the child locations of `location_id` itself. To compare an arbitrary set of areas, call `ma_get_time_series_data` or `ma_get_time_series_operations` once per area.

### Apartment or house type groups only

`type_group` accepts `apartment` or `house` only. Commercial property, plots and other types are not covered by this tool.

## Questions

### Can I get the heatmap as a map image?

No. `ma_get_heatmap` returns data, not an image: one row per child location with `location_id`, `location_name` and `value`. The tool description says to use these rows for map visualisation or spatial dashboards. You join the rows to district shapes from your own mapping source and colour them by `value`. The heatmap does not return district geometries or centre coordinates.

### Can I filter the heatmap to 2-bedroom apartments under a price?

Yes. Set `type_group` to `apartment` and `bedrooms_range` to `{"min": 2, "max": 2}`. Set `price_range` to `{"max": <your ceiling>}`. You can also add `price_per_sqm_range`, `total_area_range`, `construction_year_range`, `characteristics` or `conditions`. Narrow filters leave fewer properties per district, so expect more null values in small districts.

### Does the heatmap include rentals?

Yes. Set `business_type` to `rent` and the heatmap compares districts on the rental market, for example by average asking rent per m² with `data_point` `avg_price_psqm`. Each call covers either sale or rent. To compare a district's sale and rental markets, make one call for each and join the rows on `location_id`.

### What if the city has no child locations?

Then the heatmap has nothing to compare. If no matching data is found, the tool raises a `ToolError`. Pick a higher parent from the typeahead's `breadcrumbs` so that the city appears as one of the children. Or compare chosen areas one by one with `ma_get_time_series_data`, which accepts up to 10 location ids or a circle.

All use cases: [Use cases](/docs/use-cases#area-insights).
