Build a project

Asking Rent vs. Rent Zestimate: Build a Rental Comparison Spreadsheet

Compare monthly asking rents with Zillow rent estimates for a known list of properties. Download a Python report that keeps missing data and exclusions visible.

By PropertiesAPI4 min read

Which rental listings deserve a closer look?

You have a shortlist of rental properties and want to compare each asking rent with the source-provided rent estimate. A useful first pass puts those figures next to each other, calculates the gap, and makes missing or mismatched data obvious. This guide creates that worksheet from a saved property snapshot.

The comparison helps prioritize manual research. A listing below Zillow's rent estimate is not proof of a bargain, and a listing above it is not proof of overpricing. Lease terms, condition, concessions, included utilities, and unit identity can explain differences the estimate does not capture.

Separate asking rent, rent estimate, and home value

For a property whose homeStatus is FOR_RENT, price is the monthly asking rent in the returned currency. rentZestimate is Zillow's monthly rent estimate when the source shows one. zestimate is a home-value estimate and does not belong in the monthly-rent calculation.

The same price field has different meaning for other listing statuses. Never divide a for-sale price by a rent estimate and label the result a rent premium. The program excludes non-rental rows and requires USD explicitly rather than guessing the currency.

FieldMeaning in this worksheet
price with FOR_RENTMonthly asking rent; confirm the unit and advertised terms.
rentZestimateZillow's monthly estimate, when available.
zestimateHome-value estimate; excluded from this calculation.
null or missingUnavailable; leave the comparison blank.

Collect the properties you already selected

Use the address enrichment guide to generate output/properties.json. Include unit numbers for apartments and condos, and review requested versus returned addresses. The report works from that snapshot, so you can recalculate without consuming more lookups.

An apartment-building URL can describe a selected available unit rather than every unit in the building. Its displayed rent and unit characteristics should be checked together. Do not compare a building-level estimate with an individual apartment and assume they describe the same rentable space.

Download and run the rent report

Save compare_rents.py next to the enrichment script. It uses the Python standard library and reads your saved JSON file. The CSV it writes retains every input row, including excluded records, with a reason explaining why a calculation was skipped.

The script requires a successful lookup, no recorded identity warning, a rental listing, USD currency, and positive asking and estimated rents. It guards spreadsheet formulas in text cells while preserving numeric differences. Rows that pass still require a manual unit and lease review.

Create the rental worksheet
python compare_rents.py output/properties.json > rent-comparison.csv

Calculate the gap against the estimate

The dollar gap is asking rent minus estimated rent. The percentage gap divides that difference by estimated rent. A positive result means the asking rent is above the estimate; a negative result means it is below. The denominator stays the same for every property so the direction is consistent.

The following function is the calculation from the downloadable report. Decimal arithmetic keeps the displayed percentage rounding explicit. Missing, nonfinite, zero, or negative inputs are rejected before reaching this calculation.

Monthly comparison calculation
from decimal import Decimal

def rent_gap(asking, estimate):
    asking, estimate = Decimal(str(asking)), Decimal(str(estimate))
    gap = asking - estimate
    percent = (gap / estimate * 100).quantize(Decimal("0.01"))
    return gap, percent

# Synthetic arithmetic check, not a market observation:
assert rent_gap(2400, 2500) == (Decimal("-100"), Decimal("-4.00"))

Review the excluded rows before ranking properties

Sort by the reason column first. An unsuccessful lookup needs input or service review. identity_needs_review means the exported response carried a warning or lacked required identity fields. not_current_rental means the price cannot be used as monthly rent in this worksheet. Missing estimates stay blank.

Then compare like-for-like units. Check bedrooms, bathrooms, area, furnished status, utilities, deposits, lease length, and concessions. A headline rent with a temporary discount is not necessarily the amount payable throughout the lease. Verify current terms on the listing before drawing conclusions.

Keep fetched_at visible. A recently generated report can contain older cached property snapshots, and properties may have been collected at different times. The report describes the saved observations rather than guaranteeing current availability.

Use the report as a research queue

This workflow does not discover rental comps, estimate achieved rents, calculate occupancy, or predict investment returns. If you need comparable properties, select a defensible comparison set first and document why each unit belongs in it. The API enriches the supplied list; it does not choose that set for you.

Validation scope: the calculation and row-exclusion logic are tested with synthetic fixtures covering missing estimates, zero values, sale listings, currency differences, and identity warnings. No market-wide accuracy claim follows from those tests. Use the output to decide what to investigate next.

Sources and documentation

Product details checked against the linked documentation on October 21, 2026. Code and sample inputs are illustrative unless stated otherwise.

Written by PropertiesAPI, an independent property data service. We are not affiliated with Zillow. Source data may be incomplete or change over time.