Use cases at a glance
As your real estate portfolio grows, you need a single source of truth for your total net worth and equity position. Manually tracking 5, 10, or 20 properties across email spreadsheets and broker statements is error-prone and time-consuming. An automated portfolio agent pulls Zestimates monthly, computes equity on each property, alerts on significant value changes, and generates a dashboard showing your aggregate wealth.
Monthly portfolio snapshot
Zestimate pull on the 1st of each month. Track portfolio value over time.
Equity by property
Current Zestimate minus mortgage balance = equity. See which properties are your best performers.
Aggregate equity and net worth
Sum all properties. Track total portfolio equity and net worth month-over-month.
Value change alerts
Alert if any property drops >5% in value (or your threshold) in 30 days. Investigate outliers.
Annual appreciation tracking
Compare current values to 12 months ago. Calculate annual appreciation rate per property and portfolio-wide.
Gross yield and cap rate
Combine rental income (if applicable) with property value to track yield and cap rate over time.
Portfolio configuration file
Define your portfolio in a YAML file. Store it locally (not in git). This is your source of truth for properties and loan balances.
portfolio:
properties:
- id: "prop_001"
address: "123 Oak Street, Austin, TX 78704"
zpid: 12345678
purchase_price: 450000
purchase_date: "2020-06-15"
mortgage_balance: 380000
monthly_rent: 2800
notes: "Rented since 2021. Recent HVAC upgrade."
- id: "prop_002"
address: "456 Elm Avenue, Austin, TX 78723"
zpid: 87654321
purchase_price: 550000
purchase_date: "2019-03-10"
mortgage_balance: 420000
monthly_rent: 3200
notes: "Performing well. Strong tenant."
- id: "prop_003"
address: "789 Pine Court, Denver, CO 80202"
zpid: 11223344
purchase_price: 600000
purchase_date: "2022-01-20"
mortgage_balance: 540000
monthly_rent: null
notes: "Held for appreciation. No rental income yet."
Update mortgage balances quarterly (or whenever you get a loan statement). The agent reads this file, pulls Zestimates for each zpid, and computes equity = zestimate - mortgage_balance.
Portfolio snapshot agent
Here's the agent configuration for monthly portfolio snapshots:
---
name: portfolio-valuation-snapshot
schedule: "0 9 1 * *" # Monthly, 1st day at 9 AM
tools:
- zillow-rapidapi
config:
portfolio_file: "/data/portfolio.yaml"
storage:
type: "json_file"
path: "/data/portfolio_snapshots.json"
retention_days: 1825 # 5 years
alerts:
value_change_pct: 5 # Alert if >5% change in 30 days
output:
channels: ["slack", "email"]
---
job: |
portfolio = load_portfolio_yaml(config.portfolio_file)
current_snapshot = {
timestamp: now(),
properties: []
}
for prop in portfolio.properties:
zestimate_data = await zillow_rapidapi.get_zestimate(prop.zpid)
equity = zestimate_data.zestimate - prop.mortgage_balance
equity_pct = (equity / zestimate_data.zestimate) * 100
prop_record = {
id: prop.id,
address: prop.address,
zestimate: zestimate_data.zestimate,
mortgage_balance: prop.mortgage_balance,
equity: equity,
equity_pct: equity_pct,
monthly_rent: prop.monthly_rent
}
current_snapshot.properties.append(prop_record)
# Check for significant value changes
previous_snapshot = load_previous_snapshot()
for prop in current_snapshot.properties:
if previous_snapshot exists:
old_value = find_prop_in_snapshot(prop.id, previous_snapshot).zestimate
change_pct = ((prop.zestimate - old_value) / old_value) * 100
if abs(change_pct) >= config.alerts.value_change_pct:
alert("Property {prop.address} value changed {change_pct:+.1f}%")
# Save snapshot
save_snapshot(current_snapshot, config.storage.path)
# Generate and send report
report = generate_portfolio_report(current_snapshot)
send_report(report, config.output.channels)
Equity dashboard and metrics
Your monthly report should include an equity dashboard table:
| Property | Zestimate | Mortgage | Equity | Equity % | Monthly Rent | Gross Yield |
|---|---|---|---|---|---|---|
| 123 Oak St, Austin | $525,000 | $378,000 | $147,000 | 28.0% | $2,800 | 6.4% |
| 456 Elm Ave, Austin | $610,000 | $415,000 | $195,000 | 32.0% | $3,200 | 6.3% |
| 789 Pine Ct, Denver | $680,000 | $535,000 | $145,000 | 21.3% | — | 0.0% |
| TOTAL | $1,815,000 | $1,328,000 | $487,000 | 26.8% | $6,000 | 3.96% |
This table shows you at a glance: which properties have the most equity, which are your best renters, and your aggregate yield.
Value change alerts
If any single property's Zestimate changes by >5% (configurable) in 30 days, alert you to investigate:
if abs(monthly_change_pct) > 5:
direction = "up" if monthly_change_pct > 0 else "down"
alert_message = f"""
Alert: {prop.address} value {direction}
Previous Zestimate (Mar 1): ${prev_zestimate:,.0f}
Current Zestimate (Apr 1): ${curr_zestimate:,.0f}
Change: {monthly_change_pct:+.1f}% (${change_dollars:+,.0f})
Possible causes:
- Major data error (check Zillow directly)
- Recent comparable sales in area affecting model
- Property damage or major repair (if down)
Action: Verify on Zillow and investigate outliers.
"""
Large single-month changes are often data anomalies or Zestimate model updates, not real value shifts. Always verify on Zillow before reacting.
Portfolio-level metrics
After computing individual property equity, aggregate to portfolio level:
These metrics give you a high-level view of portfolio health. Gross yield (annual rental / total value) tells you your cash-on-cash return. Appreciation percentage shows how your total investment has grown.
Year-over-year comparison
To spot trends, compare current values to 12-months-ago snapshots:
current_snapshot = load_snapshot(date_today)
prior_year_snapshot = load_snapshot(date_today - 365_days)
yoy_appreciation = {
"total_portfolio_value": {
"then": prior_year_snapshot.total_value,
"now": current_snapshot.total_value,
"change": current_snapshot.total_value - prior_year_snapshot.total_value,
"change_pct": ((current_snapshot.total_value - prior_year_snapshot.total_value)
/ prior_year_snapshot.total_value * 100)
}
}
report += f"""
YEAR-OVER-YEAR COMPARISON (Mar 2025 → Mar 2026)
Portfolio Value: ${prior_year_snapshot.total_value:,.0f} → ${current_snapshot.total_value:,.0f}
Annual Appreciation: {yoy_appreciation['total_portfolio_value']['change_pct']:+.1f}%
Dollar Gain: ${yoy_appreciation['total_portfolio_value']['change']:+,.0f}
"""
Gross yield and cap rate tracking
For rental properties, compute gross yield (annual rent / current value) and track it over time:
for prop in portfolio.properties:
if prop.monthly_rent:
annual_rent = prop.monthly_rent * 12
gross_yield = (annual_rent / current_zestimate) * 100
# Cap rate (simplified): gross yield - property tax rate (approx 0.8%-1.2%)
estimated_property_tax_rate = 0.01 # 1% annually
cap_rate_simple = gross_yield - (estimated_property_tax_rate * 100)
report_line = f"{prop.address}: Gross Yield {gross_yield:.2f}%, Est. Cap {cap_rate_simple:.2f}%"
Gross yield trending down over time means your property value has appreciated faster than rents. This is common and good (more valuable asset, still cash-flowing). If gross yield drops below 2%, you have a heavily appreciated asset with little cash flow—consider refinancing or selling.
HEARTBEAT schedule
Monthly portfolio snapshot: 0 9 1 * * (1st of month at 9 AM). Pull Zestimates, compute equity, generate report.
Weekly equity alert check: 0 8 * * 1 (Monday 8 AM). Check for significant value changes (>5%) since last snapshot. Alert if found.
Quarterly refinance analysis: 0 8 1 1,4,7,10 * (First day of each quarter). Compute current LTV on each property, identify refi candidates.
Sample monthly report
FAQ
Should I use Zestimates for serious investment decisions?
Zestimates work well for directional tracking — knowing if your portfolio is up or down 5–10% over a quarter. They should not be used for refinancing decisions, tax appeal valuations, or major buy/sell decisions. For those, use a licensed appraiser or pull actual comps via Part 4 of this series. The monitoring agent is designed for portfolio trend awareness, not precise valuation.
How do I store my mortgage balances for equity tracking?
The agent reads loan balances from a local YAML or CSV file that you maintain. It does not connect to your bank or mortgage servicer — you update balances manually (or quarterly when you receive a statement). This keeps sensitive financial credentials out of the system entirely.
Can I include rental income in the portfolio tracking?
Yes. You can add a monthly_rent field to each property in your portfolio config, and the agent will compute gross yield (annual rent / current value), cash-on-cash return (if you also include mortgage payment), and aggregate portfolio yield. This is covered in the yield analysis section above.
How do I handle properties with unusual valuations (very new, very old, pending demo)?
If Zillow has no Zestimate or the estimate is clearly wrong (flagged as "low confidence"), set use_zestimate: false for that property in your config. Manually input a value from comps or a recent appraisal. The agent will use your manual value instead of Zillow's API response.
Can I track refinancing opportunities with this agent?
Yes, indirectly. By monitoring equity and LTV (loan-to-value = mortgage_balance / zestimate), you can identify properties where equity has grown enough to support a refi. Add a quarterly report that flags properties where equity exceeds a threshold (e.g., 30% equity) or LTV drops below a target (e.g., <70%).
What if I sell a property during the month?
Remove it from portfolio.yaml before the next monthly snapshot. The agent will no longer pull data for that zpid. Consider archiving sold properties to a separate portfolio_sold_archive.yaml for historical tracking of performance.