Skip to main content
Note: Real estate data APIs have inherent lag (1–24h for listings, 30–60 days for sold data). Always verify critical decisions with direct MLS access. Data quality notes →
Real Estate Series Part 2 of 5

Part 2: Price Changes & Days on Market — Surface Motivated Sellers Automatically

Updated March 26, 2026 13 min read Intermediate

Use cases at a glance

Price drops and high days-on-market are key signals of seller motivation. A property listed at $500k that drops to $475k after sitting 20 days is broadcasting that the seller wants to move it. An automated price-change agent catches these signals in real time, before other investors notice.

Price drops in target zips

Alert when a property you're tracking drops price by $5k+ or >2%.

DOM threshold exceeded

Alert when a listing sits >60 days (or your local threshold) without a price drop.

Zestimate gap widening

Alert when list price drops to within 5% of Zestimate—often a sign of motivation.

Price history for a specific address

Pull and archive all price changes on a property you're considering or already tracking.

Stale listing digest

Weekly summary of all properties >60 days on market in your target zips, sorted by age.

Market-wide price momentum

Aggregate data: are prices rising, falling, or stagnant in your market over the past 30 days?

Price change detection agent

To detect price changes, your agent must store historical snapshots of listing data. On each polling cycle, it compares the current snapshot to the previous one, identifying zpids where the price has changed.

Here's the agent configuration:

---
name: price-change-alert
schedule: "0 */4 * * *"  # Every 4 hours
tools:
  - zillow-rapidapi
config:
  search_params:
    zip_codes: ["78704", "78723"]
    property_type: "Single Family"

  price_change_thresholds:
    min_drop_dollars: 5000
    min_drop_pct: 2.0

  zestimate_thresholds:
    gap_pct: 5  # Alert if list price within 5% of Zestimate

  storage:
    type: "json_file"
    path: "/data/price_snapshots.json"
    retention_days: 90

  output:
    channels: ["slack"]
    slack:
      webhook_url: "${SLACK_WEBHOOK_URL}"
---

job: |
  current = await zillow_rapidapi.search(config.search_params)
  previous = load_snapshot(config.storage.path)

  for listing in current:
    zpid = listing.zpid
    if zpid in previous:
      old_price = previous[zpid].price
      new_price = listing.price
      drop_dollars = old_price - new_price
      drop_pct = (drop_dollars / old_price) * 100

      if drop_dollars >= config.price_change_thresholds.min_drop_dollars:
        if drop_pct >= config.price_change_thresholds.min_drop_pct:
          send_price_alert(listing, drop_dollars, drop_pct)

  save_snapshot(current, config.storage.path)

Key mechanics: The agent maintains a price_snapshots.json file mapping zpid to historical price data. On each run, it fetches current listings, compares prices to the snapshot, and alerts only if both thresholds are met (absolute dollar drop AND percentage drop). After processing, it updates the snapshot with current data.

Both thresholds required

Setting both a dollar threshold and a percentage threshold prevents false positives. Requiring both filters out trivial adjustments (a $1 drop on a $500k property = 0.0002%, well below a 2% threshold) while catching genuine price reductions across all price ranges.

Days on Market monitoring

Days on market is a critical signal. A property listed for 45 days in a 30-day-median market suggests overpricing or condition issues. The key is benchmarking against your local median DOM.

Market Tier Median DOM Alert Threshold Interpretation
Hot (urban, competitive) 15 days >25 days Overpriced or has issues. Seller may be motivated to reduce.
Warm (suburban) 30 days >45 days Above-market DOM. Check price competitiveness.
Cool (rural/secondary market) 60 days >90 days Well above market median. Property or price likely problematic.
Cold (very low demand) 90+ days >150 days Severely distressed. Potential short sale or foreclosure risk.

A DOM alert doesn't trigger a price change alert. Instead, it flags properties that have been stagnant for too long. Pair this with a price-drop alert: if a property has been on market >60 days and suddenly drops price, that's a high-confidence motivated seller signal.

Insider tip: In hot markets, a property hitting 20+ days is unusual and worth investigating. In cool markets, wait until 90+ days. Calibrate your DOM thresholds to your specific market's median, not national averages.

Zestimate gap analysis

Zillow's Zestimate is an automated valuation model. When a listing price drops to near or below the Zestimate, it often signals the seller has lost confidence in the original asking price and is capitulating toward market reality.

Here's an agent snippet for Zestimate gap tracking:

for listing in current:
  gap_pct = ((listing.zestimate - listing.price) / listing.zestimate) * 100

  if gap_pct >= config.zestimate_thresholds.gap_pct:
    send_zestimate_gap_alert(listing, gap_pct)
    # Interpretation: list price is now within 5% of Zestimate
    # or BELOW Zestimate. Seller is actively discounting.

When a property listed at $550k (Zestimate $550k) has listed at $550k, the gap is 0%. If price drops to $525k, gap becomes 4.5%. Hit 5% and you alert. If it drops to $500k, gap is 9%—strong seller motivation signal.

Weekly stale listing digest

Instead of alerting on every >60-day listing, compile a weekly report showing all stale inventory in your target zips, sorted by age descending.

schedule: "0 9 * * 1"  # Monday 9 AM

job: |
  current = await zillow_rapidapi.search(config.search_params)
  stale = [l for l in current if l.dom >= 60]
  stale = sorted(stale, key=lambda x: x.dom, reverse=True)

  report = format_stale_digest(stale)
  send_slack_message(report)

Sample report output:

Weekly Stale Listing Digest — March 24, 2026
Stale Listings (DOM ≥60) in 78704, 78723
123 Oak Street, 78704
DOM: 87 days | Price: $549,500 | Z-est: $575k | Beds: 3
456 Elm Avenue, 78723
DOM: 142 days | Price: $425,000 | Z-est: $460k | Beds: 2
789 Pine Court, 78704
DOM: 156 days | Price: $615,000 | Z-est: $695k | Beds: 4
Total: 3 stale listings | Avg DOM: 128 days | Avg discount to Z-est: -6.2%

HEARTBEAT schedule

HEARTBEAT: Price change polling

Price change detection: 0 */4 * * * (every 4 hours). Balances API cost and responsiveness. Increases to 0 */2 * * * (every 2 hours) if monitoring <20 zip codes in a hot market.

Weekly stale digest: 0 9 * * 1 (Monday 9 AM). Compiled report of all DOM >60 listings.

Monthly price momentum: 0 8 1 * * (1st of month). Compare avg prices month-over-month to gauge market direction.

Sample alert output

Here's what a price-drop alert looks like in Slack:

Price Drop Alert — March 25, 2026 at 3:47 AM
📉 Price reduction detected
Address 123 Oak Street, Austin, TX 78704
Old Price $549,500
New Price $524,000
Drop -$25,500 (-4.6%)
Beds / Baths 3 BD / 2 BA
Days on Market 38 days
Zestimate $575,000
New gap to Zestimate -8.9% (overpriced before, now realistic)
Motivation Signal Moderate—38 DOM + 4.6% drop suggests pricing adjustment after soft market response

FAQ

How do I distinguish a meaningful price drop from a trivial $1,000 reduction?

Set both an absolute threshold (e.g., min $5,000 drop) AND a percentage threshold (e.g., min 2% reduction). Require both to be met. This filters out cosmetic price adjustments and ensures you're seeing genuine seller motivation.

What does a high DOM (days on market) actually indicate?

DOM above the local average suggests overpricing, condition issues, or a motivated seller willing to negotiate. The key is benchmarking against your specific market's median DOM — a 45-day DOM means very different things in San Francisco (hot market) vs. rural Ohio. The agent can pull local median DOM from Zillow data for context.

Can I track price changes on properties I don't own and haven't saved?

Yes — you define your watchlist by zip code, neighborhood, or polygon, not by individual property. The agent monitors all active listings in the target area and alerts on any that match your price-change or DOM thresholds.

How often is the Zillow data updated for price changes?

Price changes typically appear within 2-4 hours of being reported to the MLS, depending on syndication lag. Run your price-change agent every 4 hours to catch most changes within a reasonable timeframe. For very hot markets where timing is critical, run every 2 hours.

Should I alert on price increases?

Typically no—your goal is to find deals, not overpriced inventory. However, if you're tracking a specific property you own or are considering, a price increase could signal rising demand. You could configure a separate alert for price increases on a watchlist of specific zpids, but broad alerts on price increases will add noise.