Building an Autocomplete Search Feature with Repliers APIs
A comprehensive guide to implementing a unified search experience that combines MLS listings with cities and neighborhoods using the Repliers API.
This recipe demonstrates how to build a powerful autocomplete search feature that allows users to search for both MLS listings and locations simultaneously. The results are presented categorically, giving users a seamless search experience whether they're looking for a specific property address, MLS number, or exploring different areas.

The first step involves searching through MLS listings using the /listings endpoint. This allows users to find properties by address components or MLS numbers.
`address.streetNumber` - Allows finding properties by house number
`address.streetName` - Enables searching by street names
`mlsNumber` - Lets users search by listing ID/MLS number
`address.city` - Enables city-based property searches
Only request the fields you need to display in your autocomplete results. This improves API performance significantly. Learn more about field optimization in our Fields Parameter Guide.
Note: Results are returned in order of relevance based on our proprietary algorithm, refined over years of optimization.
Simultaneously search for matching locations using the /locations/autocomplete endpoint. This provides cities, neighborhoods, and areas from MLS data.
You can limit results to specific location types if needed:
This example excludes areas (counties/regions) and only returns cities and neighborhoods.
Concatenate the listings and locations results, then present them to users in organized categories (e.g., "Properties", "Cities", "Neighborhoods").
Debounce User Input Implement a debounce mechanism to prevent API calls on every keystroke. Recommended delay: 300-500ms after the user stops typing.
Field Selection Only request the fields you need in your fields parameter. This significantly improves response times and reduces bandwidth usage.
Concurrent Requests Execute both API calls (listings and locations) simultaneously using Promise.all() or similar concurrent execution patterns.
Categorized Results Present results in clear categories:
Properties (from listings endpoint)
Cities (from locations endpoint)
Neighborhoods (from locations endpoint)
Areas (from locations endpoint, if included)
Visual Hierarchy Use clear visual distinctions between categories and include relevant details like:
Property addresses and prices
Location types (city, neighborhood, area)
Geographic context when helpful
Loading States Implement appropriate loading indicators while API requests are in progress.
For markets where MLS location data doesn't align with local terminology, consider combining:
Option 1: Google Places Integration
Option 2: Mapbox Integration
This hybrid approach provides the comprehensive MLS listing data from Repliers while leveraging the superior location recognition capabilities of specialized mapping services.
This autocomplete implementation provides users with a comprehensive search experience that bridges the gap between specific property searches and general location exploration. By combining both endpoints and following the optimization practices outlined above, you can create a fast, intuitive search interface that helps users find exactly what they're looking for.
Overview
This recipe demonstrates how to build a powerful autocomplete search feature that allows users to search for both MLS listings and locations simultaneously. The results are presented categorically, giving users a seamless search experience whether they're looking for a specific property address, MLS number, or exploring different areas.
Example

Implementation Steps
Step 1: Search MLS Listings
The first step involves searching through MLS listings using the /listings endpoint. This allows users to find properties by address components or MLS numbers.
API Request
GET https://api.repliers.io/listings?search={user_input}&searchFields=address.streetNumber,address.streetName,mlsNumber,address.city&fields=address.*,mlsNumber,listPrice
Request Parameters Breakdown
Parameter | Description | Example |
---|---|---|
search | The user's input from the search field | 123 |
searchFields | Comma-separated list of fields to search within | address.streetNumber,address.streetName,mlsNumber,address.city |
fields | Fields to include in the response (for performance optimization) | address.*,mlsNumber,listPrice |
Why These Search Fields?
`address.streetNumber` - Allows finding properties by house number
`address.streetName` - Enables searching by street names
`mlsNumber` - Lets users search by listing ID/MLS number
`address.city` - Enables city-based property searches
Field Selection Best Practices
Only request the fields you need to display in your autocomplete results. This improves API performance significantly. Learn more about field optimization in our Fields Parameter Guide.
Example Response
{
"apiVersion": "1",
"page": 1,
"numPages": 3,
"pageSize": 100,
"count": 293,
"statistics": {
"listPrice": {
"min": 1,
"max": 14585000
}
},
"listings": [
{
"mlsNumber": "X12151945",
"listPrice": "1250000.00",
"address": {
"area": "Peterborough",
"city": "Trent Lakes",
"country": "Canada",
"district": null,
"majorIntersection": "Hwy 36 & Bessie Ave",
"neighborhood": "Trent Lakes",
"streetDirection": null,
"streetName": "Fire Route 123",
"streetNumber": "13",
"streetSuffix": "N/A",
"unitNumber": null,
"zip": "K0M 1A0",
"state": "Ontario",
"communityCode": null,
"streetDirectionPrefix": null
}
},
{
"mlsNumber": "X12196167",
"listPrice": "1895000.00",
"address": {
"area": "Grey County",
"city": "Grey Highlands",
"country": "Canada",
"district": null,
"majorIntersection": "Lakeview Rd off of Rd 63",
"neighborhood": "Grey Highlands",
"streetDirection": null,
"streetName": "Lakeview",
"streetNumber": "123",
"streetSuffix": "Rd",
"unitNumber": null,
"zip": "N0C 1M0",
"state": "Ontario",
"communityCode": null,
"streetDirectionPrefix": null
}
}
]
}
Note: Results are returned in order of relevance based on our proprietary algorithm, refined over years of optimization.
Step 2: Search Locations (Asynchronous)
Simultaneously search for matching locations using the /locations/autocomplete endpoint. This provides cities, neighborhoods, and areas from MLS data.
API Request
GET https://api.repliers.io/locations/autocomplete?search={user_input}
Filtering by Location Type
You can limit results to specific location types if needed:
GET https://api.repliers.io/locations/autocomplete?search=tor&type=city&type=neighborhood
This example excludes areas (counties/regions) and only returns cities and neighborhoods.
Example Response
{
"page": 1,
"numPages": 2,
"pageSize": 10,
"count": 20,
"locations": [
{
"resource": "Property:2381",
"locationId": "CAONCIREWPFEEZ",
"name": "Toronto",
"type": "city",
"map": {
"latitude": "43.653226",
"longitude": "-79.3831843"
},
"address": {
"state": "ON",
"country": "CA",
"city": "Toronto",
"area": "Toronto",
"neighborhood": ""
}
},
{
"resource": "Property:2381",
"locationId": "CAONNBZFGYQLJV",
"name": "Toronto Gore Rural Estate",
"type": "neighborhood",
"map": {
"latitude": "43.8003876",
"longitude": "-79.7014332"
},
"address": {
"state": "ON",
"country": "CA",
"city": "Brampton",
"area": "Peel",
"neighborhood": "Toronto Gore Rural Estate"
}
}
]
}
Step 3: Combine and Present Results
Concatenate the listings and locations results, then present them to users in organized categories (e.g., "Properties", "Cities", "Neighborhoods").
Implementation Best Practices
Performance Optimization
Debounce User Input Implement a debounce mechanism to prevent API calls on every keystroke. Recommended delay: 300-500ms after the user stops typing.
// Example debounce implementation
const debounce = (func, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(null, args), delay);
};
};
const debouncedSearch = debounce(performSearch, 300);
Field Selection Only request the fields you need in your fields parameter. This significantly improves response times and reduces bandwidth usage.
Concurrent Requests Execute both API calls (listings and locations) simultaneously using Promise.all() or similar concurrent execution patterns.
User Experience Considerations
Categorized Results Present results in clear categories:
Properties (from listings endpoint)
Cities (from locations endpoint)
Neighborhoods (from locations endpoint)
Areas (from locations endpoint, if included)
Visual Hierarchy Use clear visual distinctions between categories and include relevant details like:
Property addresses and prices
Location types (city, neighborhood, area)
Geographic context when helpful
Loading States Implement appropriate loading indicators while API requests are in progress.
Code Example
async function performAutocompleteSearch(query) {
if (query.length < 2) return; // Don't search for very short queries
try {
// Execute both searches concurrently
const [listingsResponse, locationsResponse] = await Promise.all([
fetch(`https://api.repliers.io/listings?search=${encodeURIComponent(query)}&searchFields=address.streetNumber,address.streetName,mlsNumber,address.city&fields=address.*,mlsNumber,listPrice`),
fetch(`https://api.repliers.io/locations/autocomplete?search=${encodeURIComponent(query)}`)
]);
const listings = await listingsResponse.json();
const locations = await locationsResponse.json();
// Combine and categorize results
const results = {
properties: listings.listings || [],
cities: locations.locations?.filter(loc => loc.type === 'city') || [],
neighborhoods: locations.locations?.filter(loc => loc.type === 'neighborhood') || [],
areas: locations.locations?.filter(loc => loc.type === 'area') || []
};
displayResults(results);
} catch (error) {
console.error('Search failed:', error);
// Handle error appropriately
}
}
// Apply debouncing
const debouncedSearch = debounce(performAutocompleteSearch, 300);
// Attach to search input
document.getElementById('search-input').addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});
Alternative Approaches
Hybrid Location Services
For markets where MLS location data doesn't align with local terminology, consider combining:
Option 1: Google Places Integration
// Use Google Places for locations, Repliers for listings
const [listingsResponse, placesResponse] = await Promise.all([
searchReplierListings(query),
searchGooglePlaces(query)
]);
Option 2: Mapbox Integration
// Use Mapbox for locations, Repliers for listings
const [listingsResponse, mapboxResponse] = await Promise.all([
searchReplierListings(query),
searchMapboxPlaces(query)
]);
This hybrid approach provides the comprehensive MLS listing data from Repliers while leveraging the superior location recognition capabilities of specialized mapping services.
Conclusion
This autocomplete implementation provides users with a comprehensive search experience that bridges the gap between specific property searches and general location exploration. By combining both endpoints and following the optimization practices outlined above, you can create a fast, intuitive search interface that helps users find exactly what they're looking for.
Updated on: 05/06/2025
Thank you!