Arcadium Data Scrapers
Home / Actors / Zillow Scraper

Zillow Scraper

Give it a city, ZIP code, county, Zillow search URL, property URL or zpid and it returns Zillow homes for sale, for rent or recently sold, one JSON row per property: price, Zestimate, rent Zestimate, beds, baths, square feet, lot, home type, days on market, price cut, brokerage, photos and coordinates. With details: description, year built, facts, price history, tax history and schools. $2.10 per 1,000 properties, $3.20 per 1,000 with details; paid plans pay less. You pay only for rows you get.

$2.10 per 1,000 properties on the Free plan, down to $1.20 on higher plans

Why this actor

Drop-in input

Drop-in input. Input written for maxcopell/zillow-scraper (searchUrls, resultsLimit), maxcopell/zillow-zip-search (zipCodes, priceMin, priceMax, daysOnZillow, forRent, sold) or maxcopell/zillow-detail-scraper (startUrls, propertyStatus) works as it is.

As stated in the actor’s README. The full list of accepted input names is on the Store page.

Switching from another actor

What you get

FieldWhat it holds
rowTypeKind of row. Filter on this first. 'property': one Zillow property (charged as 'property', or 'property-details' when detailed is true). 'error': an input could not be read; see code and message (free).
platformAlways 'zillow'.
propertyIdZillow property id (zpid), the number before _zpid in the property URL. Unique per run.
urlProperty page URL on zillow.com.
statusListing status as Zillow states it: FOR_SALE, FOR_RENT, RECENTLY_SOLD, PENDING, OFF_MARKET, ...
statusTextStatus as shown on the card, e.g. 'Active', 'House for rent', 'Sold'.
priceList price in USD; monthly rent for rentals; null for sold homes in search rows (see lastSoldPrice on detail rows).
currencyCurrency of all money fields, normally USD.
addressFull address line, e.g. '3207 Wickham Ln, Austin, TX 78725'.
streetStreet address.
cityCity name of the property address.
stateTwo-letter state code.
zipcodeZIP code of the property address.
latitudeLatitude (WGS84).
longitudeLongitude (WGS84).
bedsNumber of bedrooms.
bathsBathrooms (half baths count 0.5).
livingAreaLiving area in square feet.
lotAreaLot size in lotAreaUnit.
lotAreaUnitUnit of lotArea: sqft or acres.
homeTypeSINGLE_FAMILY, CONDO, TOWNHOUSE, MULTI_FAMILY, APARTMENT, LOT, MANUFACTURED, ...
yearBuiltYear built (detail rows).
daysOnMarketDays on Zillow.
zestimateZillow's estimated market value in USD (Zestimate).
rentZestimateZillow's estimated monthly rent in USD.
taxAssessedValueLatest tax-assessed value in USD.
priceChangeLast price change in USD (negative = price cut).
priceChangeDateISO date of the last price change.
dateSoldISO date of the last sale, when known.
lastSoldPriceLast sold price in USD (detail rows).
brokerNameListing brokerage (company). Agent names, phones and emails are never included.
photosProperty photo URLs (photos.zillowstatic.com).
photoCountNumber of photos on the listing (detail rows).
hasVideoTrue when the listing has a video.
has3DModelTrue when the listing has a 3D home tour.
detailedTrue when the row carries the detail fields (description, facts, priceHistory, taxHistory, schools).
descriptionListing description; emails, phone numbers and agent names removed.
monthlyHoaFeeMonthly HOA fee in USD.
propertyTaxRateProperty tax rate in percent.
mlsIdMLS listing number.
listingDataSourceWhere the listing comes from, e.g. the MLS name or 'Phoenix'.
countyCounty name (detail rows).
parcelIdCounty parcel number.
factsSelected building and lot facts: heating, cooling, appliances, flooring, parkingFeatures, garageParkingCapacity, stories, basement, poolFeatures, view, lotFeatures, sewer, waterSource, associationFee, taxAnnualAmount, school names, atAGlanceFacts and more (keys present only when Zillow has them).
priceHistoryPrice events, newest first: {date, event ('Listed for sale', 'Price change', 'Sold', 'Listed for rent'...), price, pricePerSquareFoot, priceChangeRate, source}. No agent names.
taxHistoryPublic tax record per year: {date, taxPaid, value, taxIncreaseRate, valueIncreaseRate}.
schoolsNearby assigned schools: {name, rating (GreatSchools 1-10), distance (miles), grades, level, link}.
pageViewCountPage views Zillow reports for the listing.
favoriteCountTimes the listing was saved.
searchInputThe location or search URL this row was found by (null for property URLs).
searchRank1-based position in that search's results.
scrapedAtISO time the row was read.
inputError rows: the input that failed.
codeError rows: invalid_input, not_found, blocked or unavailable.
messageError rows: what went wrong, in plain words.

Sample row (from the README example; long text shortened, lists cut to two items):

{
  "rowType": "property",
  "platform": "zillow",
  "propertyId": "70345655",
  "url": "https://www.zillow.com/homedetails/3207-Wickham-Ln-Austin-TX-78725/70345655_zpid/",
  "status": "FOR_SALE",
  "price": 324900,
  "currency": "USD",
  "address": "3207 Wickham Ln, Austin, TX 78725",
  "city": "Austin",
  "state": "TX",
  "zipcode": "78725",
  "latitude": 30.232096,
  "longitude": -97.5937,
  "beds": 4,
  "baths": 3,
  "livingArea": 2575,
  "lotArea": 4800.312,
  "lotAreaUnit": "sqft",
  "homeType": "SINGLE_FAMILY",
  "daysOnMarket": 140,
  "zestimate": null,
  "rentZestimate": null,
  "taxAssessedValue": 365588,
  "priceChange": -15000,
  "priceChangeDate": "2026-10-14",
  "brokerName": "T J Lewis Real Estate",
  "photos": null,
  "detailed": false,
  "searchInput": "Austin, TX",
  "searchRank": 1,
  "scrapedAt": "2026-10-22T10:00:00.000Z"
}

Price

Live Apify price on 2026-11-02, per 1,000 rows, by Apify plan. You pay only for rows delivered; error and summary rows marked free in the README cost nothing. Plus $0.001 per GB of memory when a run starts.

Per 1,000FreeBronzeSilverGoldPlatinumDiamond
Property (main)$2.10$1.80$1.50$1.20$1.20$1.20
Property with details$3.20$2.70$2.20$1.50$1.50$1.50

Run it from code or an AI agent

Actor ID arcadium/zillow-properties. Set APIFY_TOKEN to your Apify API token. The input below is the actor’s prefilled example; see the guide for every field.

curl
curl -X POST "https://api.apify.com/v2/acts/arcadium~zillow-properties/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"locations":["Austin, TX"],"maxResultsPerSearch":50}'
JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/zillow-properties').call({
  "locations": [
    "Austin, TX"
  ],
  "maxResultsPerSearch": 50
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Python
# pip install apify-client
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/zillow-properties").call(run_input={
    "locations": ["Austin, TX"],
    "maxResultsPerSearch": 50,
})
items = client.dataset(run.default_dataset_id).list_items().items  # apify-client 3.x returns a Run object
print(items)
MCP
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=arcadium/zillow-properties",
      "headers": {
        "Authorization": "Bearer <APIFY_TOKEN>"
      }
    }
  }
}
LangChain
# pip install langchain-apify   (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("arcadium/zillow-properties")
rows = tool.invoke({"run_input": {
    "locations": ["Austin, TX"],
    "maxResultsPerSearch": 50,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])
LlamaIndex
# pip install llama-index-readers-apify
import os
from llama_index.core import Document, VectorStoreIndex
from llama_index.readers.apify import ApifyActor

reader = ApifyActor(os.environ["APIFY_TOKEN"])
documents = reader.load_data(
    actor_id="arcadium/zillow-properties",
    run_input={
        "locations": ["Austin, TX"],
        "maxResultsPerSearch": 50,
    },
    dataset_mapping_function=lambda item: Document(text=str(item.get("description") or ""), metadata={"url": item.get("url")}),
)
index = VectorStoreIndex.from_documents(documents)
CrewAI
# pip install crewai crewai-tools langchain-apify   (reads APIFY_API_TOKEN from the environment)
from crewai import Agent
from crewai_tools import ApifyActorsTool

tool = ApifyActorsTool(actor_name="arcadium/zillow-properties")
researcher = Agent(
    role="Research analyst",
    goal="Answer with data collected by the tool",
    backstory="Uses public web data.",
    tools=[tool],
)
n8n
{
  "nodes": [
    {
      "name": "Run arcadium/zillow-properties",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        0,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/arcadium~zillow-properties/run-sync-get-dataset-items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "{\"locations\":[\"Austin, TX\"],\"maxResultsPerSearch\":50}",
        "options": {
          "timeout": 300000
        }
      }
    }
  ],
  "connections": {}
}
Google Sheets
// Extensions > Apps Script. Store your token once: Project Settings > Script properties > APIFY_TOKEN.
function importLastRun() {
  const token = PropertiesService.getScriptProperties().getProperty('APIFY_TOKEN');
  const url = 'https://api.apify.com/v2/acts/arcadium~zillow-properties/runs/last/dataset/items?status=SUCCEEDED&clean=true&format=json';
  const res = UrlFetchApp.fetch(url, { headers: { Authorization: 'Bearer ' + token } });
  const rows = JSON.parse(res.getContentText());
  if (!rows.length) return;
  const keys = Object.keys(rows[0]);
  const values = rows.map((r) => keys.map((k) => (typeof r[k] === 'object' ? JSON.stringify(r[k]) : r[k])));
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.clearContents();
  sheet.getRange(1, 1, 1, keys.length).setValues([keys]);
  sheet.getRange(2, 1, values.length, keys.length).setValues(values);
}

Limitations

Related actors

AutoScout24 Scraper

AutoScout24 used cars from 8 EU country sites (make, model, year, km, price, price rating, fuel, power, dealer) for URLs or filters; $0.44 per 1,000 cars.

$0.44 per 1,000 Car listings on the Free plan, down to $0.33 on higher plans