Skip to content

Zillow API

The TrueScrape Zillow API exposes 3 public endpoints covering Zillow agent profile, Zillow listing details and Search Zillow listings by location. Every call is a GET against public, logged-out pages and returns the same unified schema as every other platform here. Calls cost 1 credit each. A cache hit is free, and a failed or empty response is never charged.

Endpoints

EndpointReturnsCreditsCacheableBatchable
/v1/zillow/agentZillow agent profile1yesyes
/v1/zillow/propertyZillow listing details1yesyes
/v1/zillow/searchSearch Zillow listings by location1yesyes

Reference

GET/v1/zillow/agent1 creditcacheablebatchable

Zillow agent profile

Public Zillow agent/team profile: brokerage, license, rating and review count, where published.

ParameterTypeRequiredDescription
urlstringyesZillow agent profile URL, e.g. https://www.zillow.com/profile/<username>

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one RealEstateAgent.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstring | nullalways
namestring | nullalways
urlstring | nullalways
photoUrlstring | nullalways
brokerageNamestring | nullalways
licenseNumberstring | nullalways
phonestring | nullalways
biostring | nullalways
languagesstring[]always
serviceAreasstring[]always
ratingnumber | nullalways
reviewCountnumber | nullalways
salesStatsAgentStat[]alwaysSales figures the source publishes for the agent, such as deals closed or average days on market. Which figures appear varies by source.
listingsPropertyListing[]alwaysProperty listings shown on the agent's profile.
fetchedAtstringalwaysWhen this record was retrieved, as an ISO 8601 timestamp.
curl
curl "$API/v1/zillow/agent?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/zillow/agent?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/zillow/agent",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/zillow/agent
Open the full playground
GET/v1/zillow/property1 creditcacheablebatchable

Zillow listing details

Public details for a Zillow listing: price, status, beds/baths, area, address and an inline photo set. **Required:** Pass either zpid or url.

ParameterTypeRequiredDescription
zpidstringnoZillow property id (zpid), e.g. "120900080"
urlstringnoZillow listing URL, e.g. https://www.zillow.com/homedetails/<slug>/<zpid>_zpid/

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one PropertyListing.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalwaysThe property id on its source, such as a Zillow zpid. Always a string.
urlstring | nullalways
listingTypesale | rent | nullalways
statusactive | pending | under_offer | sold | rented | off_market | unknown | nullalwaysWhere the listing is in its lifecycle. `pending` and `under_offer` mean a deal is in progress. `off_market` means withdrawn without a sale and may return, unlike `sold`. `unknown` means the status could not be read as one of the other values.
pricenumber | nullalwaysAsking price, or the rent for a rental, in `currency`. Read it together with `priceQualifier`.
currencystring | nullalwaysISO 4217 currency code for the amounts in this record, such as USD or EUR.
priceQualifierstring | nullalwaysWording that changes what `price` means, such as "offers over", "guide price", "per month" or "starting at".
pricePerAreanumber | nullalwaysPrice per unit of area, in `currency` per `areaUnit`.
addressAddressalways
latitudenumber | nullalways
longitudenumber | nullalways
bedsnumber | nullalways
bathsnumber | nullalwaysNumber of bathrooms. Can be fractional, such as 2.5.
receptionsnumber | nullalwaysNumber of reception rooms, a figure UK and European listings state. US listings have no equivalent, so it is null there.
areanumber | nullalwaysInterior floor area, in `areaUnit`.
areaUnitsqft | sqm | nullalwaysUnit of `area`: `sqft` for square feet, `sqm` for square metres. Null when the source gave no unit.
lotAreanumber | nullalwaysArea of the plot the property stands on, in `lotAreaUnit`.
lotAreaUnitsqft | sqm | nullalwaysUnit of `lotArea`: `sqft` for square feet, `sqm` for square metres. Null when the source gave no unit.
propertyTypestring | nullalwaysProperty type as the source words it, so values differ between sources.
yearBuiltnumber | nullalways
descriptionstring | nullalways
imageUrlsstring[]always
floorPlanUrlsstring[]always
agentNamestring | nullalways
agentPhonestring | nullalways
brokerageNamestring | nullalwaysThe listing brokerage, or the management company for a rental building.
amenitiesRecord<string, string>alwaysFurther listing facts as label and value pairs, such as HOA dues, a council tax band or an energy rating. Which labels appear varies by source.
schoolsSchool[]always
priceHistoryPriceEvent[]alwaysPast events for the property, such as listings, price changes and sales.
listedAtstring | nullalwaysWhen the property was listed. Usually an ISO 8601 timestamp; some sources pass their own date text through.
updatedAtstring | nullalwaysWhen the source last updated the listing. Usually an ISO 8601 timestamp; some sources pass their own date text through.
fetchedAtstringalwaysWhen this record was retrieved, as an ISO 8601 timestamp.
curl
curl "$API/v1/zillow/property?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/zillow/property?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/zillow/property",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/zillow/property
Open the full playground

Questions

How much does the Zillow API cost?
Calls cost 1 credit each. Every endpoint is cacheable, and a cache hit costs nothing. A failed request and an empty result are both free, on every endpoint.
Does the Zillow API need a login or cookies?
No. Every endpoint reads public, logged-out pages only — no account, no cookies, no session. An API key identifies your own TrueScrape account and nothing else.
Can I fetch many Zillow targets in one request?
Yes. 3 of 3 are batchable: one POST to /v1/jobs/batch takes many targets and returns a job id to poll.
Can I watch Zillow endpoints for changes?
Yes, 2 of 3. A subscription polls on your schedule and fires your webhook only when the content changed; the rest carry x-subscribable: false in the spec.