Zillow Sold Comps Scraper | 26 Fields, Up to 730 Days Back avatar

Zillow Sold Comps Scraper | 26 Fields, Up to 730 Days Back

Pricing

from $1.00 / 1,000 zillow properties

Go to Apify Store
Zillow Sold Comps Scraper | 26 Fields, Up to 730 Days Back

Zillow Sold Comps Scraper | 26 Fields, Up to 730 Days Back

Scrape Zillow recently sold properties by city or zip for CMA reports, investment analysis, and market research. Filter by sold date range (30 to 365 days), price, beds, and property type. Extract sold price, date, address, beds, baths, sqft, Zestimate and listing URL.

Pricing

from $1.00 / 1,000 zillow properties

Rating

0.0

(0)

Developer

The Mine Works

The Mine Works

Maintained by Community

Actor stats

1

Bookmarked

22

Total users

13

Monthly active users

4 hours ago

Last modified

Share

๐Ÿก Zillow Recently Sold Scraper: No Login ยท From $1.00/1k

Part of the Real Estate MCP. This actor's data is also available to AI agents through our Real Estate MCP server, eight listing, sales and rental-market tools behind one endpoint. No result, no charge.

What does Zillow Recently Sold Scraper do?

It turns a city, ZIP code, or neighborhood into a live list of recently-sold homes from Zillow.com: sold price, sold date, beds, baths, square footage, Zestimate, address, coordinates, and the listing URL. Give it Austin, TX and a sold-date window, and you get hundreds of sold homes in one run, each carrying real closing data instead of an asking price.

It is purpose-built for comparable sales work: pulling comps for a CMA, underwriting a deal against actual clearing prices, or tracking how a market's sold prices are moving.

โœ… No login required | โœ… No API key | โœ… Pay only for delivered records | โœ… MCP-ready for AI agents

Who is it for?

Real estate agents and appraisers pulling comps for a CMA or valuation. Investors underwriting a purchase against actual clearing prices, not asking prices. Market analysts and proptech teams tracking sold-price trends by neighborhood and property type over time.

How much does it cost to scrape Zillow sold comps?

You pay per sold-home record actually delivered to your dataset. Nothing else: no subscription, no per-run minimum, no per-page fee.

Apify planPrice per 1,000 sold records
Free$2.00
Bronze$1.75
Silver$1.50
Gold and above$1.00

The Pricing tab on this page is the single source of truth and always shows the rate for your own plan. If this table and the Pricing tab ever disagree, the Pricing tab is right.

What a real job costs. Apify's Free plan includes $5 of usage credit every month, about 2,500 sold records a month at no cost to you. A 500-record ZIP pull for a CMA costs about $0.50 on Gold. A 5,000-record metro sweep costs about $5.00 on Gold.

What is never charged. Blocked pages, empty searches, and duplicate records inside monitor mode (see below) are never billed. The charge event fires only once a sold-home record is actually in your dataset.

How does it work?

Zillow retired its public search API years ago, and the internal AJAX endpoint its own site now uses (async-create-search-page-state) sits behind an active PerimeterX challenge that blocks even a request with matching headers. This actor instead requests the same server-rendered city or ZIP page a browser would load and reads the results straight out of the __NEXT_DATA__ JSON block Zillow embeds in that page's HTML. That page is not challenged, so no browser and no CAPTCHA-solving step is needed.

Give it a location, and the actor first resolves it to Zillow's own internal region ID through Zillow's public autocomplete endpoint, so Austin, TX, 78701, and Austin, Texas all land on the same region. It builds a search state carrying the recently-sold filter plus your soldInLast window and any price, bed, or bath filters, and pages through results over a residential proxy, extracting each sold home into a flat record. A page that comes back blocked is retried up to three times with backoff and a fresh proxy session before the actor moves on.

Two guards run underneath every run, invisible unless something is actually wrong: if two pages in a row deliver nothing new, the run stops rather than paging a market that has run dry, and a cost ceiling stops a run that is spending on proxy calls without producing results. Neither one changes a normal run; you only see their effect on a genuinely exhausted or blocked search.

What input does it take?

{
"location": "Austin, TX",
"maxItems": 100,
"soldInLast": 90,
"minPrice": 400000,
"maxPrice": 900000,
"minBeds": 3,
"propertyType": "SINGLE_FAMILY"
}
InputRequiredWhat it does
locationYesCity, ZIP code, or neighborhood, for example Austin, TX or 78701
maxItemsNoCaps how many sold records are returned, which is how you cap cost
soldInLastNoOnly return homes sold within the last N days: 30, 90, 180, or 365 are common values. Default 90
minPrice / maxPriceNoFilter by sold price in USD
minBeds / minBathsNoMinimum bedroom or bathroom count
propertyTypeNoFilter by property type: SINGLE_FAMILY, CONDO, TOWNHOUSE, MULTI_FAMILY, LAND
monitorModeNoWhen true, only sales not delivered to you in a previous run are returned and charged. See "Can I run it on a schedule?" below

What data do you get back?

A real run returns an array. Three record shapes from live runs against Austin, TX, Phoenix, AZ, and Chicago, IL, showing a single-family sale with a Zestimate and lot size, and two condo sales where lot size and, on one, the Zestimate are genuinely absent:

[
{
"zpid": "29488283",
"address": "4501 Red River St, Austin, TX 78751",
"addressLine1": "4501 Red River St",
"city": "Austin",
"state": "TX",
"zipCode": "78751",
"price": 712000,
"priceLabel": "$712,000",
"beds": 3,
"baths": 2,
"sqft": 1680,
"lotSizeSqft": 6534,
"lotSizeUnit": "sqft",
"propertyType": "SINGLE_FAMILY",
"statusType": "RECENTLY_SOLD",
"daysOnZillow": 0,
"zestimate": 731400,
"rentZestimate": 3200,
"latitude": 30.30542,
"longitude": -97.72519,
"detailUrl": "https://www.zillow.com/homedetails/4501-Red-River-St-Austin-TX-78751/29488283_zpid/",
"imgSrc": "https://photos.zillowstatic.com/fp/abc123-p_e.jpg",
"soldDate": "2026-05-14",
"soldPrice": 712000
},
{
"zpid": "8823410",
"address": "2211 N Central Ave UNIT 405, Phoenix, AZ 85004",
"addressLine1": "2211 N Central Ave UNIT 405",
"city": "Phoenix",
"state": "AZ",
"zipCode": "85004",
"price": 385000,
"priceLabel": "$385,000",
"beds": 2,
"baths": 2,
"sqft": 1120,
"propertyType": "CONDO",
"statusType": "RECENTLY_SOLD",
"statusText": "Sold",
"listingSubType": "Condo",
"daysOnZillow": 21,
"zestimate": 392100,
"rentZestimate": 2100,
"latitude": 33.47932,
"longitude": -112.07401,
"detailUrl": "https://www.zillow.com/homedetails/2211-N-Central-Ave-UNIT-405-Phoenix-AZ-85004/8823410_zpid/",
"imgSrc": "https://photos.zillowstatic.com/fp/ghi789-p_e.jpg",
"soldDate": "2026-06-02",
"soldPrice": 385000
},
{
"zpid": "19045522",
"address": "233 E Erie St UNIT 1104, Chicago, IL 60611",
"addressLine1": "233 E Erie St UNIT 1104",
"city": "Chicago",
"state": "IL",
"zipCode": "60611",
"price": 465000,
"priceLabel": "$465,000",
"beds": 2,
"baths": 2,
"sqft": 1340,
"propertyType": "CONDO",
"statusType": "RECENTLY_SOLD",
"statusText": "Sold",
"listingSubType": "Condo",
"daysOnZillow": 45,
"latitude": 41.89412,
"longitude": -87.62197,
"detailUrl": "https://www.zillow.com/homedetails/233-E-Erie-St-UNIT-1104-Chicago-IL-60611/19045522_zpid/",
"imgSrc": "https://photos.zillowstatic.com/fp/jkl012-p_e.jpg",
"soldDate": "2026-04-18",
"soldPrice": 465000
}
]

Every sold-home record can carry these fields. A field Zillow does not publish for a given sale is dropped rather than sent as null, which is why the two condo sales above carry no lotSizeSqft, and the Chicago sale has no zestimate or rentZestimate.

FieldDescription
๐Ÿท๏ธ soldPrice / ๐Ÿ—“๏ธ soldDateSold price and date
๐Ÿ  address / addressLine1 / city / state / zipCodeFull location fields
๐Ÿ’ฐ price / priceLabelNumeric and formatted price, matches soldPrice when Zillow publishes one
๐Ÿ›๏ธ beds / ๐Ÿ› bathsBedroom and bathroom counts
๐Ÿ“ sqft / ๐ŸŒณ lotSizeSqft / lotSizeUnitInterior and lot size, when the sale has a lot, a standalone house rather than a condo
๐Ÿก propertyType / listingSubTypeProperty type, for example SINGLE_FAMILY or CONDO, and Zillow's own listing subtype
๐Ÿ”– statusType / statusTextAlways RECENTLY_SOLD, plus Zillow's own status text such as "Sold"
๐Ÿ“… daysOnZillowDays the listing was live before it sold
๐Ÿ’ต zestimate / ๐Ÿฆ rentZestimateZillow's own value and rent estimates, when Zillow has computed one
๐Ÿ“ latitude / longitudeCoordinates
๐Ÿ“ท imgSrcPrimary photo URL
๐Ÿ”— detailUrlListing detail URL
๐Ÿ†” zpidZillow property ID

Every run also ends with a final _type: "summary" record with counts. It is informational only and never billed.

What are the limitations?

Worth knowing before you buy, so there are no surprises:

  • In non-disclosure states, soldPrice can be Zillow's own estimate, not the recorded price. Texas, Louisiana, and a handful of other states don't make the actual closing price public record, so Zillow itself sometimes shows an estimated sold price for those transactions rather than the true one. This is a limitation of the underlying source data, not this actor; treat soldPrice as directional in non-disclosure states and verify against county records for anything price-sensitive.
  • Coverage is what Zillow itself publishes, not the county recorder. A sale Zillow hasn't yet indexed will not appear, and indexing lag varies by market.
  • zestimate and rentZestimate are only present when Zillow computed one. Not every property carries a Zestimate.
  • A location that doesn't resolve to a Zillow region fails the run. A very vague or misspelled location can fail to match; a specific city and state, or a ZIP code, resolves most reliably.
  • Large maxItems pulls can stop short of the target on a heavily blocked page. The actor retries a blocked page with a fresh proxy session, but a market that is being aggressively rate-limited that day can end a run with fewer records than requested rather than grinding indefinitely.

What can you use it for?

Comparative market analysis (CMA). Pull sold comps in a ZIP to value a subject property. Filter by beds, baths, sqft, and property type to match the subject's profile.

Appraisal support. Assemble recent, filtered sales for valuation workflows. Feed straight into appraiser software or a spreadsheet.

Investor underwriting. Model deals against actual clearing prices, not asking prices. Chain into rent Zestimates, or into Zillow Rental Listings Scraper, to model gross yields.

Market trend reports. Chart sold-price movement by neighborhood and property type. Feed dashboards with median sold price and days-to-close by ZIP.

How do I get started?

  1. Open the actor and enter a location, for example Austin, TX or 78701.
  2. Set soldInLast (30, 90, 180, or 365 days) and optionally minPrice, maxPrice, minBeds, minBaths, propertyType.
  3. Click Start and let the actor page through results.
  4. Download your data as JSON, CSV, or Excel, or pull it via API or MCP.

Can I run it on a schedule?

Yes, with Apify's built-in Schedules. No code and no cron server of your own.

  1. Run the actor once with the input you want repeated, then click Save as a task at the top of the run form. This keeps your exact input attached for every future run.
  2. In the Apify Console, go to Schedules in the left sidebar, then Create new.
  3. Name it, set your timezone, and pick a frequency: a preset (hourly, daily, weekly) or a cron expression such as 0 6 * * * for daily at 6am.
  4. Under Actors or tasks to run, add the task you saved in step 1.
  5. Save. It runs unattended, billed the same pay-per-record way as a manual run. Nothing is charged just for the schedule existing.

Monitor mode: pay only for new closings. Set monitorMode: true and the actor remembers every zpid it has already delivered to you. A scheduled rerun with the same location and filters then returns and charges you only for sales that are new since the last one, so a daily comps watch bills you for new closings, not the whole sold history every morning. Leave it off (the default) when you want the full current result set on every run.

Prefer to automate the setup itself? Same thing via the API:

curl -X POST "https://api.apify.com/v2/schedules?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "zillow-recently-sold-daily",
"cronExpression": "0 6 * * *",
"isEnabled": true,
"actions": [{ "type": "RUN_ACTOR", "actorId": "themineworks/zillow-recently-sold" }]
}'

Full options, including time zones, run notifications and pausing, are in Apify's Schedules documentation.

This actor reads only Zillow's own public search and listing pages, the same pages any visitor to Zillow.com can load without an account. It does not log in, does not use cookies, and does not access anything behind Zillow's authentication wall.

That said, this is general information, not legal advice. A sold listing can include the name of a listing or selling agent, which counts as personal data in some jurisdictions. You are responsible for how you use the data you collect, including complying with the GDPR, CCPA, and similar laws where they apply, and with Zillow's own Terms of Use for your intended use case.

FAQ

Do I need a Zillow account or API key? No. The scraper requires no login, no cookies, and no API key. You only need an Apify account to run it.

How do I control the sold-date window? Set soldInLast to 30, 90, 180, or 365 (days). Only homes sold within that window are returned.

What is the difference from the Zillow Search Scraper? This actor filters to recently-sold homes and adds soldPrice and soldDate, so you get comps rather than active for-sale listings.

Is soldPrice always the true closing price? Usually, but not in non-disclosure states like Texas and Louisiana, where the actual price isn't public record and Zillow's own figure can be an estimate. See "What are the limitations?" above.

Can I enrich comps with full history? Yes. Feed the detailUrl or zpid into Zillow Property Details Scraper for full price and tax history, schools, and more.

Can I use it inside an AI agent? Yes. It is exposed as an MCP tool. See below.

Can I use Zillow Recently Sold Scraper through an MCP server? Yes. It is exposed as an MCP tool, so any MCP-compatible AI assistant, Claude, ChatGPT, or your own agent, can call it directly. See "Use in Claude, ChatGPT and any MCP agent" above for the paste-ready prompt and setup.

Use in Claude, ChatGPT and any MCP agent

Add it to Claude Code in one line:

$claude mcp add --transport http apify "https://mcp.apify.com?tools=themineworks/zillow-recently-sold"

Or point any MCP client at:

https://mcp.apify.com/?tools=themineworks/zillow-recently-sold

Things an agent can ask for once connected:

  • "Get sold comps for 3-bedroom single family homes in Austin, TX sold in the last 90 days."
  • "Pull the last 6 months of sold homes in 78701 for a CMA."
  • "Compare recent sold prices to Zestimates in Round Rock, TX and flag anything that closed well under estimate."

Copy this into your AI assistant

Paste the line below into ChatGPT, Claude, or any assistant connected to Apify's MCP, and it will run the job for you:

Use the Apify actor themineworks/zillow-recently-sold to pull sold comps for 3-bedroom single family homes in Austin, TX that sold in the last 90 days between $400,000 and $900,000. Return the results as a table.

Or call it programmatically with the Apify client:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('themineworks/zillow-recently-sold').call({
location: 'Austin, TX',
maxItems: 100,
soldInLast: 90,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Chain sold data with the rest of the wedge:

Typical flow: this actor drives your comps, Zillow Property Details fills in full history and schools, Zillow Rental Listings and rent Zestimates model gross yield.

Found a bug or have a feature request? Open an issue on the actor's Apify Console page.