# Zillow Property Search, Price Drops and Detail Lookup (`accountable_eel/zillow-listing-lookup`) Actor

Zillow scraper for US homes by city or zip code: price, beds, baths, Zestimate, broker, photo; for sale, for rent or sold homes. New Zillow listings alert to Slack, price drops on luxury homes in 90210, listings with HOA and tax history. Export a Zillow search to Google Sheets or n8n.

- **URL**: https://apify.com/accountable_eel/zillow-listing-lookup.md
- **Developed by:** [Adriana Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Real estate, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.06 / 1,000 zillow listing returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Zillow Property Search, Price Drops and Detail Lookup

A Zillow scraper for US real estate searches. Type any US city, ZIP code or neighbourhood, paste
any Zillow search link with custom filters, or look up individual homedetails links. Results come
back newest first: property address, asking price, bedrooms, bathrooms, living area, lot size,
year built, days on market, Zestimate, rent Zestimate, brokerage name, main photo and direct URL.
Turn on monitoring and any search becomes a live new-listings alert and price drop tracker, with
direct webhook delivery to Discord, Slack, Telegram or your own API endpoint. No login or browser
automation required. You pay per listing returned.

This actor extracts only publicly visible listing data published on zillow.com. It is an independent
tool and is not affiliated with, endorsed by, or sponsored by Zillow, Inc.

### Who it's for

- **Real estate investors and house flippers** monitoring specific ZIP codes or neighbourhoods
  for new inventory and price reductions before other buyers make an offer.
- **Real estate agents and brokers** compiling daily comp tables, tracking price movements,
  and watching competitor brokerage inventory across their territory.
- **Home buyers and renters** who want an instant Telegram or Discord notification the moment a
  qualifying home hits the market, without constantly refreshing apps.
- **Data analysts and proptech developers** piping structured US property data into Google Sheets,
  n8n, Make, Clay, PostgreSQL or custom valuation models.

### Why this one

- **Monitoring is built in.** Most Zillow scrapers on Apify Store return a one-off snapshot and
  stop. This actor includes a persistent watchlist memory across scheduled runs: it flags new
  listings, price cuts, price rises, and homes that went off-market (sold or withdrawn).
- **Direct webhook notifications.** Connect your Discord webhook, Slack channel, or Telegram
  bot with a single URL. Get rich alert cards delivered as changes happen without building an
  external pipeline.
- **Pay only for real listings found.** Misses, empty searches, price rises and off-market
  notifications are completely free. You only pay for returned listings and optional detail lookups.
- **Brokerage-level contact only.** Respects privacy standards: outputs the listing brokerage firm
  name without scraping personal agent mobile numbers or private emails.
- **Fast HTTP extraction.** Uses server-rendered data payloads rather than slow, resource-heavy
  browser emulation, keeping compute overhead and run times minimal.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `searches` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~zillow-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"searches":["Austin, TX"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

#### Setting up a search

1. In the Input tab, enter one location per line in `searches`: a city and state (`Austin, TX`,
   `Miami, FL`), a 5-digit ZIP code (`90210`, `78701`), or a neighbourhood (`SoHo, New York`).
2. Alternatively, paste any Zillow search URL directly into `searchUrls` to preserve complex
   polygon map filters or specialized criteria.
3. Choose the listing status: **For sale** (default), **For rent**, or **Recently sold**.
4. Set optional filters: minimum/maximum price, bedroom and bathroom counts, and property type
   (single family, multi-family, condo, townhouse, manufactured, lot/land, apartment).
5. Set `maxListings` to your budget limit (default 40 listings per search).
6. To enable change alerts, tick **Delta mode** under Monitoring and configure your schedule.

### Input

```json
{
  "searches": [
    "Austin, TX"
  ]
}
```

One per line: a city, ZIP code or neighbourhood ('Austin, TX', '90210', 'SoHo, New York'), a zillow.com search URL, or a homedetails property link. Accepted formats: Austin, TX, 90210, https://www.zillow.com/austin-tx/, https://www.zillow.com/homedetails/123-Main-St-Austin-TX-78701/12345678_zpid/.

#### Filtering and monitoring examples

**1. Finding single family homes under $500,000 in Austin, TX:**

```json
{
  "searches": ["Austin, TX"],
  "status": "for_sale",
  "maxPrice": 500000,
  "homeType": "single_family",
  "minBeds": 3,
  "minBaths": 2
}
```

**2. Monitoring luxury rentals in Beverly Hills with Discord alerts:**

```json
{
  "searches": ["90210"],
  "status": "for_rent",
  "minPrice": 5000,
  "deltaMode": true,
  "alertOnPriceDrop": true,
  "notifyUrl": "https://discord.com/api/webhooks/YOUR_WEBHOOK_URL"
}
```

**3. Detailed property inspection including price and tax history:**

```json
{
  "listingUrls": [
    "https://www.zillow.com/homedetails/123-Main-St-Austin-TX-78701/12345678_zpid/"
  ],
  "includeDetails": true
}
```

### Output

One row per property listing. Each row contains core property attributes, pricing, market metrics,
and change tracking metadata:

| Field | Description |
|---|---|
| `zpid`, `url` | Zillow unique property identifier and canonical listing URL |
| `streetAddress`, `city`, `state`, `zipcode` | Full property address components |
| `latitude`, `longitude` | Geographic coordinates |
| `price`, `priceChange`, `statusText` | Asking price in USD, recent price change amount, and listing status |
| `beds`, `baths`, `livingArea`, `lotArea` | Bedrooms, bathrooms, square footage, and lot size |
| `homeType`, `yearBuilt`, `daysOnZillow` | Property style, construction year, and cumulative days on market |
| `zestimate`, `rentZestimate` | Zillow estimated market value and estimated monthly rental value |
| `brokerName`, `photo` | Listing brokerage firm name and primary high-resolution photograph URL |
| `description`, `priceHistory`, `taxHistory` | Extended property details (populated when `includeDetails` is enabled) |
| `monthlyHoaFee`, `schools` | Monthly HOA assessment and nearby school ratings (with details enabled) |
| `changeType`, `previousPrice`, `priceDeltaPct` | Watchlist change status (`new`, `price-drop`, `price-rise`, `gone`) |
| `firstSeenAt`, `lastSeenAt`, `daysListed` | Watchlist timestamps and duration |

| query | found | status | searchUrl | totalAvailable | listingCount | detailCount | truncated | newCount | priceDropCount | priceRiseCount | goneCount | monitorStatus | medianPrice | properties | zpid | url | streetAddress | city | state | zipcode | latitude | longitude | price | priceChange | statusText | beds | baths | livingArea | lotArea | homeType | yearBuilt | daysOnZillow | zestimate | rentZestimate | brokerName | photo | description | priceHistory | taxHistory | monthlyHoaFee | schools | changeType | previousPrice | priceDeltaPct | firstSeenAt | lastSeenAt | daysListed | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Austin, TX | true | OK | <search link on zillow> | <total matching on zillow> | \<listings returned (billed)> | \<detail fetches (billed)> | <more results were available> | <new listings this run> | <price drops this run> | <price rises this run> | <gone listings this run> | <monitoring status> | <median asking price of this search> | \<all listings found (full list)> | \<zillow property id (zpid)> | <listing link> | <street address> | <city> | <state> | <zip code> | <latitude> | <longitude> | \<asking price (usd)> | <price change> | <listing status> | <bedrooms> | <bathrooms> | \<living area (sq ft)> | \<lot area (sq ft)> | <property type> | <year built> | <days on zillow> | <zestimate valuation> | <rent zestimate> | <listing brokerage name> | <main listing photo> | <property description> | <price change history> | <property tax history> | <monthly hoa fee> | <nearby school ratings> | \<change type (new, price-drop, gone)> | <previous price> | <price change percentage> | <first seen on watchlist> | <last seen on watchlist> | <days listed> | 1970-01-01T00:00:00.000Z |

### Monitoring: only what changed

When `deltaMode` is enabled, the actor turns each search into a continuous watchlist backed by a
persistent named key-value store on your Apify account (`zillow-listing-lookup-delta`).

- **New listings (`changeType: "new"`)**: Properties appearing on the market for the first time since
  the previous run.
- **Price drops (`changeType: "price-drop"`)**: Properties whose asking price fell by at least
  `minPriceChangePct` (default 0.5%).
- **Price rises (`changeType: "price-rise"`)**: Properties whose asking price increased. Returned free.
- **Off-market homes (`changeType: "gone"`)**: Properties that disappeared from the active search window
  (sold, pending, or withdrawn). Returned free.
- **Unchanged listings**: Automatically filtered out so you are never billed for duplicate observations.

Use `alertOnNewOnly` or `alertOnPriceDrop` to narrow alerts to specific events, or enable `skipFirstRun`
to prime the watchlist memory silently without triggering initial notifications.

### Integrations and webhooks

Export or stream listing records directly into third-party tools:

- **Discord & Slack**: Pass a webhook URL in `notifyUrl` to receive rich formatted alert cards in your team chat.
- **Telegram**: Pass `https://api.telegram.org/bot<TOKEN>/sendMessage?chat_id=<CHAT_ID>` in `notifyUrl`.
- **Google Sheets / Airtable**: Use Apify's native integrations to append each row to a spreadsheet on run completion.
- **n8n / Make / Zapier**: Trigger downstream workflows via run webhooks or periodic dataset pulls.

# Actor input Schema

## `searches` (type: `array`):

One per line: a city, ZIP code or neighbourhood ('Austin, TX', '90210', 'SoHo, New York'), a zillow.com search URL, or a homedetails property link. Accepted formats: Austin, TX, 90210, https://www.zillow.com/austin-tx/, https://www.zillow.com/homedetails/123-Main-St-Austin-TX-78701/12345678_zpid/. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

## `excludeKeywords` (type: `array`):

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

## `maxResults` (type: `integer`):

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `status` (type: `string`):

Choose whether to search properties for sale, rentals, or recently sold homes.

## `maxListings` (type: `integer`):

Newest first. You pay per listing returned, so this controls your maximum budget per search.

## `minPrice` (type: `integer`):

Optional lower price bound in US dollars. For rentals this is monthly rent.

## `maxPrice` (type: `integer`):

Optional upper price bound in US dollars. For rentals this is monthly rent.

## `minBeds` (type: `integer`):

Optional minimum number of bedrooms. Homes with fewer bedrooms are excluded.

## `minBaths` (type: `integer`):

Optional minimum number of bathrooms. Homes with fewer bathrooms are excluded.

## `homeType` (type: `string`):

Optional property style filter. Leave on Any type to include all property categories.

## `includeDetails` (type: `boolean`):

Fetches each listing's full property detail page. Billed as a separate detail event per property.

## `deltaMode` (type: `boolean`):

Turns a search into a watchlist. Unchanged listings are removed before billing. Price rises and gone listings are free.

## `deltaName` (type: `string`):

Leave empty to derive from filters, or enter a custom name to pin watchlist memory across filter adjustments.

## `alertOnNewOnly` (type: `boolean`):

With monitoring on and this ticked, return only listings the watchlist has never seen before.

## `alertOnPriceDrop` (type: `boolean`):

With monitoring on and this ticked, return only listings whose asking price dropped.

## `minPriceChangePct` (type: `number`):

A listing must change in price by at least this percentage to count as a price drop or rise.

## `skipFirstRun` (type: `boolean`):

The first run remembers current listings without returning or billing them. Alerts begin on the second run.

## `notifyUrl` (type: `string`):

Optional secret webhook link. New listings, price reductions and gone properties are posted directly to your chat.

## `quietRunOutput` (type: `boolean`):

With monitoring on and this ticked, a run where no listings changed writes nothing to the dataset.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

## `expandRows` (type: `boolean`):

When on, each listing found gets its own row instead of being grouped under its listing. You're still only charged once per listing, no matter how many rows it produces.

## `maxConcurrency` (type: `integer`):

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

## `proxyConfiguration` (type: `object`):

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "searches": [
    "Austin, TX"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "status": "for_sale",
  "maxListings": 40,
  "homeType": "",
  "includeDetails": false,
  "deltaMode": false,
  "deltaName": "",
  "alertOnNewOnly": false,
  "alertOnPriceDrop": false,
  "minPriceChangePct": 0.5,
  "skipFirstRun": false,
  "notifyUrl": "",
  "quietRunOutput": false,
  "columns": [
    "searchUrl",
    "totalAvailable",
    "listingCount",
    "detailCount",
    "truncated",
    "newCount",
    "priceDropCount",
    "priceRiseCount",
    "goneCount",
    "monitorStatus",
    "medianPrice",
    "properties",
    "zpid",
    "url",
    "streetAddress",
    "city",
    "state",
    "zipcode",
    "latitude",
    "longitude",
    "price",
    "priceChange",
    "statusText",
    "beds",
    "baths",
    "livingArea",
    "lotArea",
    "homeType",
    "yearBuilt",
    "daysOnZillow",
    "zestimate",
    "rentZestimate",
    "brokerName",
    "photo",
    "description",
    "priceHistory",
    "taxHistory",
    "monthlyHoaFee",
    "schools",
    "changeType",
    "previousPrice",
    "priceDeltaPct",
    "firstSeenAt",
    "lastSeenAt",
    "daysListed"
  ],
  "expandRows": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searches": [
        "Austin, TX"
    ],
    "includeKeywords": [],
    "excludeKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/zillow-listing-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searches": ["Austin, TX"],
    "includeKeywords": [],
    "excludeKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/zillow-listing-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searches": [
    "Austin, TX"
  ],
  "includeKeywords": [],
  "excludeKeywords": []
}' |
apify call accountable_eel/zillow-listing-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/zillow-listing-lookup"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/DrOFssZxLpCqhS4ar/builds/PGcdZgUGmEc9lUPq2/openapi.json
