/map

GET
https://api.houski.ca/map

The map endpoint provides access to property map pins (which are essentially just properties), and clusters. Additionally, it can generate heatmap data, presented as a grid of cells where each cell's intensity reflects the concentration of properties relative to other cells. The endpoint supports extensive filtering options for properties, including fields such as list price, sale price, for sale status, and number of bedrooms, among others.

This endpoint conforms to Houski API's standard filtering and sorting functionality.

To see all the fields that can be filtered or sorted by, see the fields page.

Example use cases

You can find examples for common use cases on our recipes page.
  1. Systems that track and monitor property data changes in a region. For example, to monitor for properties or land going on sale within a specific boundary.
  2. Online property marketplaces can enhance their services with map-based functionality.
  3. Governments can leverage both pin and cluster data for housing and urban planning.
  4. Investors can visualize high-potential areas and trends for property investment.
  5. Insurance companies can use the data to better assess property risks.
  6. Property management companies can optimize rental pricing strategies.
  7. Journalists can use the data to create visualizations for stories related to housing trends and affordability, for example 'Where are the cheapest houses in Canada?'.
  8. Data analysts can derive fast, unique insights from clustered property data.

Request parameters

NameRequiredTypeDescription
api_keyYesUUID v4Authorization API key
clusterNoBoolean (default: false)Manual control of whether the data returned should be in pins or clusters.
cluster_overNoIntegerAutomatically return clusters instead of pins when there are more results than this.
heatmapNoBoolean (default: false)Return heatmap data instead of pins.
heatmap_cell_limitNoIntegerThe max number of heatmap cells returned (default: 1000)
abort_overNoIntegerAbort request if number of results exceeds this value (cost control).
polygonIf not using bboxPolygon filter stringGet results inside a polygon.
bbox_ne_latIf not using polygonNumberNortheast latitude for bounding box.
bbox_ne_lngIf not using polygonNumberNortheast longitude for bounding box.
bbox_sw_latIf not using polygonNumberSouthwest latitude for bounding box.
bbox_sw_lngIf not using polygonNumberSouthwest longitude for bounding box.

Response object

Type declarations are available at the bottom of this page.

NameTypeDescription
cache_hitBooleanIndicates if the data was retrieved from the cache
cost_centsNumberCost of the API call in cents
dataObjectContains the map data in 'clusters' and 'properties' sub-objects (for determinism)
errorStringDetails about the error. Empty if no error
is_propertiesBooleanIndicates if the returned data is properties
is_clusterBooleanIndicates if the returned data is clusters
paginationObjectPagination information
price_quoteBooleanRequest is for a price quote
result_totalNumberTotal number of results
time_msNumberTime taken for the request to complete in milliseconds

Example requests and responses

Programming language

Select the programming language you want to display the code examples in.

Get map data by bounding box
Request
Shell session
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"
TypeScript code
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);
})();
Response
JSON
{
  "aborted": false,
  "cache_hit": true,
  "cost_cents": 0.11453499644994736,
  "data": {
    "clusters": [
      {
        "latitude": 51.0633430480957,
        "longitude": -114.11053466796876,
        "number_of_properties": 1665
      },
      {
        "latitude": 50.90694046020508,
        "longitude": -114.09441375732422,
        "number_of_properties": 1456
      },
      {
        "latitude": 50.906883239746094,
        "longitude": -114.00670623779295,
        "number_of_properties": 2666
      },
      {
        "latitude": 51.02766418457031,
        "longitude": -114.1750946044922,
        "number_of_properties": 2110
      },
      {
        "latitude": 50.959529876708984,
        "longitude": -114.11669158935548,
        "number_of_properties": 2293
      },
      {
        "latitude": 50.93888092041016,
        "longitude": -114.04544830322266,
        "number_of_properties": 1805
      },
      {
        "latitude": 51.05910873413086,
        "longitude": -114.1979751586914,
        "number_of_properties": 2158
      },
      {
        "latitude": 51.145469665527344,
        "longitude": -114.10301208496094,
        "number_of_properties": 2264
      },
      {
        "latitude": 51.11467361450195,
        "longitude": -113.97093963623048,
        "number_of_properties": 1108
      },
      {
        "latitude": 51.13216781616211,
        "longitude": -114.16522979736328,
        "number_of_properties": 5382
      }
    ],
    "heatmap": [],
    "properties": []
  },
  "error": "",
  "is_clusters": true,
  "is_heatmap": false,
  "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": 42
}
Get map data by polygon

Polygon requests are made from a string in the format of 'lat_lng,lat_lng,lat_lng...', for all of the polygon's points.

Request
Shell session
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&polygon=51.0447_-114.0719,51.0544_-114.0719,51.0544_-114.0856,51.0452_-114.0856&results_per_page=3&select=address"
TypeScript code
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('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);
})();
Response
JSON
{
  "aborted": false,
  "cache_hit": false,
  "cost_cents": 1.2000000476837158,
  "data": {
    "clusters": [],
    "heatmap": [],
    "properties": [
      {
        "address": "114 777 3 Avenue SW",
        "latitude": 51.05043029785156,
        "longitude": -114.07775115966795,
        "property_id": "5cd54ffaecc557da"
      },
      {
        "address": "1212 815 4 Avenue SW",
        "latitude": 51.04952621459961,
        "longitude": -114.079345703125,
        "property_id": "a85a533b5fdeb95"
      },
      {
        "address": "1318 815 4 Avenue SW",
        "latitude": 51.04952621459961,
        "longitude": -114.079345703125,
        "property_id": "de3f059cc156975a"
      }
    ]
  },
  "error": "",
  "is_clusters": false,
  "is_heatmap": false,
  "is_properties": true,
  "pagination": {
    "current_page": 1,
    "has_next_page": true,
    "has_previous_page": false,
    "page_total": 17
  },
  "price_quote": false,
  "result_total": 49,
  "time_ms": 1093
}

Response type declarations

TypeScript code
interface MapResponse {
    aborted: boolean;
    cache_hit: boolean;
    cost_cents: number;
    data: MapData;
    error: string;
    is_clusters: boolean;
    is_properties: boolean;
    is_heatmap: boolean;
    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;
}

// You can find the Property type on the /properties endpoint API docs
// https://www.houski.ca/api-documentation/properties