Zillow is at the forefront of real estate APIs for creative developers. It offers unparalleled property information, as well as Zillow’s popular add-on data, such as the Zestimate. A Zestimate is Zillow’s best guess as to the value of a given property while considering a wealth of interrelated data, such as recent sale prices for comparable properties.
Related: How to get Airbnb Property Data
You can now access this API on the RapidAPI Marketplace. For more information, please see RapidAPI’s Zillow API documentation.
To get started, just:
- Register for a free account with Zillow.
- After completing the simple registration, Zillow will email you your Zillow Web Services ID (ZWSID).
Zillow API Endpoints
With that out of the way, let’s take a quick tour of Zillow’s API endpoints that are available via RapidAPI.
getChart returns an HTML chart comprised of images and property data.
getComps returns a list of recent, similar sales for a property.
getDeepComps returns a list of recent, deeply similar sales for a property.
getDeepSearchResults returns property for a given address.
getRegionChildren returns a list of regions that exist within the “parent” region provided in the request.
getSearchResults returns property for a given address.
getUpdatedPropertyDetails returns the most recently updated details provided by the homeowner.
getZestimate returns Zillow’s estimated values related to a given property (where exists).
To show the user information about a given home, the flow will likely include a general search at first, and then a more focused query related to a given home by way of the `zpid` that Zillow uses as a UUID for homes.
RapidAPI’s example code snippets show this information. As you can see here, we are first searching for a known address.
import requests url = "https://zillowdimashirokovv1.p.rapidapi.com/GetSearchResults.htm" payload = "rentzestimate=true&rentzestimate=false&zws-id=<YOUR ZILLOW ID>&citystatezip=97525&address=583-N-5th-Ave-Gold-Hill-OR" headers = { 'x-rapidapi-host': "ZillowdimashirokovV1.p.rapidapi.com", 'x-rapidapi-key': "YOUR RAPID API KEY", 'content-type': "application/x-www-form-urlencoded" } response = requests.request("POST", url, data=payload, headers=headers) print(response.text)
The above request will yield something like the following:
<?xml version="1.0" encoding="utf-8"?><SearchResults:searchresults xsi:schemaLocation="http://www.zillow.com/static/xsd/SearchResults.xsd https://www.zillowstatic.com/vstatic/80d5e73/static/xsd/SearchResults.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SearchResults="http://www.zillow.com/static/xsd/SearchResults.xsd"><request><address>583-N-5th-Ave-Gold-Hill-OR</address><citystatezip>97525</citystatezip></request><message><text>Request successfully processed</text><code>0</code></message><response><results><result><zpid>48327876</zpid><links><homedetails>https://www.zillow.com/homedetails/583-N-5th-Ave-Gold-Hill-OR-97525/48327876_zpid/</homedetails><graphsanddata>http://www.zillow.com/homedetails/583-N-5th-Ave-Gold-Hill-OR-97525/48327876_zpid/#charts-and-data</graphsanddata><mapthishome>http://www.zillow.com/homes/48327876_zpid/</mapthishome><comparables>http://www.zillow.com/homes/comps/48327876_zpid/</comparables></links><address><street>583 N 5th Ave</street><zipcode>97525</zipcode><city>Gold Hill</city><state>OR</state><latitude>42.433585</latitude><longitude>-123.050717</longitude></address><zestimate><amount currency="USD">203531</amount><last-updated>11/09/2019</last-updated><oneWeekChange deprecated="true"></oneWeekChange><valueChange duration="30" currency="USD">3791</valueChange><valuationRange><low currency="USD">181143</low><high currency="USD">221849</high></valuationRange><percentile>0</percentile></zestimate><localRealEstate><region name="Gold Hill" id="31785" type="city"><links><overview>http://www.zillow.com/local-info/OR-Gold-Hill/r_31785/</overview><forSaleByOwner>http://www.zillow.com/gold-hill-or/fsbo/</forSaleByOwner><forSale>http://www.zillow.com/gold-hill-or/</forSale></links></region></localRealEstate></result></results></response></SearchResults:searchresults><!-- H:001 T:53ms S:842 R:Sun Nov 10 17:26:17 PST 2019 B:5.0.62950-master.2aa0979~delivery_ready.266b9ad -->
Then, with the response data from Zillow — in particular the `<zpid>48327876</zpid>`— we can go on to make further use of Zillow’s API by requesting an HTML chart made up of images and data about the home, like so.
import requests url = "https://zillowdimashirokovv1.p.rapidapi.com/GetChart.htm" payload = "chartDuration=1year&chartDuration=5years&chartDuration=10years&zpid=48327876&unit-type=dollar&zws-id=<YOUR ZILLOW ID>" headers = { 'x-rapidapi-host': "ZillowdimashirokovV1.p.rapidapi.com", 'x-rapidapi-key': "YOUR RAPID API KEY", 'content-type': "application/x-www-form-urlencoded" } response = requests.request("POST", url, data=payload, headers=headers)
The above request will yield the following response. Notice you have several URLs now.
print(response.text) <?xml version="1.0" encoding="utf-8"?><Chart:chart xsi:schemaLocation="http://www.zillow.com/static/xsd/Chart.xsd https://www.zillowstatic.com/vstatic/80d5e73/static/xsd/Chart.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Chart="http://www.zillow.com/static/xsd/Chart.xsd"><request><zpid>48327876</zpid><unit-type>dollar</unit-type></request><message><text>Request successfully processed</text><code>0</code></message><response><url>https://www.zillow.com:443/app?chartDuration=1year%2C5years%2C10years&chartType=partner&page=webservice%2FGetChart&service=chart&zpid=48327876</url><graphsanddata>http://www.zillow.com/homedetails/583-N-5th-Ave-Gold-Hill-OR-97525/48327876_zpid/#charts-and-data</graphsanddata></response></Chart:chart><!-- H:002 T:10ms S:201 R:Sun Nov 10 17:21:13 PST 2019 B:5.0.62950-master.2aa0979~delivery_ready.266b9ad →
You will also notice Zillow’s API returns XML. To make this API easier to use, an XML to JSON conversion example might be helpful. So, I put together the following.
We have a simple Flask App here that has two routes — `/`, or our index view, and `/get-chart`, a route that allows only HTTP POST requests, and that needs a user-supplied ZPID in order to work.
Note that the index view returns a simple HTML form by which a user can supply a ZPID in order to get an XML response from Zillow, and to then convert that to JSON, and finally return it to the browser.
from flask import Flask, request, jsonify import requests from lxml import etree app = Flask(__name__) YOUR_RAPID_API_KEY = '<Your Rapid Api Key>' YOUR_ZILLOW_ZWS_ID = '<Your Zillow ID>' @app.route('/') def index(): return """ <form action="/get-chart" method="post"> <p><input type=text name=zpid placeholder=zpid> <p><input type=submit value="Get Chart"> </form> """ @app.route('/get-chart', methods=['POST']) def get_chart(): zpid = request.form.get('zpid') url = "https://zillowdimashirokovv1.p.rapidapi.com/GetChart.htm" # NOTE: For the sake of brevity we have hard coded all variables except for the ZPID. payload = "chartDuration=1year&chartDuration=5years&chartDuration=10years&zpid={0}&unit-type=dollar&zws-id={1}".format(zpid, YOUR_ZILLOW_ZWS_ID) headers = { 'x-rapidapi-host': "ZillowdimashirokovV1.p.rapidapi.com", 'x-rapidapi-key': YOUR_RAPID_API_KEY, 'content-type': "application/x-www-form-urlencoded" } response = requests.post( url, data=payload, headers=headers) root = etree.XML(response.content) # lxml is a super powerful library. Here we have gotten the root element of our XML # and we are now going to iterate over all elements in order to build our Python dict # and finally convert it to JSON with Flask’s `jsonify`. data = {} for element in root.iter(): data[element.tag] = element.text return jsonify(data) if __name__ == '__main__': app.run(debug=True)
See the app in action in this video:
Related Reading
- Related Real Estate APIs
- Best Real Estate Websites
- Pulling Zillow Rent Data
- Zillow vs Redfin vs Trulia
Leave a Reply