By Sagar Shankaran, Founder of CallSphere
Build an AI assistant for real estate agents that searches property listings, performs comparative market analysis, generates valuations, and prepares transaction documents.
Key takeaways
Real estate agents juggle property searches, market analysis, client communication, document preparation, and scheduling — often for dozens of clients simultaneously. An AI assistant can handle the data-intensive tasks: searching listings against buyer criteria, running comparative market analyses, generating property valuations, and drafting transaction documents. This frees agents to focus on relationship building and negotiation.
Connect to listing data and implement intelligent filtering.
sequenceDiagram
autonumber
participant Caller as Caller
participant Agent as CallSphere Agent
participant API as CRM API
participant DB as CRM Database
participant Webhook as Webhook Listener
Caller->>Agent: Inbound call begins
Agent->>Agent: STT plus intent detection
Agent->>API: Lookup contact by phone
API->>DB: Read contact record
DB-->>API: Contact and history
API-->>Agent: Personalized context
Agent->>API: Create call activity
Agent->>API: Update deal stage
API->>Webhook: Outbound webhook fires
Webhook-->>Agent: Confirmed
Agent->>Caller: Spoken confirmation
from pydantic import BaseModel
from datetime import date
class PropertyListing(BaseModel):
mls_id: str
address: str
city: str
state: str
zip_code: str
price: float
bedrooms: int
bathrooms: float
sqft: int
lot_size: float # acres
year_built: int
property_type: str # "single_family", "condo", "townhouse"
days_on_market: int
listing_date: date
features: list[str]
description: str
class BuyerCriteria(BaseModel):
min_price: float = 0
max_price: float = float("inf")
min_bedrooms: int = 0
min_bathrooms: float = 0
min_sqft: int = 0
property_types: list[str] = []
zip_codes: list[str] = []
must_have_features: list[str] = []
max_days_on_market: int | None = None
def search_properties(
listings: list[PropertyListing], criteria: BuyerCriteria
) -> list[PropertyListing]:
"""Filter listings against buyer criteria."""
results = []
for listing in listings:
if listing.price < criteria.min_price:
continue
if listing.price > criteria.max_price:
continue
if listing.bedrooms < criteria.min_bedrooms:
continue
if listing.bathrooms < criteria.min_bathrooms:
continue
if listing.sqft < criteria.min_sqft:
continue
if (
criteria.property_types
and listing.property_type not in criteria.property_types
):
continue
if (
criteria.zip_codes
and listing.zip_code not in criteria.zip_codes
):
continue
if criteria.max_days_on_market is not None:
if listing.days_on_market > criteria.max_days_on_market:
continue
results.append(listing)
return sorted(results, key=lambda x: x.price)
Beyond simple filtering, the agent ranks properties using the LLM to evaluate lifestyle fit.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent for real estate in your browser — 60 seconds, no signup.
from openai import OpenAI
client = OpenAI()
class RankedProperty(BaseModel):
mls_id: str
match_score: float # 0.0 to 1.0
strengths: list[str]
concerns: list[str]
summary: str
class PropertyRanking(BaseModel):
ranked_properties: list[RankedProperty]
def rank_properties(
properties: list[PropertyListing],
buyer_notes: str,
) -> PropertyRanking:
"""Rank properties based on buyer preferences and lifestyle."""
listings_text = "\n\n".join(
f"MLS# {p.mls_id}: {p.address}, {p.city}\n"
f"${p.price:,.0f} | {p.bedrooms}bd/{p.bathrooms}ba | "
f"{p.sqft:,} sqft | Built {p.year_built}\n"
f"Features: {', '.join(p.features[:10])}\n"
f"Description: {p.description[:300]}"
for p in properties[:15]
)
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"You are an experienced real estate agent. Rank "
"these properties for the buyer based on their "
"stated preferences and lifestyle needs. Consider "
"value, condition, location, and feature alignment."
),
},
{
"role": "user",
"content": (
f"Buyer Notes: {buyer_notes}\n\n"
f"Properties:\n{listings_text}"
),
},
],
response_format=PropertyRanking,
)
return response.choices[0].message.parsed
CMA is the foundation of property valuation. The agent finds comparable sales and estimates value.
class ComparableSale(BaseModel):
address: str
sale_price: float
sale_date: date
sqft: int
bedrooms: int
bathrooms: float
price_per_sqft: float
adjustments: dict[str, float] # {"pool": +5000, "age": -3000}
adjusted_price: float
class CMAReport(BaseModel):
subject_address: str
comparables: list[ComparableSale]
estimated_value: float
value_range_low: float
value_range_high: float
price_per_sqft_avg: float
market_trend: str # "appreciating", "stable", "declining"
confidence: str
def run_cma(
subject: PropertyListing,
recent_sales: list[PropertyListing],
) -> CMAReport:
"""Run a comparative market analysis."""
# Find comparable properties
comps = []
for sale in recent_sales:
if sale.mls_id == subject.mls_id:
continue
# Filter by proximity criteria
sqft_diff = abs(sale.sqft - subject.sqft) / subject.sqft
bed_diff = abs(sale.bedrooms - subject.bedrooms)
if sqft_diff > 0.25 or bed_diff > 1:
continue
price_per_sqft = sale.price / sale.sqft if sale.sqft else 0
# Calculate adjustments
adjustments = {}
sqft_adjustment = (subject.sqft - sale.sqft) * (
price_per_sqft * 0.5
)
adjustments["sqft_difference"] = round(sqft_adjustment, 0)
age_diff = sale.year_built - subject.year_built
adjustments["age_difference"] = round(age_diff * 500, 0)
total_adjustment = sum(adjustments.values())
adjusted = sale.price + total_adjustment
comps.append(
ComparableSale(
address=sale.address,
sale_price=sale.price,
sale_date=sale.listing_date,
sqft=sale.sqft,
bedrooms=sale.bedrooms,
bathrooms=sale.bathrooms,
price_per_sqft=round(price_per_sqft, 2),
adjustments=adjustments,
adjusted_price=round(adjusted, 0),
)
)
comps = sorted(
comps,
key=lambda c: abs(c.sqft - subject.sqft),
)[:5]
if comps:
adjusted_prices = [c.adjusted_price for c in comps]
avg_value = sum(adjusted_prices) / len(adjusted_prices)
avg_ppsf = sum(c.price_per_sqft for c in comps) / len(comps)
else:
avg_value = subject.price
avg_ppsf = subject.price / subject.sqft if subject.sqft else 0
return CMAReport(
subject_address=subject.address,
comparables=comps,
estimated_value=round(avg_value, 0),
value_range_low=round(avg_value * 0.95, 0),
value_range_high=round(avg_value * 1.05, 0),
price_per_sqft_avg=round(avg_ppsf, 2),
market_trend="stable",
confidence="high" if len(comps) >= 3 else "medium",
)
Generate property briefs and offer documents.
def generate_property_brief(
listing: PropertyListing, cma: CMAReport
) -> str:
"""Generate a client-facing property brief."""
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"Write a professional property brief for a buyer "
"client. Include property highlights, market "
"position, value assessment, and recommendation. "
"Keep it concise and actionable."
),
},
{
"role": "user",
"content": (
f"Property: {listing.address}, {listing.city}\n"
f"Asking Price: ${listing.price:,.0f}\n"
f"Specs: {listing.bedrooms}bd / "
f"{listing.bathrooms}ba / {listing.sqft:,} sqft\n"
f"Year Built: {listing.year_built}\n"
f"Days on Market: {listing.days_on_market}\n"
f"Features: {', '.join(listing.features)}\n\n"
f"CMA Estimated Value: "
f"${cma.estimated_value:,.0f}\n"
f"Value Range: ${cma.value_range_low:,.0f} - "
f"${cma.value_range_high:,.0f}\n"
f"Avg Price/SqFt: ${cma.price_per_sqft_avg:.0f}\n"
f"Market Trend: {cma.market_trend}"
),
},
],
)
return response.choices[0].message.content
Most MLS systems expose data through RETS (Real Estate Transaction Standard) or the newer RESO Web API. Services like Bridge Interactive, Spark Platform, or ListHub provide normalized API access across multiple MLS systems. You will need MLS board membership or a data license agreement to access listing data.
Still reading? Stop comparing — try CallSphere live.
See the real estate AI agent handle a real call — complete, industry-specific, and live in your browser. No signup.
AI CMAs are useful for quick market positioning but should not replace licensed appraisals for lending purposes. The accuracy depends heavily on comparable data quality and quantity. In markets with many similar properties and recent sales, AI valuations can be within 3-5% of appraised values. In unique or rural properties, the error margin increases significantly.
Commercial real estate requires different valuation methods (income capitalization, discounted cash flow) and data sources (CoStar, LoopNet). You would extend the agent with commercial-specific models that factor in cap rates, NOI, tenant quality, and lease terms rather than residential comparables.
#RealEstate #PropertyValuation #MLSIntegration #DocumentGeneration #AIAgent #AgenticAI #LearnAI #AIEngineering

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
How estate agents and property managers in Luxembourg City and across the Grand Duchy use CallSphere to capture multilingual viewing and enquiry calls 24/7, GDPR compliant.
Market data on automotive and real-estate lead handling across South Korea, Taiwan and Hong Kong, and how CallSphere AI agents answer every enquiry 24/7 in local languages — PIPA, PDPA and PDPO aware.
Azerbaijani law firms, accountants, and real estate agencies lose clients to unanswered calls. CallSphere books consultations 24/7 in Azerbaijani, Russian, and English across Baku and Ganja.
San Pedro on Ambergris Caye runs on divers and property buyers who inquire from every time zone. See how CallSphere AI voice + chat agents answer reef-trip bookings and real estate leads 24/7 in English and Spanish.
Grenada real estate agencies and Citizenship-by-Investment advisors use CallSphere AI voice and chat agents to answer high-value international enquiries instantly, qualify investors, and never miss a lead.
American real estate agents and property managers lose leads and tenants to unanswered calls. See how CallSphere AI voice and chat agents capture every inquiry 24/7.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.