Articles on: Vibe Coding

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

Was this article helpful?

Share your feedback

Cancel

Thank you!