Listing Journeys Aren't Always Linear

Use ".statusChangeHistory" to decipher what's going on with a listing at any point during its lifecycle

Status Change History

Why track a listing's status over its lifecycle

currentStatus tells you where a listing is right now — Active, Pending, Closed, Withdrawn. It doesn't tell you the path it took to get there. statusChangeHistory tracks that path: how many times a listing's status has flipped, and what it changed from/to.

This matters for:

  • Relist detection — a listing currently Active whose previous_status is Withdrawn or Expired came back on the market rather than being brand-new inventory.
  • Deal-fall-through signals — a listing that went Pending → back to Active (previous status = Pending, current = Active) is a strong buy-side re-engagement signal.
  • Market velocityaverageDaysBetweenStatusChanges measures how quickly listings move through their lifecycle in a given area.
  • Lead scoring — listings with a high numberOfStatusChanges often correlate with distressed sales, difficult negotiations, or price/condition issues worth investigating.

Structure

"statusChangeHistory": {
  "currentStatus": "Active",
  "previousStatus": "Withdrawn",
  "numberOfStatusChanges": 3,
  "averageDaysBetweenStatusChanges": 45.5,
  "statusChangeList": [
    { "statusChangeDate": "2026-04-02", "previousStatus": "Withdrawn", "newStatus": "Active" }
  ]
}
FieldTypeMeaning
currentStatusstringThe listing's status right now
previousStatusstringThe status immediately before the current one
numberOfStatusChangesintTotal count of recorded status transitions
averageDaysBetweenStatusChangesfloatAverage time between transitions
statusChangeList[].statusChangeDatedateWhen a specific transition happened
statusChangeList[].previousStatus / newStatusstringThe before/after status of that specific transition

Data note: the per-event statusChangeList array is not currently populated across the index — use the aggregate fields (numberOfStatusChanges, previousStatus, averageDaysBetweenStatusChanges) for filtering today. Those aggregates ARE reliably populated (confirmed against ~9.2M listings with numberOfStatusChanges > 0).

Available filters

FilterTypeMaps to
has_status_changesboolnumberOfStatusChanges > 0 — the listing has changed status at least once
number_of_status_changes_min/_maxintBound how many times it's transitioned
previous_statusenumThe status immediately prior to the current one — same vocabulary/aliases as status (e.g. "Sold""Closed")

Example queries

Find listings that are Active again after being Withdrawn (classic "back on market"):

{ "active": true, "previous_status": "Withdrawn" }

Find listings that fell out of contract (Pending → Active):

{ "active": true, "previous_status": "Pending" }

Find listings that have churned through status changes repeatedly (possible distress signal):

{ "has_status_changes": true, "number_of_status_changes_min": 3 }