SheetMagicSheetMagic

Export Zillow Listings to Google Sheets and Spot Price Cuts

Paste a Zillow search URL into =ZILLOWSEARCH() and get one row per home in Google Sheets: price, Zestimate, days on Zillow, price reductions and more. 100 listings is one formula and 600 scraping credits instead of an evening of copying.

Phil Nguyen · 7 min read

Run your search on zillow.com, nudge the map, copy the URL from the address bar, and put =ZILLOWSEARCH("your-url") in a cell. SheetMagic writes the listings to a results tab in the sheet, one row per home, so you can sort a whole zip code by price cuts, days on market and Zestimate instead of clicking through listings one at a time.

Picture an investor watching one zip code. If copying a listing by hand, with price, beds, sqft and days on market, takes about a minute, 100 listings is roughly 100 minutes every time they want a fresh look. =ZILLOWSEARCH(A1, , 100) returns the same 100 rows for 600 scraping credits (6 per listing), with columns a manual copy usually skips, like Zestimate and Price Reduction.

That is the whole workflow. The rest of this guide covers the one rule that trips people up (the URL), the columns you get, and how many scraping credits a search costs.

Which Zillow URL does ZILLOWSEARCH need?

ZILLOWSEARCH needs a Zillow search-results URL that contains ?searchQueryState=.... A bare category URL such as https://www.zillow.com/homes/for_sale/Austin,-TX_rb/ is rejected, and so is a plain city name like "Austin TX".

To get a URL that works:

  1. Go to zillow.com and run the search you want: type the location and pick For Sale, For Rent or Sold.
  2. Set any filters (price, beds, home type).
  3. Drag or zoom the map slightly. Zillow only rewrites the address bar once the map moves.
  4. Copy the whole URL from the address bar. It will contain ?searchQueryState=.

If you copy the URL before touching the map, it can carry a searchQueryState with no map area in it. SheetMagic checks for this and writes an #ERROR message into the cell instead of running the search, and it does this before any credits are reserved. The fix is the same: reopen the search, drag the map, and copy the URL again.

The URL also has to be on zillow.com. Any other site is rejected with a message asking for a zillow.com search URL.

How do you filter by price, beds or sold homes?

Set every filter on zillow.com before you copy the URL. Price, beds, baths, home type and sold versus for sale all travel inside the URL, and ZILLOWSEARCH has no separate filter arguments.

The URL also decides the mode. Rental listings come from a rentals or for-rent search, and sold comps come from a sold search.

What columns do you get?

Each listing becomes one row with these columns:

GroupColumns
LocationAddress, City, State, Zip, Latitude, Longitude
HomePrice, Beds, Baths, Sqft, Lot Size, Home Type
ListingStatus, Days on Zillow, ZPID, URL
ValuationZestimate, Rent Zestimate, Tax Assessed Value
Price historyPrice Reduction, Price Change, Price Changed
FlagsFor Sale By Owner, Foreclosure, New Construction, Open House
MediaPhoto Count, Main Photo

Two things to know when you read the numbers:

  • Price is the sale price on for-sale and sold searches, and the monthly rent on rental searches. Label your tabs so you remember which mode you ran.
  • Lot Size is blank for condos, apartments and to-be-built plans. That is normal, not a failed scrape.

Home Type is cleaned up for you, so Zillow's SINGLE_FAMILY code shows as "Single Family".

What are the extraction methods?

ZILLOWSEARCH takes an optional second argument that controls how the results are collected:

MethodWhen to use it
PAGINATION (default)Most searches, up to roughly 500 listings
PAGINATION_WITH_ZOOM_INYou need more than about 500 listings from one search. It re-runs the search over smaller map areas, so it is slower and returns more rows
MAP_MARKERSReads the map layer instead of the results list

Zillow caps a single search at roughly 500 listings, which is why the zoom-in method exists.

The third argument is the maximum number of listings to return. For example:

=ZILLOWSEARCH(A1, "PAGINATION", 50)

If you leave it out, ZILLOWSEARCH returns up to 20 listings. The most one call can return is 1,000. A value below 1 shows #ERROR: maxResults must be 1 or more in the cell.

How many scraping credits does it cost?

ZILLOWSEARCH costs 6 scraping credits per listing returned. A default search of 20 listings is 120 credits, and 100 listings is 600 credits. Billing follows the rows actually written, so a search that finds fewer homes than your limit costs less.

For scale, here is what each plan includes:

PlanScraping credits
Free100
Solo10,000 per month
Growth45,000 per month
Scale115,000 per month

One search URL can fan out to many listings, so the maximum-results argument is the real cost lever. Start with 20 to 50 and raise it once the columns look right. For more on how credits and AI tokens differ, see AI tokens vs scraping credits.

Where do the results land?

On a new tab named Zillow Search Results, so nothing on your own tab is overwritten. The first column, Source, holds the address of the formula cell that asked for each row, and the listing columns follow from column B (Address).

With Keep Formula on, which is the default, the formula cell keeps your formula as text afterwards. With Keep Formula off, the cell changes to a status such as ✅ 30 results → Zillow Search Results. Change it in Extensions > SheetMagic > Open AI Settings.

What can you do with the exported listings?

The table is a shortlist waiting to happen. Each of these is a sort or a filter on columns ZILLOWSEARCH already returns:

  1. Find sellers who are already moving on price. Filter for a non-empty Price Reduction and sort by Days on Zillow. Homes that have sat and been cut are where an offer below asking is worth making, and you see them all at once instead of finding them one listing at a time.
  2. Check asking price against the estimate. Add a column of Price - Zestimate and sort it. Listings priced well above the Zestimate are the ones to question before you overpay; the ones below go to the top of your viewing list.
  3. Pull sold comps before you bid. Run the same area as a sold search and compare Price divided by Sqft against the homes you are looking at, so your offer rests on what homes like it actually sold for.
  4. Reach owners without an agent. Filter the For Sale By Owner column for a short list of owner-listed homes, where you deal with the seller directly.

Example workflow: comparing neighborhoods

  1. Make one tab per neighborhood. In each, paste that neighborhood's Zillow search URL in A1 and put =ZILLOWSEARCH(A1, , 30) in A2. Each one writes its own results tab (Zillow Search Results, then Zillow Search Results (2) and so on), so rename each results tab after its neighborhood.
  2. On a results tab, Address is column B, Price F, Beds G and Sqft I. Add a summary column with AITEXT in the first empty column of row 2, for example =AITEXT("Write a one-line summary of this home for an investor: " & B2 & ", price " & F2 & ", " & G2 & " beds, " & I2 & " sqft").
  3. For the homes you shortlist, use =ZILLOWHOME() with the home's Zillow URL or street address to pull the full detail record, one property per row.

For more ways to turn scraped rows into analysis, see the data analysis guide, and for the wider scraping toolkit start with the web scraping hub or the web scraping in Google Sheets guide.

Text and scraping formulas run on the free allowance. Install from the Google Workspace Marketplace, no card, no expiry.

Install free for Google Sheets

About the author

Phil NguyenPhil builds SheetMagic, the Google Sheets add-on that brings AI and web scraping into the spreadsheet, used by 6,300+ people. He writes these guides from the formulas he runs on his own sheets.