Investor and deal tools
Pull recent sales near a property to check the price before an offer, with $/sq ft on every row.
Homes for sale, sold homes, rentals and full price history from Zillow, as typed JSON. Built for proptech apps, investor tools and AI agents.
100 free credits · No credit card required
Search homes for sale, sold homes and rentals by ZIP, city, map box or radius. Look up one home by address for its facts and full history. Every row links back to its source.
curl -G https://api.realtycrawl.com/v1/zillow/sold \ -H "Authorization: Bearer $REALTYCRAWL_KEY" \ -d zip=80221 \ -d sold_within_days=90{ "request_id": "req_01JA4X9EXAMPLE", "status": "complete", "credits": 1, "cached": false, "poll_url": null, "error": null, "result": { "source": "zillow", "query": { "zip": "80221", "sold_within_days": 90 }, "count": 1, "reported_total": null, "next_cursor": "c1.eyJ2IjoxfQ.example", "collected_at": "2026-10-12T20:31:05Z", "schema_version": 1, "completeness": "complete", "summary": { "priced_count": 1, "disclosed_count": 0, "median_sale_price": 450000, "p25": 450000, "p75": 450000, "median_price_per_sqft": 265, "earliest_sold_date": "2026-10-09", "latest_sold_date": "2026-10-09" }, "data": [ { "source": "zillow", "source_id": "12998656", "source_url": "https://www.zillow.com/homedetails/2041-Samuel-Dr-Denver-CO-80221/12998656_zpid/", "sold_date": "2026-10-09", "sale_price": { "amount": 450000, "currency": "USD" }, "sale_price_disclosure": "unknown", "list_price": null, "list_date": null, "sale_to_list_ratio": null, "days_on_market": null, "price_per_sqft": 265, "beds": 3, "baths": 2, "living_area_sqft": 1700, "property_type": "single_family", "address": { "line1": "2041 Samuel Drive", "unit": null, "city": "Denver", "state": "CO", "zip": "80221", "county": null, "county_fips": null }, "location": { "lat": 39.831684, "lng": -105.01129 }, "broker_name": "LPT Realty", "extras": { "home_type_raw": "SINGLE_FAMILY", "days_on_zillow": 3, "zestimate": { "amount": 446500, "currency": "USD" }, "rent_zestimate": { "amount": 2567, "currency": "USD" }, "tax_assessed_value": { "amount": 421000, "currency": "USD" } } } ], "field_notes": [ { "field": "list_price", "reason": "not_on_search_page", "detail": "Zillow's sold search does not show the last asking price. Call `property` for the full price history." }, { "field": "days_on_market", "reason": "not_on_search_page", "detail": "Zillow's sold search shows days since the sale, not days on market. That number is in `extras.days_on_zillow`. Call `property` for listing and sale dates." } ] }}Zillow closed its public API in 2021. What's left is approval-only feeds, raw source JSON, or a scraper you maintain yourself. RealtyCrawl returns typed rows you can build on, with a public status page fed by real calls.
One route at a time: Zillow homes for sale · Zillow sold homes · Zillow rentals · Zillow property details · Zillow estimate
Rival details checked October 2026. RealtyCrawl is not affiliated with Zillow.
Try it on your own ZIP. Start with 100 free credits, no card or Zillow login.
Get a free API keyHome data sits on portals with no open API. RealtyCrawl gives your product the same facts buyers see, without building and fixing scrapers yourself.
Pull recent sales near a property to check the price before an offer, with $/sq ft on every row.
Show buyers and owners a home's facts, price history and county tax record in your own product.
Compare rents across single homes and apartment buildings in an area, with each building's unit list.
Track median sale price and price per square foot by ZIP from the summary on every sold search.
Check a home's size, year built, last sale and tax history from one address lookup.
Let your agent look up sold homes and price history, with a link to the source for every row.
Every source fills the same core fields. Facts only: no listing photos and no copied descriptions. Zillow's Zestimate is labeled as Zillow's, never as ours.
Get a key, send one command, then poll the job it returns for the result. We handle collecting the data, so you never maintain a scraper.
Search homes for sale, sold homes and rentals on Zillow, and look up one home's facts, history and estimate. Each new source gets its own routes, so yours never change.
Every source returns the same core fields with the same names and types. Generate a typed client from the OpenAPI spec.
Connect Claude, Cursor or VS Code to the hosted MCP server, or give your agent llms.txt and the Markdown docs.
A field we can't fill is null, never missing and never guessed. field_notes says why, so a hidden sold price stays hidden.
Failed calls and pages past the end are free. Every response shows exactly what it cost.
Every error has a code your code can check, for bad inputs, limits and temporary failures. Every response has a request ID for support.
curl -G https://api.realtycrawl.com/v1/zillow/sold \ -H "Authorization: Bearer $REALTYCRAWL_KEY" \ -d zip=80221 \ -d sold_within_days=90Connect your assistant to the hosted MCP server with one URL and your API key. It searches sold homes, listings and rentals, waits for the results and links every row.
What have homes in 80221 sold for in the last 90 days?
2041 Samuel Drive sold on Oct 9, 2026 for $450,000, about $265 per square foot.
claude mcp add --transport http realtycrawl https://api.realtycrawl.com/mcp \ --header "Authorization: Bearer $REALTYCRAWL_KEY"One prompt gives your assistant the endpoint, the sign-in header and how to wait for a result, so its first script works. Get a free key and you have sold homes in your app in minutes.
I'm building with the RealtyCrawl API. It returns real-estate data from Zillow as typed JSON: homes for sale, sold homes, rentals and property history. Read the docs first: https://realtycrawl.com/llms.txt OpenAPI spec: https://realtycrawl.com/openapi.json Rules for the code you write: - Base URL: https://api.realtycrawl.com/v1 - Auth: send the header "Authorization: Bearer <key>". Read the key from the REALTYCRAWL_KEY environment variable. Never put it in browser code. - Zillow sold homes: GET /zillow/sold?zip=<5-digit ZIP>&sold_within_days=90. You can send city and state instead of zip. - A call often answers 202 with status "pending" and a poll_url. Poll GET /jobs/<request_id>?wait=20 with the same header until status is "complete" or "failed". - The rows are in result.data, each with address, sale_price, sold_date, sale_price_disclosure and source_url. sale_price is null when the price isn't public; result.field_notes says why. Never replace a null with a guess. - result.summary has median_sale_price and median_price_per_sqft. For the next page, send result.next_cursor as cursor. - A search costs 1 credit and property details cost 2. A free account starts with 100 credits that do not refill, so save results while testing instead of repeating a call. Start with a short script that prints the median sale price for ZIP "80221". Then ask me what I want to build.
Every plan includes every route. A search costs 1 credit and property details cost 2. Failed calls are free, and you can change plans any time.
For trying every route and building a first version.
For side projects, scripts and personal deal sheets.
For tools that check a market every day.
For apps that pull comps and history every day.
For products built on property data at real volume.
Need more than 50,000 credits a month? Scale is $399 for 250,000. Contact us
Still wondering about something? Email support@realtycrawl.com and a person will reply.
Not one you can sign up for. Zillow closed its public API in 2021. Its Bridge feeds need approval and an MLS or broker tie.
RealtyCrawl gives you Zillow homes for sale, sold homes, rentals, property details and Zestimates as typed JSON, with a key you can get today. RealtyCrawl is not affiliated with Zillow.
From public pages on each source, collected signed out. We never need your Zillow login.
Every row has source and source_url, so anyone can check it. We return facts only: no listing photos and no copied descriptions.
Some states don't make sale prices public: AK, ID, KS, LA, MS, MT, ND, NM, TX, UT, WY, and parts of MO. When a price isn't shown, sale_price is null and field_notes says why.
We never fill a missing sale price with a list price or an estimate. Every sold row has sale_price_disclosure, so you know how the price is known.
Size, type, year built, lot, listing agent and brokerage, the last sale, the county tax record, and the full price history with event labels like listed, price_change, pending and sold. It also has the tax history by year.
It works for sold and off-market homes too. If the history can't be read on a call, the facts still come back with completeness: partial and a field note.
No. The Zestimate and Rent Zestimate are Zillow's estimates. We pass them through labeled source: zillow and don't make our own.
Yes. Single homes and apartment buildings both come back from the rentals route. A building is one row with its lowest rent and a unit list in extras.units.
A cache hit answers 200 with the rows. Otherwise you get 202 and a poll_url. Poll it with ?wait=20 until status is complete or failed.
Each result has collected_at, so you can see how fresh it is. Large areas are split into smaller map boxes behind next_cursor, so you can keep paging past the site's result cap.
A search for homes for sale, sold homes or rentals costs 1 credit, including a cache hit. Property details cost 2, and an estimate costs 1.
Failed calls are free, and so is a page past the last one. Polling a job is free, but it counts toward your calls per minute. Send an Idempotency-Key when you retry, so you're only charged once.
Zillow in the US today. Realtor.com and Redfin are next, then sources outside the US.
Each source gets its own routes, like /v1/zillow/sold, and every source returns the same core fields. Adding a source never changes the routes you already use.
Yes. Connect Claude, Cursor, VS Code or any MCP client to the hosted MCP server with your key. Each route is a typed tool, like zillow_sold. Agents can also read llms.txt and the OpenAPI spec.
Create a free account, make a key, and send your first request in about two minutes. Start with 100 free credits, no card.