Price drops and the last price change

price_drops_count counts the price cuts in the home's current listing, and last_price_change describes the most recent price change in that listing, up or down.

FieldType
data.calculated.price_drops_countinteger or null
data.calculated.last_price_changeobject or null: { date, price, previous_price, change, change_pct }

Fields under data.calculated are calculated by PropertiesAPI from the other fields in the same response. They are not Zillow estimates.

What it means

PropertiesAPI reads priceHistory oldest first and starts at the latest Listed for sale or Listed for rent event, so older listings of the same home don't count. Every Price change event priced below the event before it adds one to price_drops_count.

last_price_change is the latest Price change event in that listing, with date, price, previous_price, change (price minus previous price) and change_pct (change over previous price, times one hundred). It can be a rise: a recorded Austin listing cut its price once and then raised it, so it has one drop and a positive last change.

These figures turn a long history into two signals you can sort and filter by. They come from the events Zillow shows, so a price change that isn't on the page isn't counted.

Recorded example

Recorded lookup of a home for sale
{
  "priceHistory": [
    {
      "date": "2026-10-12",
      "event": "Price change",
      "price": 634970,
      "pricePerSquareFoot": 200,
      "priceChangeRate": -0.07299589763055317,
      "source": "NTREIS"
    },
    {
      "date": "2026-10-02",
      "event": "Price change",
      "price": 684970,
      "pricePerSquareFoot": 216,
      "priceChangeRate": 0.0007597340930674264,
      "source": "Normandy Homes"
    }
  ],
  "calculated": {
    "price_drops_count": 1,
    "last_price_change": {
      "date": "2026-10-12",
      "price": 634970,
      "previous_price": 684970,
      "change": -50000,
      "change_pct": -7.3
    }
  }
}
Recorded lookup of a home for sale
{
  "calculated": {
    "price_drops_count": 1,
    "last_price_change": {
      "date": "2026-10-15",
      "price": 400000,
      "previous_price": 395000,
      "change": 5000,
      "change_pct": 1.27
    }
  }
}

Values are copied from recorded lookups of public Zillow pages, with the other fields of data left out; long lists are cut to their first entries and long text to its opening words. They show the shape and typical values, not today's data for these homes.

When it is null

  • price_drops_count is null when priceHistory has no listing event at all; it is zero when the current listing has no cuts.
  • last_price_change is null when the current listing has no Price change event.

Read it in code

Send a Zillow link, a zpid or an address to GET /v1/zillow/property with your key in the x-api-key header, then read the field from data:

curl and jq
curl -sG "https://api.propertiesapi.com/v1/zillow/property" \
  -H "x-api-key: $PROPERTIESAPI_KEY" \
  --data-urlencode "url=https://www.zillow.com/homedetails/1704-Shelbourne-Dr-Austin-TX-78752/29412761_zpid/" \
  | jq '.data | {calculated: (.calculated | {price_drops_count, last_price_change})}'
Python
import os
import requests

r = requests.get(
    "https://api.propertiesapi.com/v1/zillow/property",
    params={"url": "https://www.zillow.com/homedetails/1704-Shelbourne-Dr-Austin-TX-78752/29412761_zpid/"},
    headers={"x-api-key": os.environ["PROPERTIESAPI_KEY"]},
    timeout=120,
)
r.raise_for_status()
home = r.json()["data"]
c = home["calculated"]
last = c["last_price_change"]
print("cuts in this listing:", c["price_drops_count"])
if last:
    print(last["date"], last["previous_price"], "->", last["price"], f"({last['change_pct']}%)")
JavaScript (Node)
const url = "https://www.zillow.com/homedetails/1704-Shelbourne-Dr-Austin-TX-78752/29412761_zpid/";
const res = await fetch(
  `https://api.propertiesapi.com/v1/zillow/property?url=${encodeURIComponent(url)}`,
  { headers: { "x-api-key": process.env.PROPERTIESAPI_KEY } },
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { data: home } = await res.json();
const { price_drops_count, last_price_change: last } = home.calculated;
console.log("cuts in this listing:", price_drops_count);
if (last) console.log(last.date, last.previous_price, "->", last.price, `(${last.change_pct}%)`);

Common mistakes

  • Treating last_price_change as the last cut. Check the sign of change.
  • Counting cuts across every listing of the home from priceHistory yourself. Relistings reset the count here on purpose.
  • Expecting price drops on rentals with no history. Apartment building rentals had no priceHistory in our recorded lookups.

Zillow is a trademark of Zillow, Inc. PropertiesAPI is an independent service and is not affiliated with, endorsed by or sponsored by Zillow.

Price drops and the last price change questions

Does a relisting reset the price drop count?+

Yes. Only events from the latest Listed for sale or Listed for rent event on count.

Can last_price_change be an increase?+

Yes. It is the most recent change either way; change is positive for a rise.

Is change_pct a fraction?+

No. change_pct is a percent with two decimals, unlike priceChangeRate in priceHistory, which is a fraction.