Articles on: Property Search & Filtering

Locations API Implementation Guide

Overview


The Locations API provides two endpoints for working with geographical data in your real estate application:


  • GET /locations - Advanced filtering and querying of location data
  • GET /locations/autocomplete - Relevance-based search for typeahead/dropdown interfaces


These endpoints use location terminology that directly matches your MLS data, eliminating the common mismatch issues that occur when using third-party services like Google Maps or Mapbox for location search.


Try out locations endpoints in our Developer Playgrounds


Understanding Location Sources


The API aggregates location data from multiple providers, each offering different geographical coverage and use cases. Use the source parameter to restrict results to a specific provider, or omit it to search across all available sources.


  • MLS - Locations sourced directly from MLS (Multiple Listing Service) data. These locations use terminology that matches your MLS board exactly, ensuring consistency with the geographical divisions referenced in your listings data and eliminating mismatch issues common with third-party geocoders. Usually doesn't contain boundary data.
  • UserDefined - Custom locations you create and define yourself. Use this source to add proprietary neighborhoods, service areas, or any bespoke geographies specific to your business that aren't represented in MLS data.
  • LiveBy - Locations sourced from LiveBy, a third-party provider specializing in neighborhood and community data. LiveBy augments MLS data with neighborhood boundaries and community-level detail, useful when you need location boundaries data and neighborhood insights.


Understanding Location Types


The API recognizes location types spanning multiple geographical hierarchies and administrative divisions:


  • area - Larger geographical divisions (synonymous with region, county, parish) that may contain multiple cities and neighborhoods
  • city - Municipal divisions (synonymous with town) that can include multiple neighborhoods
  • city-alternate - Alternate representation of a city, used for specific data sources or contexts
  • neighborhood - The smallest geographical unit (synonymous with community) within a city
  • neighborhood-alternate - Alternate representation of a neighborhood, used for specific data sources or contexts
  • postalCode - Postal code areas that may span multiple neighborhoods or cities
  • district - Administrative or political districts that may span multiple neighborhoods or cities
  • schoolDistrict - School district areas that may span multiple neighborhoods or cities
  • school - Specific school locations and their catchment areas


Location Model


Each location entity includes the following structure:


{
"locationId": "CAONNBWJBFJQLT",
"name": "Downsview-Roding-CFB",
"type": "neighborhood",
"map": {
"latitude": "43.7298069",
"longitude": "-79.4923515",
"point": "POINT (-79.4923515 43.7298069)",
"boundary": [
[
[
-79.55113337288341,
43.77949638257084
],
[
-79.45357859322043,
43.802565569203864
],
[
-79.42666692986468,
43.73381743036484
],
[
-79.55113337288341,
43.77949638257084
]
]
]
},
"address": {
"state": "ON",
"country": "CA",
"city": "Toronto",
"area": "Toronto",
"neighborhood": "Downsview-Roding-CFB"
}
}


GET /locations


Use this endpoint for advanced filtering, pagination, and geographical queries.


Common Use Cases


1. List All Neighborhoods in a City


GET /locations?city=Toronto&type=neighborhood


Returns all neighborhoods within Toronto.


2. List All Cities and Neighborhoods in an Area


GET /locations?area=York%20Region&type=city,neighborhood


Returns all cities and neighborhoods within York Region.


3. Get All Areas in a State


GET /locations?state=MA&typearea


4. Get Locations Within a Radius


GET /locations?lat=43.7298069&long=-79.4923515&radius=5


Returns all locations within 5km of the specified coordinates.


5. Get Locations with Boundaries Only


GET /locations?city=Toronto&hasBoundary=true


Returns only locations that have boundary polygon data, useful for map visualization.


6. Optimize Response Size with Field Selection


GET /locations?city=Toronto&type=neighborhood&fields=name,type,locationId


Returns only the specified fields, reducing payload size for better performance.


GET /locations Parameters Reference


Parameter

Type

Description

pageNum

integer

Page number for pagination (e.g., pageNum=2 for results 101-200 with 100 results per page)

resultsPerPage

integer

Number of locations per page (1-300, default: 100)

source

array of strings

Filter by data source: MLS, UserDefined, LiveBy

type

array of strings

Filter by location type: area, city, city-alternate, neighborhood, neighborhood-alternate, postalCode, district, schoolDistrict, school

area

array of strings

Filter by area names

city

array of strings

Filter by city names

neighborhood

array of strings

Filter by neighborhood names

state

array of strings

Filter by 2-letter state/province/territory codes

locationId

array of strings

Filter by specific location IDs (obtained from autocomplete endpoint)

name

string

Filter by exact location name (case-insensitive)

classification

array of strings

Filter by location classification

subType

array of strings

Filter by location sub-type

minSize

float

Minimum location size in square kilometers

maxSize

float

Maximum location size in square kilometers

lat

float

Latitude coordinate (requires long; combine with radius or pointWithinBoundary)

long

float

Longitude coordinate (requires lat; combine with radius or pointWithinBoundary)

radius

float

Radius in kilometers (requires lat and long)

map

GeoJSON

Polygon or multi-polygon boundary for geographical filtering

pointWithinBoundary

boolean

When true, returns only locations whose boundaries contain the point specified by lat/long (default: false)

hasBoundary

boolean

Return only locations with boundary polygons

schoolType

array of strings

Filter schools by school type (applies when type=school)

schoolLevel

array of strings

Filter schools by school level (applies when type=school)

privateSchoolAffiliation

array of strings

Filter schools by private school affiliation (applies when type=school)

schoolDistrictName

array of strings

Filter schools by school district name (applies when type=school)

fields

string

Comma-separated list of fields to include in response

locations

boolean

Include locations in the response (default: true). Set to false to speed up responses when only aggregates are needed

aggregates

string

Return aggregated values and counts for specified fields

sortBy

string

Sort results by type: typeAsc or typeDesc



Geographical Filtering with Boundaries

You can filter locations that fall within a custom boundary using GeoJSON polygon format:


GET /locations?map=[[[long1,lat1],[long2,lat2],[long3,lat3],[long1,lat1]]]


Important Notes:


  • Coordinates must be in [longitude, latitude] order (WGS 84 format)
  • Polygons must be closed (first and last points identical)
  • For large polygons, use POST method with map data in request body


Pagination

To paginate through results, use the pageNum and resultsPerPage parameters together. For example, with 50 results per page:


  • Page 1: pageNum=1&resultsPerPage=50
  • Page 2: pageNum=2&resultsPerPage=50
  • Page 3: pageNum=3&resultsPerPage=50


Using Aggregates to Discover Filter Values


The aggregates parameter returns the distinct values and counts for a given field across the matching location set. This is the recommended way to populate filter UIs (dropdowns, chips, checkboxes) with values that actually exist in your data — instead of hardcoding enum lists that may drift out of sync.


Pass a comma-separated list of supported fields:


GET /locations?aggregates=school.districtName,school.schoolType&locations=false


Tip: Set locations=false when you only need aggregate data. This skips fetching and serializing the locations array, significantly reducing response time and payload size.


Aggregates respect any filters applied to the request, so you can scope the distinct values to a subset of locations. For example, to see the school types available within a specific city:


GET /locations?city=Austin&type=school&aggregates=school.schoolType&locations=false


Example response:


{
"source": ["MLS", "LiveBy"],
"page": 1,
"numPages": 104,
"pageSize": 100,
"count": 10337,
"aggregates": {
"school": {
"districtName": {
"Austin Independent School District": 129,
"Pflugerville Independent School District": 34,
"Leander Independent School District": 24,
"Round Rock Independent School District": 23,
"Manor Independent School District": 17
},
"schoolType": {
"public": 386,
"private": 105
}
}
},
"locations": []
}


Each key in the aggregate object is a distinct value; each value is the count of locations that have it. Nested fields (e.g. school.districtName) are returned as nested objects in the response.


Supported aggregate fields:


  • Core: type, subType, classification, source
  • Address: address.state, address.area, address.city, address.neighborhood
  • School identification: school.districtName, school.schoolType, school.schoolLevel, school.lowGrade, school.highGrade, school.privateSchoolAffiliation
  • School classification flags: school.isCharterSchool, school.isMagnetSchool, school.isVirtualSchool, school.isPrivate, school.isJJFacility, school.isTitleISchool, school.isTitleISchoolwideSchool, school.isAssigned
  • School programs: school.giftedAndTalented, school.dualEnrollment, school.creditRecovery, school.singleSexClasses, school.apCourse, school.apEnrollment, school.internationalBaccalaureate, school.corporalPunishment, school.interscholarAthletics, school.offersKindergarten, school.offersFullDayKindergarten
  • Private school details: school.privateHours, school.privateDays, school.privateHasLibrary, school.privateCoed
  • Other: school.expenditurePerStudent


Requesting an aggregate on a field not in the list above will return and error.



GET /locations/autocomplete


Use this endpoint for implementing search-as-you-type functionality in dropdown menus and search boxes. The endpoint uses relevance-based matching and handles partial searches and spelling mistakes.


Common Use Cases



GET /locations/autocomplete?search=down


Returns relevant matches like "Downsview-Roding-CFB", "Downtown Toronto", etc.


2. Search Within Specific City


GET /locations/autocomplete?search=park&city=Toronto


Returns only locations containing "park" within Toronto.


3. Search for Specific Location Type


GET /locations/autocomplete?search=york&type=area


Returns only areas (counties/regions) matching "york".


4. Include Boundaries for Map Display


GET /locations/autocomplete?search=downtown&boundary=true


Returns matching locations with their boundary polygons included (adds 10-20ms latency).


GET /locations/autocomplete Parameters Reference


Parameter

Type

Description

search

string

Required. User's search input (3-100 characters)

source

array of strings

Filter by data source: MLS, UserDefined, LiveBy

type

array of strings

Filter by location type: area, city, city-alternate, neighborhood, neighborhood-alternate, postalCode, district, schoolDistrict, school

area

array of strings

Search only within specified areas

city

array of strings

Search only within specified cities

state

array of strings

Filter by 2-letter state/province/territory codes

classification

array of strings

Filter by location classification

subType

array of strings

Filter by location sub-type

minSize

float

Minimum location size in square kilometers

maxSize

float

Maximum location size in square kilometers

lat

float

Latitude coordinate (requires long; combine with radius)

long

float

Longitude coordinate (requires lat; combine with radius)

radius

float

Radius in kilometers (requires lat and long)

map

GeoJSON

Limit search to locations within specified boundary

boundary

boolean

Include boundary polygons in results (adds 10-20ms latency)

hasBoundary

boolean

Only search locations that have boundary polygons

fields

string

Comma-separated list of fields to include in response

resultsPerPage

integer

Number of results per page (1-10, default: 10)


Best Practices


1. Use Field Selection to Optimize Performance

Only request the fields you need to reduce payload size and improve response times:


// Good: Only request needed fields
GET /locations/autocomplete?search=toronto&fields=name,type,locationId

// Avoid: Requesting all data when you only need basic info
GET /locations/autocomplete?search=toronto


2. Implement Proper Debouncing

Debounce autocomplete requests (typically 200-300ms) to reduce unnecessary API calls as users type.


3. Handle Boundary Data Efficiently

Only request boundaries when you need them for map visualization:


// When you need to display on map
GET /locations?city=Toronto&hasBoundary=true&fields=name,map.boundary

// When you only need location names for a list
GET /locations?city=Toronto&fields=name,type


4. Chain Autocomplete with Full Location Queries

Use the autocomplete endpoint to get locationIds based on user search, then use the /locations endpoint with the locationId parameter to retrieve full location details including boundaries and complete address information.


5. Use Hierarchical Filtering

Structure your location selection flow hierarchically for better user experience:


  1. First, let users select an area
  2. Then show cities within the selected area
  3. Finally, show neighborhoods within the selected city


Use the area, city, and type parameters to implement this hierarchy.


Common Integration Patterns


Pattern 1: Property Search by Location

Use the autocomplete endpoint to help users find a location, retrieve the locationId from the selected result, then use that locationId to filter listings in your listings search endpoint.




Pattern 2: Map-Based Exploration

Retrieve locations with boundary polygons using the /locations endpoint with hasBoundary=true, then render these boundaries on your map interface. Users can click on boundary polygons to view properties within that location




When users click on a map or enter coordinates, use the lat, long, and radius parameters to find all locations within a specific distance. This is useful for "search nearby" functionality.


Pattern 4: Geographical Filtering

Use the map parameter with a custom polygon to find locations within a user-drawn area on a map. This enables "draw a boundary" search functionality.


Troubleshooting


No Results Returned

  • Check that location type filters match available data
  • Try broader search terms in autocomplete
  • Verify geographical coordinates are in the correct format (longitude, latitude order)


Response Times

  • Use fields parameter to limit returned data
  • Only request boundary data when necessary for map visualization
  • Implement proper pagination with reasonable resultsPerPage values
  • Use autocomplete endpoint for search operations (it's optimized for speed)


Boundary Polygons Missing

  • Not all locations have boundary data available
  • Use hasBoundary=true to filter only locations with boundaries
  • Use boundary=true in autocomplete when you need boundary data included


Query Parameter Size Limits

If your GeoJSON polygon data exceeds URL query parameter size limits, use the POST method instead of GET and include the map data in the request body.


What questions does this article answer?


  • What does the Locations API do and what endpoints are available?
  • How are area, city, and neighborhood defined and related hierarchically?
  • How can I use the Locations API to drive search filters or dropdowns that match MLS® terminology?
  • How do I build a typeahead / autocomplete UI for locations using GET /locations/autocomplete?
  • How does integrating Locations with listing search improve relevance vs. using generic geocoding?

Updated on: 17/04/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!