Zillow API Python tutorial

Zillow API in Python

Get listing price, status, Zestimate, rent Zestimate, photos and price history from a Zillow link or an address in a few lines of Python. Then batch a whole spreadsheet.

Base URL https://api.propertiesapi.com/v1 · auth header x-api-key. Zillow's own API needs Bridge approval. This tutorial uses PropertiesAPI, an independent service that returns Zillow property and listing data as JSON, provided as-is.

1. Set your key

Keep the key out of your code. Everything below uses requests. No SDK needed.

Shell
pip install requests pandas
export PROPERTIESAPI_KEY="your_key_here"

2. Look up one Zillow link

Send any zillow.com/homedetails link as ?url=. A live lookup takes typically 8 seconds, up to about 20, so set a generous timeout. The body is { data, meta }.

Python
import os, requests

BASE = "https://api.propertiesapi.com/v1"
session = requests.Session()
session.headers["x-api-key"] = os.environ["PROPERTIESAPI_KEY"]

r = session.get(
    f"{BASE}/zillow/property",
    params={"url": "https://www.zillow.com/homedetails/130-Water-St-APT-12D-New-York-NY-10005/2064142765_zpid/"},
    timeout=120,
)
r.raise_for_status()
home = r.json()["data"]

print(home["address"], home["homeStatus"])
print(f"Price      ${home['price']:,}")
print(f"Zestimate  {home['zestimate']}  rent {home['rentZestimate']}/mo")   # either can be None
print(home["beds"], "beds,", home["baths"], "baths,", home["livingArea"], "sqft, built", home["yearBuilt"])
print(home["daysOnZillow"], "days on Zillow,", len(home["photos"]), "photos")

3. Or look up by address

No Zillow link? Send ?address= and we find the matching Zillow property first. The response is the same. An address lookup costs 1 credit, the same as a link.

Python
r = session.get(
    f"{BASE}/zillow/property",
    params={"address": "1600 Main St, Austin, TX 78701"},
    timeout=120,
)
body = r.json()
home = body["data"]
print(home["zpid"], home["detailUrl"], "cached" if body["meta"]["cached"] else "live")

4. What comes back

{ data, meta }: data is the property, meta says whether it came from the 24-hour cache (free) and how many credits it used. Fields Zillow doesn't show for that property come back as null. Example values below are illustrative.

JSON
{
  "data": {
    "zpid": "2064142765",
    "detailUrl": "https://www.zillow.com/homedetails/130-Water-St-APT-12D-New-York-NY-10005/2064142765_zpid/",
    "address": "130 Water St APT 12D, New York, NY 10005",
    "price": 995000,
    "homeStatus": "FOR_SALE",
    "homeType": "CONDO",
    "beds": 2,
    "baths": 2,
    "livingArea": 1280,
    "zestimate": null,
    "rentZestimate": 4470,
    "daysOnZillow": 38,
    "imgSrc": null,
    "photos": [],
    "brokerName": "SERHANT.",
    "priceHistory": [],
    "taxHistory": []
  },
  "meta": {
    "cached": false
  }
}

5. Handle errors and missing fields

Don't treat null as zero: a home that isn't for sale has no price, and some homes have no Zestimate. A 404 means we couldn't find a Zillow property. Failed lookups aren't billed.

Python
import time

def lookup(**params):
    """params: url=... or address=..."""
    for attempt in range(4):
        try:
            r = session.get(f"{BASE}/zillow/property", params=params, timeout=120)
        except requests.Timeout:
            continue                      # live lookup took too long: try again
        if r.status_code == 404:
            return None                   # no matching Zillow property (not billed)
        if r.status_code >= 500:          # 502/504 upstream, 503 busy (has retry-after)
            time.sleep(int(r.headers.get("retry-after", 2 ** attempt)))
            continue
        if not r.ok:                      # 401 missing/invalid key, 400 bad input
            raise RuntimeError(r.json()["error"]["message"])
        return r.json()["data"]
    raise RuntimeError(f"lookup failed after retries: {params}")

home = lookup(address="1600 Main St, Austin, TX 78701")
if home and home["zestimate"] is None:
    print("Zillow shows no Zestimate for this home")

6. Price and tax history

History comes back as lists, as shown on the Zillow page.

Python
for e in home["priceHistory"]:
    print(e["date"], e["event"], e["price"])

for t in home["taxHistory"]:
    print(t["year"], "tax", t["taxPaid"], "assessed", t["value"])

7. Batch a CSV of links or addresses

POST /v1/zillow/batch takes up to 50 Zillow URLs or addresses per request. Results come back in data, in order, each with ok. Lookups run live, so a full batch can take a few minutes: use a long timeout. Billed per successful live lookup; cache hits are free.

Python
import pandas as pd

inputs = pd.read_csv("homes.csv")["zillow_url"].dropna().tolist()   # or an "address" column
rows, failed = [], []

for i in range(0, len(inputs), 50):
    chunk = inputs[i:i + 50]
    r = session.post(f"{BASE}/zillow/batch", json={"items": chunk}, timeout=320)
    r.raise_for_status()
    for item in r.json()["data"]:
        (rows if item["ok"] else failed).append(item)

df = pd.json_normalize([item["data"] for item in rows])
df[["address", "homeStatus", "price", "zestimate", "rentZestimate", "beds", "baths", "livingArea"]].to_csv("homes_out.csv", index=False)
print(len(rows), "found,", len(failed), "failed (not billed)")

Zillow API Python questions

Is there an official Zillow API Python library?+

No. Old packages such as python-zillow wrapped the legacy ZWSID API, which was retired in 2021, so they no longer work. Zillow's current APIs go through Bridge Interactive by application.

Is this Zillow's official API?+

No. PropertiesAPI is an independent service and is not affiliated with, endorsed by or sponsored by Zillow. It returns what the public Zillow page shows, provided as-is, with no guarantee of accuracy or completeness.

Is there a PropertiesAPI Python SDK?+

A pip package is planned. The API is plain HTTPS and JSON, so requests (or httpx) is all you need today.

Why does a lookup take so long?+

A live lookup fetches the property from Zillow at request time, so it takes typically 8 seconds, up to about 20. Set a timeout of about 120 seconds for single lookups and about 320 for batches. Repeat lookups of the same home within 24 hours come from cache, for free.

How many lookups do I get for free?+

50 free lookups, once, with no card. Paid plans (lookups a month): Starter $29/mo (2,500); Pro $79/mo (7,500); Business $199/mo (20,000); Scale $499/mo (65,000). Overage is your plan's own per-lookup rate ($11.60 per 1,000 on Starter, down to $7.68 on Scale). Repeat lookups of the same home within 24 hours are free. Failed lookups aren't billed.

Your first call in Python

50 free lookups, no card. Join the list; keys go out as we open accounts.

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