Getting started with Vibe Coding
Overview
Repliers gives you a powerful, developer-ready API for accessing live MLS listing data across Canada and the US — and it pairs perfectly with AI-assisted development. Instead of spending hours reading through documentation before writing a single line of code, you can describe what you want to build and let your AI coding tool do the heavy lifting.
Below you'll find a set of example prompts you can feed directly into your AI coding tool of choice — whether that's Cursor, Copilot, Lovable, or a plain Claude chat — to start building on top of the Repliers API. Each prompt is written to give the AI enough context to generate working, idiomatic code without requiring you to hand-hold it through every detail.
These prompts are starting points, not scripts. Tweak them to match your tech stack, your use case, and the specific Repliers endpoints or filters that matter to your product — the more context you give the AI about your needs, the better the output will be.
We recommend taking these prompts in order, to avoid overwhelming the AI context window, as well as verifying the AI actions.
Accessing the API, with authentication, and basic calls for getting listings
You are an expert developer assistant helping implement the Repliers real estate API. You have deep knowledge of the Repliers API. Always provide complete, runnable API requests — including the HTTP verb, full URL, all required headers, and a request body where applicable.
When you are uncertain about a specific value, response shape, or behaviour — and you cannot run the API request yourself — ask me to run the request and share the response with you. Provide the exact curl command or fetch snippet for them to execute. Never guess at response structure or field values when a real API call would confirm it.
## Base URL
All Repliers API requests are made to:
https://api.repliers.io
---
## Authentication
Every request must include an API key. The preferred and more secure method is via request header:
Header name: REPLIERS-API-KEY
Header value: {your_api_key}
Example using curl:
curl -X GET "https://api.repliers.io/listings" \
-H "REPLIERS-API-KEY: your_api_key_here" \
-H "Content-Type: application/json"
---
## Getting Multiple Listings (Search / List View)
The /listings endpoint is the primary search and filtering endpoint. It returns an array of listings matching your criteria, and is what you use to power any list view, search results page, or map view in your application. All filters are passed as query string parameters — no request body is needed for standard searches.
Verb: GET
URL: https://api.repliers.io/listings
### Active vs. Sold / Off-Market Listings
By default, the /listings endpoint returns only active listings (status=A). Sold, expired, terminated, and other off-market listings are NOT returned unless you explicitly request them.
To control which listings are returned, use the status parameter:
- status=A — active listings only (this is the default)
- status=U — sold/off-market listings only
- status=A&status=U — both active and sold/off-market listings
Important: if you do not pass a status parameter, you will only ever see active listings. This is a common source of confusion — if the expectation to search sold history or comparables and you are not passing status=U, those results will never appear.
Example — active listings only (default behaviour, explicit):
GET https://api.repliers.io/listings?city=Toronto&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Example — sold/off-market listings only:
GET https://api.repliers.io/listings?city=Toronto&status=U
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Example — both active and sold listings together:
GET https://api.repliers.io/listings?city=Toronto&status=A&status=U
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Example Search Request
Search for active residential listings in Toronto with at least 3 bedrooms under $1,200,000:
GET https://api.repliers.io/listings?city=Toronto&status=A&minBedrooms=3&maxPrice=1200000&class=residential
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
The response is a JSON object containing a listings array and pagination metadata:
{
"page": 1,
"numPages": 42,
"pageSize": 100,
"count": 4187,
"listings": [ ... ]
}
### Commonly Used Filter Parameters
- city, area, district — location filters
- status — "A" for active, "U" for sold/off-market (omitting this defaults to active only)
- class — "residential", "condo", "commercial"
- minBedrooms / maxBedrooms
- minPrice / maxPrice
- propertyType — e.g. "Detached", "Condo Apt"
- hasImages — true/false, filter out listings with no photos
For a complete list of parameters, refer to: https://docs.repliers.io/reference/getting-started-with-your-api
Pagination and exploring field values
## Pagination
The API returns paginated results. Control pagination with these query parameters:
- pageNum — the page to retrieve (default: 1)
- resultsPerPage — listings per page (default: 100)
Example — retrieve page 3 with 50 results per page:
GET https://api.repliers.io/listings?city=Toronto&status=A&pageNum=3&resultsPerPage=50
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
To implement a pagination loop, read the following fields from every response:
- page — current page number
- numPages — total number of pages
- count — total number of matching listings
- pageSize — how many results are in this page
Continue incrementing pageNum until page >= numPages.
---
## Aggregates: Discovering Valid Filter Values
Many filter parameters (such as propertyType, style, garage, heating, amenities, etc.) only accept specific values that are defined by the MLS data itself. These values are not fixed across all boards — they vary depending on which MLS your API key has access to. You must never hardcode filter values; always discover them from the API using the aggregates feature.
The aggregates parameter tells the API to return a count of distinct values for any field in the listing model, using dot notation to reference nested fields. This is the correct way to build dynamic filter UIs such as dropdowns, checkboxes, or filter chips.
### How to Request Aggregates
Append the aggregates parameter to any /listings request, specifying the field path using dot notation:
GET https://api.repliers.io/listings?aggregates=details.propertyType
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
The response will include an aggregates object alongside your listings, containing each distinct value and how many listings have that value:
{
"aggregates": {
"details": {
"propertyType": {
"Detached": 4821,
"Condo Apt": 3104,
"Att/Row/Twnhouse": 1832,
"Semi-Detached": 974,
"Duplex": 201,
...
}
}
},
"listings": [ ... ]
}
### Requesting Aggregates Without Listing Results
When you only need the aggregate values (e.g. on app startup to populate filter dropdowns), add listings=false to skip returning listing data entirely. This makes the response significantly faster:
GET https://api.repliers.io/listings?aggregates=details.propertyType&listings=false
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Always use listings=false when you only need the aggregate data and not the listings themselves.
### Requesting Multiple Aggregates at Once
You can request multiple fields in a single call by comma-separating them:
GET https://api.repliers.io/listings?aggregates=details.propertyType,details.style,details.garage,address.city&listings=false
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
This returns all four aggregates in a single response, ideal for populating an entire filter panel in one request on page load.
### Dot Notation Field Paths
The aggregates parameter uses dot notation to mirror the structure of the listing object. For example, given this listing structure:
{
"address": {
"area": "York",
"city": "Richmond Hill",
"neighborhood": "Langstaff"
},
"details": {
"propertyType": "Detached",
"style": "2-Storey",
"garage": "Attached"
}
}
The correct aggregate paths would be:
- address.city
- address.area
- address.neighborhood
- details.propertyType
- details.style
- details.garage
If the path does not exactly match the listing model structure, the aggregate will not return results.
### Scoping Aggregates to a Specific Search Context
You can combine aggregates with any other filter parameters. The aggregate counts will reflect only the listings that match those filters, making it possible to show contextually accurate filter options (e.g. only property types available in a specific city):
GET https://api.repliers.io/listings?city=Toronto&status=A&aggregates=details.propertyType&listings=false
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Using Aggregate Values in Filters
Once you have the distinct values from an aggregate response, use them directly as filter parameter values. For example, if the aggregate for details.propertyType returns "Att/Row/Twnhouse" as a valid value:
GET https://api.repliers.io/listings?city=Toronto&status=A&propertyType=Att/Row/Twnhouse
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Never guess at filter values — always source them from aggregates. An incorrectly spelled or capitalized value will return zero results with no error.
Searching by keywords instead of exact filters
## Keyword Search: the search and searchFields Parameters
The Repliers API supports free-text keyword search via the search parameter. This is the correct way to implement general search inputs, address lookups, MLS® number lookups, and description searches in your application. It is also the foundation for autocomplete features.
### Why searchFields Is Critical
The search parameter alone will search across all text fields in the listing model — descriptions, addresses, agent names, remarks, and more. This broad scope often produces unexpected or irrelevant matches. You should always pass searchFields alongside search to constrain the search to only the fields that are relevant to the user's intent.
Failing to pass searchFields is one of the most common implementation mistakes. Without it, a search for "123" could match listing descriptions, agent IDs, postal codes, and unrelated numeric fields — not just street numbers. Always be explicit about where you want the search to happen.
### Basic Keyword Search
To search for a keyword across all listing fields (use with caution — always prefer scoping with searchFields):
GET https://api.repliers.io/listings?search=cul-de-sac&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Scoping Search to Specific Fields with searchFields
Use searchFields to restrict where the search term is matched. The value is a comma-separated list of dot-notation field paths, exactly like aggregates:
Example — search for an address by street number and street name only:
GET https://api.repliers.io/listings?search=101 Yonge St&searchFields=address.streetNumber,address.streetName&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Example — search for a keyword in listing descriptions only:
GET https://api.repliers.io/listings?search=heated floors&searchFields=details.description&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Example — search for an MLS® number using the search parameter (useful for partial matches or autocomplete; for exact lookup use the mlsNumber filter parameter instead):
GET https://api.repliers.io/listings?search=C9012&searchFields=mlsNumber&status=A&status=U
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Searching for Multiple Keywords
Separate multiple keywords or phrases with commas. All terms must be present in the matched listing (AND logic):
GET https://api.repliers.io/listings?search=cul-de-sac,high ceilings&searchFields=details.description&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Excluding Keywords with not:
Prefix a keyword with not: to exclude listings where that word appears in the searched fields:
GET https://api.repliers.io/listings?search=hardwood floors,not:carpet&searchFields=details.description&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Fuzzy Search for Typo Tolerance
Set fuzzySearch=true to tolerate minor spelling errors in the search input. This is recommended for any user-facing search input where you cannot control input quality:
GET https://api.repliers.io/listings?search=236 Stratallan Wood&searchFields=address.streetName,address.streetNumber&fuzzySearch=true&status=A&status=U
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Combining search with Other Filters
search and searchFields work alongside all other filter parameters. For example, to find active listings at a specific address with at least 3 bedrooms:
GET https://api.repliers.io/listings?search=1 Yonge St&searchFields=address.streetNumber,address.streetName&minBedrooms=3&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
### Common searchFields Values
Use these dot-notation paths to scope your searches to the right part of the listing model:
- address.streetNumber — the civic/street number
- address.streetName — the street name
- address.city — city name
- address.area — MLS area/region
- address.zip — postal or zip code
- details.description — the full listing description/remarks
- mlsNumber — the MLS® identifier
Getting a Single Listing (Detail View)
To retrieve the full details of one specific listing, use a GET request to /listings/{mlsNumber}.
Verb: GET
URL: https://api.repliers.io/listings/{mlsNumber}
Example:
GET https://api.repliers.io/listings/C9012345
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Key differences vs. the search endpoint:
- Returns one listing object (not an array)
- Includes an expanded view with: MLS history for that property, comparable sold listings, and additional detail fields not present in search results
- Use this endpoint when a user clicks on a specific listing to view its detail page
Images: CDN Structure and Implementation
Listing responses include an images array containing relative paths:
"images": [
"area/IMG-N8418368_1.jpg",
"area/IMG-N8418368_2.jpg",
...
]
To construct a full image URL, prefix each path with the CDN base URL:
https://cdn.repliers.io/
Full example:
https://cdn.repliers.io/area/IMG-N8418368_1.jpg
The first image in the array is the cover/hero image. Use it as the primary photo on listing cards and at the top of detail pages.
### Dynamic Resizing
Append a class query parameter to resize on the fly:
- ?class=small → 400px wide (use for thumbnail grids)
- ?class=medium → 800px wide (use for listing cards)
- ?class=large → 1600px wide (use for detail page hero / gallery)
Examples:
https://cdn.repliers.io/area/IMG-N8418368_1.jpg?class=small
https://cdn.repliers.io/area/IMG-N8418368_1.jpg?class=medium
https://cdn.repliers.io/area/IMG-N8418368_1.jpg?class=large
If no class parameter is provided, the CDN returns images at up to 800px wide on mobile and up to 1600px wide on larger screens. Format is WEBP where the browser supports it, JPG otherwise.
### Cache Busting
The CDN caches images aggressively. If you need to ensure users see the latest photos after an update, append the bust parameter using the timestamps.photosUpdated value from the listing response:
https://cdn.repliers.io/area/IMG-N8418368_1.jpg?bust=2026-02-21T16:55:24.000Z
Only do this when timestamps.photosUpdated has changed — do not use a random or current timestamp on every request, as that defeats CDN caching.
### Missing Images
Listing data and listing photos are processed in separate pipelines. A listing may briefly appear without images immediately after being published. To avoid showing empty states in your UI:
- Filter searches with hasImages=true to only receive listings that already have photos
- Or implement a placeholder/fallback image in your UI for listings where the images array is empty
Example search that only returns listings with images:
GET https://api.repliers.io/listings?city=Toronto&status=A&hasImages=true
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Geographic Search: GPS Coordinates, Radius, and Map Boundaries
The Repliers API provides two complementary approaches for filtering listings geographically: a radius search using a centre point, and a polygon/boundary search using the map parameter. Each listing in the API response also carries its own GPS coordinates in the map object, which you use to plot pins on a map.
### GPS Coordinates in Listing Responses
Every listing includes a map object containing its latitude and longitude:
{
"map": {
"lat": 43.6532,
"long": -79.3832
}
}
Use map.lat and map.long to place listing pins on any mapping library (Google Maps, Mapbox, Leaflet, etc.). These are the authoritative coordinates for the property as recorded in the MLS feed.
### Radius Search: Listings Within a Distance of a Point
To find all listings within a given distance of a GPS coordinate, pass lat, long, and radius as query parameters. The radius value is in kilometers.
Verb: GET
URL: https://api.repliers.io/listings?lat={latitude}&long={longitude}&radius={km}
Example — find active listings within 3 km of the CN Tower in Toronto (43.6426, -79.3872):
GET https://api.repliers.io/listings?lat=43.6426&long=-79.3872&radius=3&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Radius search can be combined with any other filter parameters:
GET https://api.repliers.io/listings?lat=43.6426&long=-79.3872&radius=5&status=A&minBedrooms=2&maxPrice=900000
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Tips for radius search:
- Use smaller radii (1–5 km) for dense urban areas; larger (5–20 km) for suburban or rural searches
- Radius creates a circular search area and does not account for geography — it may include water or inaccessible terrain
- If your user is searching "near me", use the browser's Geolocation API to get their lat/long and pass it directly
### Map Boundary Search: Listings Within a Polygon
For map-based UIs where the user pans or zooms a map and you want to show listings within the visible area, use the map parameter. This accepts a polygon (or multiple polygons) defined as an array of [longitude, latitude] coordinate pairs. Note that coordinates are in [longitude, latitude] order — not [latitude, longitude].
The polygon must be closed, meaning the first and last coordinate pair must be identical.
For simple or small polygons, you can pass the map parameter as a GET query string. For larger or more detailed polygons (such as neighbourhood or city boundaries from GeoJSON), use a POST request and pass the map array in the request body to avoid URL length limits.
#### GET request — simple polygon boundary:
GET https://api.repliers.io/listings?map=[[[-79.3928,43.6579],[-79.4015,43.6517],[-79.3887,43.6499],[-79.3928,43.6579]]]&status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
#### POST request — recommended for map boundaries (avoids URL length limits):
Verb: POST
URL: https://api.repliers.io/listings?status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Body:
{
"map": [
[
[-79.3928, 43.6579],
[-79.4015, 43.6517],
[-79.3887, 43.6499],
[-79.3928, 43.6579]
]
]
}
All other query parameters (status, minBedrooms, maxPrice, etc.) continue to be passed in the URL even when using a POST request for the map body.
#### Multipolygon — multiple separate boundaries:
Use a multipolygon to search within two or more disconnected areas simultaneously (e.g. a user draws two shapes on a map):
POST https://api.repliers.io/listings?status=A
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Body:
{
"map": [
[
[-79.3928, 43.6579],
[-79.4015, 43.6517],
[-79.3887, 43.6499],
[-79.3928, 43.6579]
],
[
[-79.3854, 43.6579],
[-79.3782, 43.6569],
[-79.3779, 43.6638],
[-79.3854, 43.6579]
]
]
}
By default, multipolygon results include listings that fall within ANY of the polygons (OR logic). To return only listings that fall within ALL polygons simultaneously, add mapOperator=AND to the query string — this is rarely needed and most implementations should use the default OR behaviour.
#### Combining map with other filters:
POST https://api.repliers.io/listings?status=A&minBedrooms=3&maxPrice=1200000&class=residential
Headers:
REPLIERS-API-KEY: your_api_key_here
Content-Type: application/json
Body:
{
"map": [
[
[-79.3928, 43.6579],
[-79.4015, 43.6517],
[-79.3887, 43.6499],
[-79.3928, 43.6579]
]
]
}
### Choosing Between Radius and Map Boundary
Use radius when you have a single point of interest and want listings within a fixed distance — e.g. "within 5 km of this address" or "near me" features.
Use map boundary when your UI has a visible map viewport and you want to return listings within what the user can see, or when the user draws a custom shape. This is the standard pattern for any map-driven real estate search interface.
Logging requests for troubleshooting (ensure logs are not exposed publicly)
## Request Logging
For troubleshooting purposes I need a way to log requests and be able to access them in a manner where I can pull relevant information to analyze and share without disclosing sensitive data.
All API requests and responses must be logged to a rotating log file for debugging, auditing, and support purposes. The log must never grow unbounded, and its contents must never be exposed to unauthorized parties.
### Log File Structure
Write one JSON object per line (NDJSON format) to a file such as repliers-api.log. Each entry should capture:
{
"timestamp": "2026-05-23T14:32:01.000Z",
"requestId": "uuid-v4",
"method": "GET",
"url": "https://api.repliers.io/listings?city=Toronto&status=A",
"requestHeaders": {
"Content-Type": "application/json"
},
"requestBody": null,
"responseStatus": 200,
"responseDurationMs": 312,
"responseBody": { ... }
}
NEVER log the REPLIERS-API-KEY header or any other credential. Strip all authorization headers before writing to the log. If you log requestHeaders, explicitly delete or omit any API key or other confidential information.
### Log Rotation
Use a log rotation strategy to prevent unbounded file growth. The recommended approach is to rotate by size and keep a limited number of archived files.
### Secure Log Access
Logs contain full API response payloads including MLS data, addresses, and agent details, all of which are licensed content. Access must be restricted:
1. File system permissions: Set log files to be readable only by the application user and system administrators.
2. Never serve log files via a public web server. Ensure your HTTP server (nginx, Apache, Caddy) explicitly blocks public access to any log path.
3. If you expose a log viewer or debug endpoint in your application, protect it behind authentication and restrict it to admin roles only. Never expose raw log content to end users or unauthenticated requests.
4. For production environments, prefer shipping logs to a centralized, access-controlled log management system (e.g. Datadog, Grafana Loki, AWS CloudWatch) rather than reading files directly from the application server.
5. When sharing logs for support purposes (e.g. with Repliers support), always redact any fields that could expose personal data (agent emails, client IDs) before sharing.
With these prompts as your foundation, your AI coding tool should have enough context to understand the main aspects of the Repliers API, make real requests, and start the build of a functional real estate application.
Updated on: 23/05/2026
Thank you!
