Returns property pins and clusters for interactive maps.
Also generates heatmap data as a grid of cells whose intensity reflects property concentration. Filtering supports list price, sale price, for sale status, bedrooms, and more.
Supports standard filtering and sorting.
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | UUID v4 | Your API key for authorization |
| cluster | No | Boolean (default: false) | Manual control of whether the data returned should be in pins or clusters. |
| cluster_over | No | Integer | Automatically return clusters instead of pins when there are more results than this. |
| heatmap | No | Boolean (default: false) | Return heatmap data instead of pins. |
| heatmap_cell_limit | No | Integer | The max number of heatmap cells returned (default: 1000, max: 10000) |
| heatmap_aggregation_field | No | String | Field to use for heatmap intensity calculation. When not provided, density of properties is used. |
| heatmap_aggregation_type | No | String (default: 'mean') | aggregation method for heatmap values. Possible values: 'mean', 'median', 'sum' |
| heatmap_aggregation_invert_intensity | No | Boolean (default: false) | When true, inverts the intensity values (1.0 - intensity) to make lower values appear as higher intensity |
| abort_over | No | Integer | Abort request if number of results exceeds this value (cost control). |
| polygon | If not using bbox | Polygon filter string | Get results inside a polygon. |
| bbox_ne_lat | If not using polygon | Float | Northeast latitude for bounding box. |
| bbox_ne_lng | If not using polygon | Float | Northeast longitude for bounding box. |
| bbox_sw_lat | If not using polygon | Float | Southwest latitude for bounding box. |
| bbox_sw_lng | If not using polygon | Float | Southwest longitude for bounding box. |
| select | No | String - see selecting | The fields to return for each pin. Defaults to latitude, longitude, and property_id |
| results_per_page | No | Integer | Number of results per page. Maximum 1000. Ignored when clusters or a heatmap are returned. |
| page | No | Integer | The page number to retrieve results from, starting at 1 |
Heatmaps can visualize property density or numeric attributes.
Set heatmap=true without heatmap_aggregation_field to get a density heatmap where each cell's intensity is its property concentration.
Pair heatmap=true with heatmap_aggregation_field to map numeric values like price, square footage, or bedrooms.
Choose how cell values aggregate:
By default higher values mean higher intensity. Set heatmap_aggregation_invert_intensity=true to flip this - useful for affordability views where low values are the target.
Type declarations are available at the bottom of this page.
| Name | Type | Description |
|---|---|---|
| aborted | Boolean | Indicates if the request was aborted due to exceeding the abort_over limit |
| cache_hit | Boolean | Indicates if the data was retrieved from the cache |
| cost_cents | Integer | Cost of the API call in cents |
| data | Object | Contains the map data in 'clusters', 'properties', or 'heatmap' arrays depending on the request type |
| error | String | Details about the error. Empty if no error |
| is_properties | Boolean | Indicates if the returned data contains individual properties |
| is_clusters | Boolean | Indicates if the returned data contains clustered properties |
| is_heatmap | Boolean | Indicates if the returned data contains heatmap cells |
| is_heatmap_aggregation | Boolean (nullable) | When present, indicates if the heatmap uses a field for aggregation (true) or just property density (false) |
| is_heatmap_aggregation_invert_intensity | Boolean (nullable) | When present, indicates if heatmap intensity values are inverted (1.0 - value) |
| heatmap_aggregation_type | String (nullable) | When present, indicates the type of aggregation used: 'mean', 'median', or 'sum' |
| heatmap_aggregation_max_value | Float (nullable) | When present, the maximum value found in the aggregated field (before normalization) |
| heatmap_aggregation_min_value | Float (nullable) | When present, the minimum value found in the aggregated field (before normalization) |
| heatmap_aggregation_field | String (nullable) | When present, the field name used for heatmap aggregation |
| pagination | Object | Pagination information |
| price_quote | Boolean | Indicates if this is a price quote request |
| result_total | Integer | Total number of results |
| time_ms | Integer | Time taken for the request to complete in milliseconds |
The data field varies by request type:
| Name | Type | Description |
|---|---|---|
| properties | Array<Property> | Array of individual property objects when is_properties is true |
| clusters | Array<Cluster> | Array of cluster objects when is_clusters is true |
| heatmap | Array<HeatPoint> | Array of heatmap points when is_heatmap is true |
Each property contains fields chosen via select. Over 400 fields available.
See the Fields documentation for the full list.
Grouped properties for map display:
| Name | Type | Description |
|---|---|---|
| latitude | Float | Center latitude coordinate of the cluster |
| longitude | Float | Center longitude coordinate of the cluster |
| number_of_properties | Integer | Number of properties grouped in this cluster |
Cells in a heatmap:
| Name | Type | Description |
|---|---|---|
| latitude | Float | Center latitude coordinate of the heatmap cell |
| longitude | Float | Center longitude coordinate of the heatmap cell |
| intensity | Float | Normalized intensity value (0.0 to 1.0) for heatmap visualization |
| number_of_properties | Integer | Number of properties in this heatmap cell |
| aggregation_value | Float (nullable) | Raw aggregated value before normalization (when using field-based heatmaps) |
Pagination info:
| Name | Type | Description |
|---|---|---|
| current_page | Integer | Current page number (1-based) |
| results_per_page | Integer | Number of results per page. Maximum 1000. |
| total_pages | Integer | Total number of pages available |
| total_results | Integer | Total number of results across all pages |
Select the programming language you want to display the code examples in.
curl -X GET "https://api.houski.ca/map?abort_over=500000&api_key=YOUR_API_KEY&bbox_ne_lat=51.17345&bbox_ne_lng=-113.96269&bbox_sw_lat=50.87234&bbox_sw_lng=-114.22313&bedroom_gte=4&cluster_over=1000"
const houski_map_data_bounding_box = async (): Promise<MapResponse> => {
// You must copy the MapResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/map');
url.searchParams.set('abort_over', '500000');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('bbox_ne_lat', '51.17345');
url.searchParams.set('bbox_ne_lng', '-113.96269');
url.searchParams.set('bbox_sw_lat', '50.87234');
url.searchParams.set('bbox_sw_lng', '-114.22313');
url.searchParams.set('bedroom_gte', '4');
url.searchParams.set('cluster_over', '1000');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: MapResponse = await houski_map_data_bounding_box();
// Log the response
console.log(data);
})();
{
"aborted": false,
"cache_hit": true,
"cost_cents": 0.0853400006890297,
"data": {
"clusters": [
{
"latitude": 51.05131912231445,
"longitude": -113.99966430664062,
"number_of_properties": 303
},
{
"latitude": 50.911903381347656,
"longitude": -114.10991668701172,
"number_of_properties": 1541
},
{
"latitude": 50.90584182739258,
"longitude": -114.0041046142578,
"number_of_properties": 1627
},
{
"latitude": 51.04402160644531,
"longitude": -114.18861389160156,
"number_of_properties": 2468
},
{
"latitude": 50.9903678894043,
"longitude": -114.10713958740234,
"number_of_properties": 1777
},
{
"latitude": 50.93876647949219,
"longitude": -114.05735778808594,
"number_of_properties": 1354
},
{
"latitude": 51.12089157104492,
"longitude": -114.19044494628906,
"number_of_properties": 1442
},
{
"latitude": 51.14344787597656,
"longitude": -114.1373519897461,
"number_of_properties": 3459
},
{
"latitude": 51.14748764038086,
"longitude": -113.98980712890624,
"number_of_properties": 781
},
{
"latitude": 51.071407318115234,
"longitude": -114.1011199951172,
"number_of_properties": 2316
}
],
"heatmap": [],
"properties": []
},
"error": "",
"heatmap_aggregation_field": null,
"heatmap_aggregation_max_value": null,
"heatmap_aggregation_min_value": null,
"heatmap_aggregation_type": null,
"is_clusters": true,
"is_heatmap": false,
"is_heatmap_aggregation": null,
"is_heatmap_aggregation_invert_intensity": null,
"is_properties": false,
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 10,
"time_ms": 101
}
curl -X GET "https://api.houski.ca/map?api_key=YOUR_API_KEY&bbox_ne_lat=51.17345&bbox_ne_lng=-113.96269&bbox_sw_lat=50.87234&bbox_sw_lng=-114.22313&heatmap=true&heatmap_cell_limit=10"
const houski_map_data_basic_heatmap = async (): Promise<MapResponse> => {
// You must copy the MapResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/map');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('bbox_ne_lat', '51.17345');
url.searchParams.set('bbox_ne_lng', '-113.96269');
url.searchParams.set('bbox_sw_lat', '50.87234');
url.searchParams.set('bbox_sw_lng', '-114.22313');
url.searchParams.set('heatmap', 'true');
url.searchParams.set('heatmap_cell_limit', '10');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: MapResponse = await houski_map_data_basic_heatmap();
// Log the response
console.log(data);
})();
{
"aborted": false,
"cache_hit": true,
"cost_cents": 2.5396149158477783,
"data": {
"clusters": [],
"heatmap": [
{
"aggregation_value": null,
"intensity": 0.017478259280323982,
"latitude": 51.20560836791992,
"longitude": -113.9850845336914,
"number_of_properties": 2253
},
{
"aggregation_value": null,
"intensity": 0.049603190273046494,
"latitude": 51.20560836791992,
"longitude": -114.17552185058594,
"number_of_properties": 6394
},
{
"aggregation_value": null,
"intensity": 0.051201291382312775,
"latitude": 50.919952392578125,
"longitude": -114.17552185058594,
"number_of_properties": 6600
},
{
"aggregation_value": null,
"intensity": 0.1329914778470993,
"latitude": 51.20560836791992,
"longitude": -114.0802993774414,
"number_of_properties": 17143
},
{
"aggregation_value": null,
"intensity": 0.1412690132856369,
"latitude": 51.110389709472656,
"longitude": -113.9850845336914,
"number_of_properties": 18210
},
{
"aggregation_value": null,
"intensity": 0.26275572180747986,
"latitude": 51.01517105102539,
"longitude": -113.9850845336914,
"number_of_properties": 33870
},
{
"aggregation_value": null,
"intensity": 0.3050278127193451,
"latitude": 50.919952392578125,
"longitude": -113.9850845336914,
"number_of_properties": 39319
},
{
"aggregation_value": null,
"intensity": 0.4229847192764282,
"latitude": 51.01517105102539,
"longitude": -114.17552185058594,
"number_of_properties": 54524
},
{
"aggregation_value": null,
"intensity": 0.5016329884529114,
"latitude": 51.110389709472656,
"longitude": -114.0802993774414,
"number_of_properties": 64662
},
{
"aggregation_value": null,
"intensity": 0.5264966487884521,
"latitude": 51.110389709472656,
"longitude": -114.17552185058594,
"number_of_properties": 67867
},
{
"aggregation_value": null,
"intensity": 0.5289093255996704,
"latitude": 50.919952392578125,
"longitude": -114.0802993774414,
"number_of_properties": 68178
},
{
"aggregation_value": null,
"intensity": 1.0,
"latitude": 51.01517105102539,
"longitude": -114.0802993774414,
"number_of_properties": 128903
}
],
"properties": []
},
"error": "",
"heatmap_aggregation_field": null,
"heatmap_aggregation_max_value": null,
"heatmap_aggregation_min_value": null,
"heatmap_aggregation_type": "mean",
"is_clusters": false,
"is_heatmap": true,
"is_heatmap_aggregation": false,
"is_heatmap_aggregation_invert_intensity": false,
"is_properties": false,
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 12,
"time_ms": 81
}
curl -X GET "https://api.houski.ca/map?api_key=YOUR_API_KEY&bbox_ne_lat=51.17345&bbox_ne_lng=-113.96269&bbox_sw_lat=50.87234&bbox_sw_lng=-114.22313&heatmap=true&heatmap_aggregation_field=estimate_list_price&heatmap_aggregation_type=median&heatmap_cell_limit=10"
const houski_map_data_price_heatmap = async (): Promise<MapResponse> => {
// You must copy the MapResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/map');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('bbox_ne_lat', '51.17345');
url.searchParams.set('bbox_ne_lng', '-113.96269');
url.searchParams.set('bbox_sw_lat', '50.87234');
url.searchParams.set('bbox_sw_lng', '-114.22313');
url.searchParams.set('heatmap', 'true');
url.searchParams.set('heatmap_aggregation_field', 'estimate_list_price');
url.searchParams.set('heatmap_aggregation_type', 'median');
url.searchParams.set('heatmap_cell_limit', '10');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: MapResponse = await houski_map_data_price_heatmap();
// Log the response
console.log(data);
})();
{
"aborted": false,
"cache_hit": true,
"cost_cents": 2.5396149158477783,
"data": {
"clusters": [],
"heatmap": [
{
"aggregation_value": 576733.0,
"intensity": 0.206860288977623,
"latitude": 51.110389709472656,
"longitude": -113.9850845336914,
"number_of_properties": 18210
},
{
"aggregation_value": 637003.0,
"intensity": 0.4210264384746551,
"latitude": 50.919952392578125,
"longitude": -114.0802993774414,
"number_of_properties": 68178
},
{
"aggregation_value": 669490.0,
"intensity": 0.5364672541618347,
"latitude": 51.110389709472656,
"longitude": -114.0802993774414,
"number_of_properties": 64662
},
{
"aggregation_value": 799936.0,
"intensity": 1.0,
"latitude": 51.01517105102539,
"longitude": -114.17552185058594,
"number_of_properties": 54524
},
{
"aggregation_value": 541876.5,
"intensity": 0.08299960196018219,
"latitude": 51.01517105102539,
"longitude": -113.9850845336914,
"number_of_properties": 33870
},
{
"aggregation_value": 584563.0,
"intensity": 0.23468376696109772,
"latitude": 51.20560836791992,
"longitude": -114.0802993774414,
"number_of_properties": 17143
},
{
"aggregation_value": 518519.0,
"intensity": 0.0,
"latitude": 51.20560836791992,
"longitude": -114.17552185058594,
"number_of_properties": 6394
},
{
"aggregation_value": 637884.0,
"intensity": 0.4241570234298706,
"latitude": 50.919952392578125,
"longitude": -113.9850845336914,
"number_of_properties": 39319
},
{
"aggregation_value": 635795.0,
"intensity": 0.41673389077186584,
"latitude": 51.01517105102539,
"longitude": -114.0802993774414,
"number_of_properties": 128903
},
{
"aggregation_value": 722781.0,
"intensity": 0.7258338928222656,
"latitude": 51.110389709472656,
"longitude": -114.17552185058594,
"number_of_properties": 67867
},
{
"aggregation_value": 720508.0,
"intensity": 0.7177569270133972,
"latitude": 50.919952392578125,
"longitude": -114.17552185058594,
"number_of_properties": 6600
},
{
"aggregation_value": 547350.0,
"intensity": 0.10244938731193542,
"latitude": 51.20560836791992,
"longitude": -113.9850845336914,
"number_of_properties": 2253
}
],
"properties": []
},
"error": "",
"heatmap_aggregation_field": "estimate_list_price",
"heatmap_aggregation_max_value": 799936.0,
"heatmap_aggregation_min_value": 518519.0,
"heatmap_aggregation_type": "median",
"is_clusters": false,
"is_heatmap": true,
"is_heatmap_aggregation": true,
"is_heatmap_aggregation_invert_intensity": false,
"is_properties": false,
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 12,
"time_ms": 106
}
curl -X GET "https://api.houski.ca/map?abort_over=500000&address_regex=^1(1|2|3)(1|2|3|4|5).*$&api_key=YOUR_API_KEY&cluster_over=1000&page=1&polygon=51.0447_-114.0719,51.0544_-114.0719,51.0544_-114.0856,51.0452_-114.0856&results_per_page=3&select=address"
const houski_map_data_polygon = async (): Promise<MapResponse> => {
// You must copy the MapResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/map');
url.searchParams.set('abort_over', '500000');
url.searchParams.set('address_regex', '^1(1|2|3)(1|2|3|4|5).*$');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('cluster_over', '1000');
url.searchParams.set('page', '1');
url.searchParams.set('polygon', '51.0447_-114.0719,51.0544_-114.0719,51.0544_-114.0856,51.0452_-114.0856');
url.searchParams.set('results_per_page', '3');
url.searchParams.set('select', 'address');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: MapResponse = await houski_map_data_polygon();
// Log the response
console.log(data);
})();
{
"aborted": false,
"cache_hit": true,
"cost_cents": 0.119999997317791,
"data": {
"clusters": [],
"heatmap": [],
"properties": [
{
"address": "1213 608 9 Street SW",
"latitude": 51.04768371582031,
"longitude": -114.0837173461914,
"property_id": "10ab0ffc777c870"
},
{
"address": "1110 605 5 Avenue SW",
"latitude": 51.048583984375,
"longitude": -114.0745086669922,
"property_id": "10c1af6fea51866f"
},
{
"address": "1110 618 5 Avenue SW",
"latitude": 51.04884719848633,
"longitude": -114.07439422607422,
"property_id": "113a70687880c4e9"
}
]
},
"error": "",
"heatmap_aggregation_field": null,
"heatmap_aggregation_max_value": null,
"heatmap_aggregation_min_value": null,
"heatmap_aggregation_type": null,
"is_clusters": false,
"is_heatmap": false,
"is_heatmap_aggregation": null,
"is_heatmap_aggregation_invert_intensity": null,
"is_properties": true,
"pagination": {
"current_page": 1,
"has_next_page": true,
"has_previous_page": false,
"page_total": 59
},
"price_quote": false,
"result_total": 176,
"time_ms": 485
}
interface MapResponse {
aborted: boolean;
cache_hit: boolean;
cost_cents: number;
data: MapData;
error: string;
is_clusters: boolean;
is_properties: boolean;
is_heatmap: boolean;
is_heatmap_aggregation?: boolean | null;
is_heatmap_aggregation_invert_intensity?: boolean | null;
heatmap_aggregation_type?: string | null;
heatmap_aggregation_max_value?: number | null;
heatmap_aggregation_min_value?: number | null;
heatmap_aggregation_field?: string | null;
pagination: Pagination;
price_quote: boolean;
result_total: number;
time_ms: number;
}
interface MapData {
properties: Property[];
clusters: Cluster[];
heatmap: HeatPoint[];
}
interface Cluster {
latitude: number;
longitude: number;
number_of_properties: number;
}
interface HeatPoint {
latitude: number;
longitude: number;
intensity: number;
number_of_properties: number;
aggregation_value?: number | null;
}
interface Pagination {
current_page: number;
has_next_page: boolean;
has_previous_page: boolean;
page_total: number;
}
// You can find the Property type on the /properties endpoint API docs
// https://www.houski.ca/api-documentation/properties