/location

GET
http://127.0.0.1:8080/location

A catalogue of the places we hold data for, from countries down through provinces and states, cities, and the communities inside them. Each place comes back with its name, its identifier, its slug, and a ready made link, which is what you use to decide what to ask the other endpoints for next. It answers "what places can I query", not "what is happening in this place".

Use it to fill the menus people pick a place from, and to turn a place someone chose into the parameters that /properties and /map expect. It carries no prices, counts, or property attributes of its own.

Supports standard filtering. Results always come back ordered country, province, city, then community, so this endpoint takes no sort parameters.

What this costs

$0.00001 per location returned. Every place in Alberta is under two cents, and every place in Canada is about seven. Locations are the names, identifiers, and links you use to decide what to query next rather than property data itself, so they are the cheapest thing we sell.

The rate is the same at every resolution, and the same whether you take the nested tree or the flat list. Asking for communities instead of cities returns more columns per row, and none of those extra columns change the price. See the pricing page for how this compares to the other endpoints.

Because the price is per location returned, narrowing the request costs less at each step. Every place in every country we cover is about $0.37. Adding country_abbreviation=ca brings it to about $0.07, adding province_abbreviation=ab to about $0.014, and adding city=calgary to about a third of a cent. Narrower requests are faster as well as cheaper, so set the narrowest scope that answers your question.

Calling it live is fine

This endpoint is priced so you do not have to cache it to afford it. A scoped request is a fraction of a cent, so filling a menu on every page load is a reasonable thing to do, and it means your menus follow our coverage the moment it changes rather than whenever your cache was last refreshed.

Caching is still worth it in one case: when you want every place in a whole country or in every country, on a page that gets a lot of traffic. That answer changes only when we add coverage, so there is nothing to gain by asking for it repeatedly.

Example use cases

  1. Country, province, city, and community selection dropdowns.
  2. Filter locations by user preferences like price range.
  3. Get pre-built links and slugs to other Houski resources.
  4. Market analysis: list regions, then query /properties or /map.

Request parameters

NameRequiredTypeDescription
api_keyYesUUID v4Your API key for authorization
communityNoStringA community within the city
cityNoStringA city within the province
province_abbreviationNoStringA province abbreviation within the country
country_abbreviationNoStringA country abbreviation
flatNoBoolean (default: false)Return data in a flat data structure
resolutionNoStringFinest level returned: 'country', 'province', 'city' or 'community'

This endpoint has no paging and returns every location that matches in one response. Narrow the response with resolution and the location parameters above.

This endpoint also supports field filters on any filterable property field, like community_regex or bedroom_gte. See the filtering documentation for details.

Response object

Type declarations are available at the bottom of this page.

NameTypeDescription
cache_hitBooleanIndicates if the data was retrieved from the cache
cost_centsFloatCost of the API call in cents
dataObjectHolds location data in 'nested' and 'flat' sub-objects
errorStringDetails about the error. Empty if no error
is_nestedBooleanIndicates if the returned data is nested
is_flatBooleanIndicates if the returned data is flat
price_quoteBooleanIndicates whether the response is a price quote
result_totalIntegerTotal number of results
time_msIntegerTime taken for the request to complete in milliseconds

LocationData object

NameTypeDescription
nestedNestedLocationLocation data organized in a hierarchical structure
flatArray<FlatLocation>Location data as a flat array of location objects

NestedLocation object

NameTypeDescription
countriesArray<CountryNested>Countries with nested provinces, cities, and communities

CountryNested object

NameTypeDescription
nameStringFull country name
linkStringURL link to the country page
idStringUnique identifier for the country
abbreviationStringCountry abbreviation (e.g., 'ca', 'us')
slugStringURL-friendly slug for the country
provincesArray<ProvinceNested>Array of province objects within this country

ProvinceNested object

NameTypeDescription
nameStringFull province name
linkStringURL link to the province page
idStringUnique identifier for the province
abbreviationStringProvince abbreviation (e.g., 'ab', 'bc')
slugStringURL-friendly slug for the province
citiesArray<CityNested>Array of city objects within this province

CityNested object

NameTypeDescription
nameStringFull city name
linkStringURL link to the city page
slugStringURL-friendly slug for the city
idStringUnique identifier for the city
communitiesArray<CommunityNested>Array of community objects within this city

CommunityNested object

NameTypeDescription
nameStringFull community name
slugStringURL-friendly slug for the community
idStringUnique identifier for the community
linkStringURL link to the community page

FlatLocation object

NameTypeDescription
city_idString?Unique identifier for the city
city_linkString?URL link to the city page
city_slugString?URL-friendly slug for the city
cityString?Full city name
community_idString?Unique identifier for the community
community_linkString?URL link to the community page
community_slugString?URL-friendly slug for the community
communityString?Full community name
country_abbreviationString?Country abbreviation (e.g., 'ca', 'us')
country_abbreviation_idString?Unique identifier for the country abbreviation
country_abbreviation_linkString?URL link to the country page
country_slugString?URL-friendly slug for the country
countryString?Full country name
province_abbreviationString?Province abbreviation (e.g., 'ab', 'bc')
province_abbreviation_idString?Unique identifier for the province abbreviation
province_abbreviation_linkString?URL link to the province page
province_slugString?URL-friendly slug for the province
provinceString?Full province name

Example requests and responses

Programming language

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

Get location data in nested format
By default, location endpoint responses are returned in a nested format.
Request
Shell session
curl -X GET "http://127.0.0.1:8080/location?api_key=YOUR_API_KEY&city=calgary&community_regex=(?i)^ra&country_abbreviation=ca&province_abbreviation=ab"
TypeScript code
const houski_location_data_nested = async (): Promise<LocationResponse> => {

    // You must copy the LocationResponse type declarations from the 
    // Houski API documentation to strongly type the response

    const url = new URL('http://127.0.0.1:8080/location');
    url.searchParams.set('api_key', 'YOUR_API_KEY');
    url.searchParams.set('city', 'calgary');
    url.searchParams.set('community_regex', '(?i)^ra');
    url.searchParams.set('country_abbreviation', 'ca');
    url.searchParams.set('province_abbreviation', 'ab');

    const response = await fetch(url);
    const data = await response.json();

    return data;
}

(async () => {
let data: LocationResponse = await houski_location_data_nested();

// Log the response
console.log(data);
})();
Response
JSON
{
  "cache_hit": true,
  "cost_cents": 0.003000000026077032,
  "data": {
    "flat": [],
    "nested": {
      "countries": [
        {
          "abbreviation": "CA",
          "id": "9ace2b6431b7f1be",
          "link": "ca",
          "name": "Canada",
          "provinces": [
            {
              "abbreviation": "AB",
              "cities": [
                {
                  "communities": [
                    {
                      "id": "e4ea09d684accf91",
                      "link": "ca/ab/calgary/ramsay",
                      "name": "Ramsay",
                      "slug": "ramsay"
                    },
                    {
                      "id": "7244c981dd55f8d5",
                      "link": "ca/ab/calgary/ranchlands",
                      "name": "Ranchlands",
                      "slug": "ranchlands"
                    },
                    {
                      "id": "b67fb29c420a316e",
                      "link": "ca/ab/calgary/rangeview",
                      "name": "Rangeview",
                      "slug": "rangeview"
                    }
                  ],
                  "id": "6ec95b53075d062c",
                  "link": "ca/ab/calgary",
                  "name": "Calgary",
                  "slug": "calgary"
                }
              ],
              "id": "aae1f05a0f89d2c7",
              "link": "ca/ab",
              "name": "Alberta",
              "slug": "alberta"
            }
          ],
          "slug": "canada"
        }
      ]
    }
  },
  "error": "",
  "is_flat": false,
  "is_nested": true,
  "price_quote": false,
  "result_total": 3,
  "time_ms": 361
}
Get location data in flat format
Request
Shell session
curl -X GET "http://127.0.0.1:8080/location?api_key=YOUR_API_KEY&city=calgary&community_regex=(?i)^ra&country_abbreviation=ca&flat=true&province_abbreviation=ab"
TypeScript code
const houski_location_data_flat = async (): Promise<LocationResponse> => {

    // You must copy the LocationResponse type declarations from the 
    // Houski API documentation to strongly type the response

    const url = new URL('http://127.0.0.1:8080/location');
    url.searchParams.set('api_key', 'YOUR_API_KEY');
    url.searchParams.set('city', 'calgary');
    url.searchParams.set('community_regex', '(?i)^ra');
    url.searchParams.set('country_abbreviation', 'ca');
    url.searchParams.set('flat', 'true');
    url.searchParams.set('province_abbreviation', 'ab');

    const response = await fetch(url);
    const data = await response.json();

    return data;
}

(async () => {
let data: LocationResponse = await houski_location_data_flat();

// Log the response
console.log(data);
})();
Response
JSON
{
  "cache_hit": true,
  "cost_cents": 0.003000000026077032,
  "data": {
    "flat": [
      {
        "city": "Calgary",
        "city_id": "6ec95b53075d062c",
        "city_link": "ca/ab/calgary",
        "city_slug": "calgary",
        "community": "Ramsay",
        "community_id": "e4ea09d684accf91",
        "community_link": "ca/ab/calgary/ramsay",
        "community_slug": "ramsay",
        "country": "Canada",
        "country_abbreviation": "CA",
        "country_abbreviation_id": "9ace2b6431b7f1be",
        "country_abbreviation_link": "ca",
        "country_slug": "canada",
        "province": "Alberta",
        "province_abbreviation": "AB",
        "province_abbreviation_id": "aae1f05a0f89d2c7",
        "province_abbreviation_link": "ca/ab",
        "province_slug": "alberta"
      },
      {
        "city": "Calgary",
        "city_id": "6ec95b53075d062c",
        "city_link": "ca/ab/calgary",
        "city_slug": "calgary",
        "community": "Ranchlands",
        "community_id": "7244c981dd55f8d5",
        "community_link": "ca/ab/calgary/ranchlands",
        "community_slug": "ranchlands",
        "country": "Canada",
        "country_abbreviation": "CA",
        "country_abbreviation_id": "9ace2b6431b7f1be",
        "country_abbreviation_link": "ca",
        "country_slug": "canada",
        "province": "Alberta",
        "province_abbreviation": "AB",
        "province_abbreviation_id": "aae1f05a0f89d2c7",
        "province_abbreviation_link": "ca/ab",
        "province_slug": "alberta"
      },
      {
        "city": "Calgary",
        "city_id": "6ec95b53075d062c",
        "city_link": "ca/ab/calgary",
        "city_slug": "calgary",
        "community": "Rangeview",
        "community_id": "b67fb29c420a316e",
        "community_link": "ca/ab/calgary/rangeview",
        "community_slug": "rangeview",
        "country": "Canada",
        "country_abbreviation": "CA",
        "country_abbreviation_id": "9ace2b6431b7f1be",
        "country_abbreviation_link": "ca",
        "country_slug": "canada",
        "province": "Alberta",
        "province_abbreviation": "AB",
        "province_abbreviation_id": "aae1f05a0f89d2c7",
        "province_abbreviation_link": "ca/ab",
        "province_slug": "alberta"
      }
    ],
    "nested": {
      "countries": []
    }
  },
  "error": "",
  "is_flat": true,
  "is_nested": false,
  "price_quote": false,
  "result_total": 3,
  "time_ms": 479
}

Response type declarations

TypeScript code
interface LocationResponse {
    cache_hit: boolean;
    cost_cents: number;
    data: LocationData;
    error: string;
    is_nested: boolean;
    is_flat: boolean;
    price_quote: boolean;
    result_total: number;
    time_ms: number;
}

interface LocationData {
    nested: NestedLocation;
    flat: FlatLocation[];
}

interface NestedLocation {
    countries: CountryNested[];
}

interface CountryNested {
    name: string;
    link: string;
    id: string;
    abbreviation: string;
    slug: string;
    provinces: ProvinceNested[];
}

interface ProvinceNested {
    name: string;
    link: string;
    id: string;
    abbreviation: string;
    slug: string;
    cities: CityNested[];
}

interface CityNested {
    name: string;
    link: string;
    slug: string;
    id: string;
    communities: CommunityNested[];
}

interface CommunityNested {
    name: string;
    slug: string;
    id: string;
    link: string;
}

interface FlatLocation {
    city_id?: string | null;
    city_link?: string | null;
    city_slug?: string | null;
    city?: string | null;
    community_id?: string | null;
    community_link?: string | null;
    community_slug?: string | null;
    community?: string | null;
    country_abbreviation?: string | null;
    country_abbreviation_id?: string | null;
    country_abbreviation_link?: string | null;
    country_slug?: string | null;
    country?: string | null;
    province_abbreviation?: string | null;
    province_abbreviation_id?: string | null;
    province_abbreviation_link?: string | null;
    province_slug?: string | null;
    province?: string | null;
}