Skip to content

Properties

Wraps the property-detail upstream. Cache TTL: 24 hours per zpid.

GET /v1/properties/by-url

QueryTypeRequiredNotes
urlstringyesFull Zillow URL: homedetails, b, community, or apartments
statusenumnoFOR_SALE (default), RECENTLY_SOLD, FOR_RENT
extract_unitsenumnodisabled (default), all, for_sale, recently_sold, for_rent, off_market — for building URLs
fieldsstringnoField projection (see Field projection)

200 response

{
"data": { "zpid": "11026031", "address": {...}, "price": 295000, "...": "..." },
"request_id": "..."
}

When extract_units != disabled and the URL is a multi-unit building, data is an array.

Errors: invalid_url, invalid_status, invalid_extract_units, not_found, upstream_timeout, upstream_error.

GET /v1/properties/by-address

QueryTypeRequired
addressstringyes
statusenumno
fieldsstringno

address should be the full street + city + state + zip. We geocode it upstream.

GET /v1/properties/{zpid}

zpid-based lookup with cache. Returns cached: true|false plus fetched_at.

{
"data": { "zpid": "11026031", "...": "..." },
"cached": true,
"fetched_at": "2026-04-30T14:22:11.000Z",
"request_id": "..."
}

Sub-resources

All sub-resources read from the same cached detail row — they’re cheap to call repeatedly within the 24h window.

GET /v1/properties/{zpid}/photos

{
"data": [{"url":"https://photos.zillowstatic.com/...", "width": 1536, "height": 1024}, ...],
"meta": { "count": 42, "photo_count": 42, "has_3d": false, "has_video": true, "cached": true }
}

GET /v1/properties/{zpid}/price-history

{
"data": [
{ "date": "2024-08-15", "event": "Listed for sale", "price": 295000, "priceChangeRate": 0 },
{ "date": "2018-03-22", "event": "Sold", "price": 211000, "priceChangeRate": 0.18 }
],
"meta": { "cached": true }
}

GET /v1/properties/{zpid}/tax-history

{ "data": [{ "time": 1704067200000, "taxPaid": 2841, "value": 248000, "valueIncreaseRate": 0.04 }], "meta": {...} }

GET /v1/properties/{zpid}/schools

{ "data": [{ "name":"Mountain View Elementary", "rating":7, "distance":0.4, "type":"public", "level":"Elementary" }], "meta": {...} }

GET /v1/properties/{zpid}/nearby

Comparable nearby listings (top ~12 from the upstream).

GET /v1/properties/{zpid}/agent

{
"data": {
"agentName": "...", "agentEmail": "...", "agentPhoneNumber": "...", "agentLicenseNumber": "...",
"brokerName": "...", "brokerPhoneNumber": "...", "attributionInfo": {...}
}
}

GET /v1/properties/{zpid}/zestimate

{
"data": {
"zestimate": 305100, "rent_zestimate": 1850,
"tax_assessed_value": 248000, "last_sold_price": 211000, "currency": "USD"
}
}

GET /v1/properties/{zpid}/open-houses

{
"data": [{ "startTime": "2026-05-04T18:00:00Z", "endTime": "2026-05-04T20:00:00Z" }],
"meta": { "tour_eligibility": {...} }
}

GET /v1/properties/{zpid}/facts

Full resoFacts blob (MLS attribute set — appliances, flooring, parking, view, etc.).

POST /v1/properties/batch

Async. Up to 500 entries per job.

Body

{
"urls": ["https://www.zillow.com/homedetails/.../11026031_zpid/", "..."],
"addresses": ["18 Zelma Dr, Greenville, SC 29617"],
"propertyStatus": "FOR_SALE",
"extractBuildingUnits": "disabled",
"maxItems": 500
}

202 response

{ "data": { "job_id": "8c2a...", "status": "running" }, "request_id": "..." }

Then poll GET /v1/jobs/{job_id} or use a webhook.