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_statusisWithdrawnorExpiredcame 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 velocity —
averageDaysBetweenStatusChangesmeasures how quickly listings move through their lifecycle in a given area. - Lead scoring — listings with a high
numberOfStatusChangesoften 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" }
]
}| Field | Type | Meaning |
|---|---|---|
currentStatus | string | The listing's status right now |
previousStatus | string | The status immediately before the current one |
numberOfStatusChanges | int | Total count of recorded status transitions |
averageDaysBetweenStatusChanges | float | Average time between transitions |
statusChangeList[].statusChangeDate | date | When a specific transition happened |
statusChangeList[].previousStatus / newStatus | string | The before/after status of that specific transition |
Data note: the per-event
statusChangeListarray 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 withnumberOfStatusChanges > 0).
Available filters
| Filter | Type | Maps to |
|---|---|---|
has_status_changes | bool | numberOfStatusChanges > 0 — the listing has changed status at least once |
number_of_status_changes_min/_max | int | Bound how many times it's transitioned |
previous_status | enum | The 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 }