Building CMAs with the Repliers API: Complete Implementation Guide
Introduction
This guide walks you through building a Comparative Market Analysis (CMA) tool using the Repliers API. CMAs are essential for real estate professionals to help clients understand property values and market conditions. By the end of this guide, you'll have a complete understanding of how to create professional, data-driven CMAs.
What Makes a Good CMA?
A comprehensive CMA should include the following components:
1. Estimated Property Value
- Current estimated value with high-low range
- Historical value trends (typically 24 months)
- Confidence indicator to set proper expectations
2. Sold Comparables
- Recent nearby properties that have sold (typically within 90 days)
- Ability to exclude irrelevant comparables from the report
3. Active Listings
- Nearby properties currently for sale
- Ability to exclude listings as needed
4. Market Statistics
- Median/average sold prices over time
- Days on market trends
- Month-over-month analysis to identify market direction
Implementation Guide
Step 1: Collect Property Address
Start by prompting the user to input the subject property's address. You'll need to collect:
- Street number
- Street name
- Postal/ZIP code
Example address: 30 South Belair Dr, Vaughan, L4H2R5
Step 2: Check for MLS History
Before asking users to manually enter property details, check if the property has MLS history. This saves time and ensures accuracy.
Endpoint: GET https://api.repliers.io/listings
Example Request:
GET https://api.repliers.io/listings?streetNumber=30&streetName=South%20Belair&zip=L4H2R5&status=U&status=A&fields=details.propertyType,details.style,details.numBedrooms,details.numBathrooms,details.basement1,details.numGarageSpaces,lot.depth,lot.width,condominium.fees.maintenance,taxes.annualAmount,details.sqft,details.yearBuilt,address,soldDate,map
Why these fields? These are the essential attributes needed to:
- Request an estimate from Repliers
- Find comparable listings
- Display property information
Response When History Exists:
{
"apiVersion": "1",
"page": 1,
"numPages": 1,
"pageSize": 100,
"count": 3,
"statistics": {
"listPrice": {
"min": 419900,
"max": 788800
}
},
"listings": [
{
"soldDate": "2015-08-17T12:00:00.000Z",
"address": {
"area": "York",
"city": "Vaughan",
"streetName": "South Belair",
"streetNumber": "30",
"streetSuffix": "Dr",
"zip": "L4H2R5",
"state": "Ontario"
},
"details": {
"basement1": "Unfinished",
"numBathrooms": "3",
"numBedrooms": "4",
"numGarageSpaces": "2.0",
"propertyType": "Detached",
"style": "2-Storey"
},
"lot": {
"depth": "111.58",
"width": "38.98"
},
"taxes": {
"annualAmount": "4929.26"
}
}
]
}
Response When No History Exists:
{
"apiVersion": "1",
"page": 1,
"numPages": 0,
"pageSize": 100,
"count": 0,
"statistics": {
"listPrice": {
"min": null,
"max": null
}
},
"listings": []
}
UX Best Practices:
1. Select the Most Recent Listing
When multiple listings are returned, use the one with the most recent soldDate as it likely has the most accurate and up-to-date property attributes.
2. Display Editable Property Details
Show the property attributes in a form that allows users to update values. For example:
- Property taxes may have increased since the last transaction
- Renovations may have changed bathrooms, square footage, or quality
- Basement finishing status may have changed
3. Handle Missing History Gracefully
If no history exists (count: 0), prompt the user to manually enter property details.
Step 3: Generate Property Estimate
Once property details are confirmed, request an estimate from Repliers.
Prerequisites: Your account needs access to the Repliers estimates add-on. See the AI-Powered Property Estimates Guide for more information.
Endpoint: POST https://api.repliers.io/estimates
Request Body Structure:
The request body mirrors the listing object structure from the history response:
{
"overallQuality": "average",
"address": {
"area": "York",
"city": "Vaughan",
"district": "Vaughan",
"streetName": "South Belair",
"streetNumber": "30",
"streetSuffix": "Dr",
"zip": "L4H2R5",
"state": "Ontario"
},
"map": {
"latitude": "43.824520",
"longitude": "-79.621904",
"point": "POINT (-79.621904 43.824520)"
},
"details": {
"basement1": "Unfinished",
"numBathrooms": "3",
"numBedrooms": "4",
"numGarageSpaces": "2.0",
"propertyType": "Detached",
"style": "2-Storey"
},
"lot": {
"depth": "111.58",
"width": "38.98"
},
"taxes": {
"annualAmount": "4929.26"
}
}
Note: Don't worry about including extra fields—they'll simply be ignored if not needed for the estimate.
Understanding overallQuality
The overallQuality field defines the property's renovation quality:
- poor: Significant deferred maintenance or dated finishes
- below average: Functional but dated or basic finishes
- average (default): Standard finishes typical for the area
- above average: Recently renovated with high-end finishes
- excellent: Magazine-quality finishes with premium materials
This field also affects comparable searches (explained later).
Response:
{
"estimateId": 123,
"estimate": 508597.59,
"estimateHigh": 577311.20,
"estimateLow": 439883.98,
"confidence": 0.135,
"history": {
"mth": {
"2024-12": { "value": 508597.59 },
"2024-11": { "value": 508491.09 },
"2024-10": { "value": 511354.31 },
"2023-01": { "value": 484527.66 }
}
}
}
Key Response Fields:
- estimate: Current property value
- estimateHigh / estimateLow: Value range
- confidence: Confidence score (lower = more confident)
- history: 24 months of historical values for trend visualization
Step 4: Find Sold Comparables
Display recently sold properties with similar characteristics to support the estimate.
Recommended Criteria:
- Sold within the past 90 days
- Similar property attributes (type, bedrooms, bathrooms)
- Sold within the estimate range
- Within a reasonable radius (5km is a good starting point)
Endpoint: GET https://api.repliers.io/listings
Example Request:
GET https://api.repliers.io/listings?status=U&lastStatus=Sld&lat=43.824520&long=-79.621904&radius=5&minSoldDate=2025-11-07&maxSoldDate=2026-02-08&fields=imageInsights.summary.quality.qualitative.overall,mlsNumber,soldDate,soldPrice,details.numBedrooms,images[0],details.numBathrooms,details.propertyType,details.style&propertyType=Detached&minBedrooms=4&minBathrooms=4&minSoldPrice=1300000&maxSoldPrice=1600000&type=sale
Query Parameter Breakdown:
status=U&lastStatus=Sld: Unavailable listings that soldlat&long: Subject property coordinatesradius=5: Search within 5kmminSoldDate&maxSoldDate: Date range (90 days)propertyType,minBedrooms,minBathrooms: Match subject propertyminSoldPrice&maxSoldPrice: Within estimate rangefields: Specific data to return (including quality rating)
Response:
{
"count": 14,
"listings": [
{
"mlsNumber": "N12703668",
"soldPrice": "1448000.00",
"soldDate": "2026-01-30T00:00:00.000Z",
"details": {
"numBathrooms": "3",
"numBedrooms": "4",
"propertyType": "Detached",
"style": "2-Storey"
},
"imageInsights": {
"summary": {
"quality": {
"qualitative": {
"overall": "average"
}
}
}
},
"images": ["IMG-N12703668_1.jpg"]
}
]
}
UX Best Practices:
1. Provide Filter Controls
Allow users to refine comparable criteria:
- ☐ Same property type
- ☐ Same style
- ☐ Same bedrooms
- ☐ Same bathrooms
This flexibility helps when there are too many or too few comparables.
2. Adjustable Time Frames
- 30 days if the market is very active
- 90 days (recommended default)
- 120+ days if inventory is limited
3. Display Quality Ratings
Group comparables by quality (excellent, above average, average) to help users understand value differences.
4. Show Property Images
Display the first image to give visual context.
Step 5: Find Active Listings
Show currently available properties for reference.
Endpoint: Same as sold comparables, but change status parameters
Example Request:
GET https://api.repliers.io/listings?status=A&lastStatus=New&lat=43.824520&long=-79.621904&radius=5&fields=mlsNumber,listPrice,details.numBedrooms,images[0],details.numBathrooms,details.propertyType,details.style&propertyType=Detached&minBedrooms=4&type=sale
Key Difference: status=A&lastStatus=New returns active listings instead of sold ones.
Step 6: Allow Exclusions
Real estate professionals often need to exclude listings that aren't truly comparable.
Excluding a Listing:
Add mlsNumber=not: followed by the MLS number to exclude:
&mlsNumber=not:N12703668
Multiple Exclusions:
Chain exclusions with additional mlsNumber=not: parameters:
&mlsNumber=not:N12703668&mlsNumber=not:N12640284
UX Best Practices:
1. Easy Removal
Add a "Remove from report" button/link on each comparable
2. Undo Capability
Allow users to re-include accidentally excluded listings with an "Include in report" option
3. Visual Indication
Clearly show which listings have been excluded (e.g., grayed out with a "Excluded" badge)
Step 7: Display Market Statistics
Show market trends to provide context for the estimate.
Endpoint: GET https://api.repliers.io/listings
Example Request:
GET https://api.repliers.io/listings?status=U&lastStatus=Sld&lat=43.824520&long=-79.621904&radius=5&minSoldDate=2024-02-07&propertyType=Detached&minBedrooms=4&minBathrooms=4&type=sale&listings=false&statistics=grp-mth,med-soldPrice,avg-daysOnMarket
Key Parameters:
listings=false: Speeds up request by skipping listing data (we only need statistics)statistics=grp-mth,med-soldPrice,avg-daysOnMarket:- Group by month
- Calculate median sold price
- Calculate average days on market
minSoldDate=2024-02-07: Go back 24 months
Response:
{
"count": 910,
"statistics": {
"soldPrice": {
"med": 1629444,
"mth": {
"2024-02": { "med": 1640000, "count": 40 },
"2024-03": { "med": 1739000, "count": 56 },
"2025-12": { "med": 1800000, "count": 21 },
"2026-01": { "med": 1466500, "count": 20 }
}
},
"daysOnMarket": {
"avg": 29,
"mth": {
"2024-02": { "avg": 23, "count": 40 },
"2024-03": { "avg": 19, "count": 56 },
"2026-01": { "avg": 44, "count": 20 }
}
}
}
}
Visualizing Market Trends:
Use this data with charting libraries (Chart.js, Recharts, D3.js, etc.) to create:
1. Median Price Trend Chart
Shows whether the market is appreciating or depreciating
2. Days on Market Trend
Indicates market speed (seller's vs buyer's market)
3. Transaction Volume
The count field shows market activity levels
Advanced Features
Using Quality Filters for Better Comparables
When searching for comparables, you can filter by quality to match the subject property:
&overallQuality=above average
This helps ensure you're comparing properties with similar renovation levels.
Additional Statistics Available
Repliers supports dozens of statistics beyond median price and days on market. Refer to the Real-Time Market Statistics Guide for complete options.
Finding Comparables by Address
For a deeper dive into comparable searches, see the Finding Comparables by Address Guide.
Complete Workflow Summary
- Collect Address → User inputs street number, name, and postal code
- Check History → GET
/listingsto find previous transactions - Confirm Details → Display property attributes in editable form
- Generate Estimate → POST
/estimateswith property details - Find Sold Comps → GET
/listingswith sold status and filters - Find Active Listings → GET
/listingswith active status - Allow Exclusions → Support removing irrelevant listings
- Show Statistics → GET
/listingswith statistics parameters - Visualize Data → Create charts and present the complete CMA
Best Practices for Production
Performance Optimization
- Cache property history to avoid redundant API calls
- Use
listings=falsewhen only statistics are needed - Request only necessary fields to reduce payload size
Error Handling
- Handle cases where no history exists
- Manage empty comparable searches gracefully
- Validate address inputs before API calls
User Experience
- Show loading states during API calls
- Provide clear feedback when no comparables are found
- Allow refinement of search criteria
- Enable comparison exclusion and restoration
Data Presentation
- Display confidence levels clearly
- Show historical value trends visually
- Group comparables by quality or date
- Highlight key statistics with visual indicators
Getting Started
To start building CMAs with the Repliers API:
- Ensure your account has the Estimates add-on enabled
- Review the Estimates Implementation Guide
- Implement the workflow outlined in this guide
- Test with various property types and markets
For additional support, refer to Repliers documentation or contact their support team.
Updated on: 17/02/2026
Thank you!
