Zillow rental analysis

POSThttps://api.propertiesapi.com/v1/zillow/rental-analysis

GEThttps://api.propertiesapi.com/v1/zillow/rental-analysis

A rental property analysis for one home by Zillow link, zpid or address: cash flow, cap rate, cash-on-cash return, DSCR, GRM, the 1% rule, break-even rent and a five-year projection. Price, rent, taxes and HOA are filled from the property; every other input is a documented default you can override.

At a glance

  • Billing: 1 credit per successful live lookup of the home, the same as GET /v1/zillow/property; a home looked up within 24 hours comes from cache and is free. The analysis adds no charge. Errors before or during the lookup aren't billed.
  • Auth: x-api-key header.
  • Latency: typically 6 seconds, up to about 20 for a live lookup; repeat lookups within 24 hours come from the cache, with no live lookup.

Parameters

Send exactly one of url or address.

NameInTypeDescription
zpidquerystringA Zillow property ID, 1–12 digits. Give exactly one of url, zpid or address.
urlquerystringA zillow.com property link: a home (zillow.com/homedetails/..._zpid/, zillow.com/homes/..._zpid/ or a new-construction zillow.com/community/.../..._zpid/ link) or a building (zillow.com/b/... or zillow.com/apartments/...). Photo and other sub-pages after the property part are ignored. Other zillow.com pages, such as search results, return 400 bad_param, free. URL-encode it. Max 500 characters. Short links (zil.lw) and m.zillow.com links aren't accepted (400 bad_param, free): send the full www.zillow.com link.
addressquerystringA one-line US address with a house number, 5-200 characters. We find the matching Zillow property first. Include the unit number for condos and apartments.

Inputs (all optional overrides)

NameInTypeDescription
statusquerystring: for_sale | sold | for_rentOptional hint for which listing to read, for a home listed for sale and for rent at once. It is a hint, not a filter: a home served from the 24-hour cache, or found first by our primary source, comes back with whatever listing it has, so check homeStatus. When the home returned doesn't have the status you asked for, meta.warning says so. If omitted, the status is detected automatically.
pricequerynumberPurchase price, USD. Required. Auto-filled from the list or sold price, else Zillow's Zestimate. Max 1000000000.
down_payment_pctquerynumberDown payment, percent of the price. Default 20% (an assumption; edit it). Default 20. Max 100.
interest_rate_pctquerynumberInterest rate, percent a year. Default 7% a year: assumed; edit it. Not a quoted rate. Default 7. Max 30.
loan_term_yearsqueryintegerLoan term, years. Default 30 years (an assumption; edit it). Default 30. Max 50.
closing_costs_pctquerynumberClosing costs, percent of the price. Default 3% of the price (an assumption; edit it). Default 3. Max 20.
monthly_rentquerynumberMonthly rent, USD. Required. Auto-filled from Zillow's rent Zestimate (an estimate). Max 10000000.
vacancy_pctquerynumberVacancy, percent. Default 5% of gross rent (an assumption; edit it). Default 5. Max 100.
management_pctquerynumberProperty management, percent. Default 8% of rent collected (an assumption; edit it). Default 8. Max 100.
maintenance_pctquerynumberMaintenance, percent. Default 5% of gross rent (an assumption; edit it). Default 5. Max 100.
capex_pctquerynumberCapital expenditures, percent. Default 5% of gross rent, set aside for big repairs (an assumption; edit it). Default 5. Max 100.
annual_property_taxquerynumberProperty tax a year, USD. Auto-filled from the tax history when there is one; otherwise an estimate of 1% of the price a year (edit it). Max 100000000.
annual_insurancequerynumberInsurance a year, USD. An estimate of 0.5% of the price a year, not a quote (edit it). Max 100000000.
monthly_hoaquerynumberHOA a month, USD. Auto-filled from the listing's HOA fee; default 0. Default 0. Max 10000000.
other_monthly_expensesquerynumberOther costs a month, USD. Utilities you pay, landscaping and so on; default 0. Default 0. Max 10000000.
rent_growth_pctquerynumberRent growth, percent a year. Projection only. Default 3% a year (an assumption; edit it). Default 3. Max 50.
appreciation_pctquerynumberAppreciation, percent a year. Projection only. Default 3% a year (an assumption; edit it). Default 3. Max 50.
expense_growth_pctquerynumberExpense growth, percent a year. Projection only: taxes, insurance, HOA and other costs. Default 3% a year (an assumption; edit it). Default 3. Max 50.

Request body

Exactly one of url, zpid or address, optional status, and any of the inputs above as JSON numbers (or numeric strings). GET takes the same names as query parameters. Inputs you leave out are filled from the property or from the documented defaults.

Request body
{
  "url": "https://www.zillow.com/homedetails/2640-Steiner-St-San-Francisco-CA-94115/15073305_zpid/",
  "interest_rate_pct": 6.5
}

Response fields

The body is { data, meta }. Money is in USD, rounded to cents; percentages and ratios are rounded to two decimals.

FieldTypeFormula or meaning
data.propertyobjectThe home the analysis used: zpid, address, detailUrl, homeStatus, homeType, beds, baths, livingArea, yearBuilt, price, zestimate, rentZestimate, monthlyHoaFee, taxAnnualAmount, taxAssessedValue and propertyTaxRate, as GET /v1/zillow/property returns them (null when Zillow doesn't show them).
data.inputsobjectOne entry per input (the parameters above): value; source (property: read from this home, with basis naming the field used; default: a documented assumption or estimate, with note; request: the value you passed); basis or note.
data.metrics.down_paymentnumberprice x down_payment_pct.
data.metrics.loan_amountnumberprice - down_payment.
data.metrics.closing_costsnumberprice x closing_costs_pct.
data.metrics.total_cash_needednumberdown_payment + closing_costs.
data.metrics.monthly_principal_and_interestnumberloan_amount x i / (1 - (1 + i)^-n), with i = interest_rate_pct / 12 and n = loan_term_years x 12. At a 0% rate, loan_amount / n; with no loan, 0.
data.metrics.annual_debt_servicenumbermonthly_principal_and_interest x 12.
data.metrics.gross_monthly_rentnumbermonthly_rent.
data.metrics.gross_annual_incomenumbermonthly_rent x 12.
data.metrics.vacancy_lossnumbergross_annual_income x vacancy_pct.
data.metrics.effective_gross_incomenumbergross_annual_income - vacancy_loss (EGI).
data.metrics.operating_expensesobjectmanagement (EGI x management_pct), maintenance (gross x maintenance_pct), capex (gross x capex_pct), property_tax, insurance, hoa (monthly_hoa x 12) and other (other_monthly_expenses x 12), a year.
data.metrics.total_operating_expensesnumberThe sum of operating_expenses.
data.metrics.noinumberNet operating income: effective_gross_income - total_operating_expenses (before the loan payment).
data.metrics.annual_cash_flownumbernoi - annual_debt_service.
data.metrics.monthly_cash_flownumberannual_cash_flow / 12.
data.metrics.cap_rate_pctnumbernoi / price, percent.
data.metrics.cash_on_cash_pctnumberannual_cash_flow / total_cash_needed, percent. null when nothing is invested (0% down and no closing costs).
data.metrics.dscrnumberDebt service coverage ratio: noi / annual_debt_service. null with no loan.
data.metrics.grmnumberGross rent multiplier: price / gross_annual_income. null with no rent.
data.metrics.one_percent_ruleobjectpasses: monthly_rent is at least 1% of price; rent_to_price_pct: monthly_rent / price, percent.
data.metrics.break_even_rentnumberThe monthly rent at which annual_cash_flow is 0: (fixed costs + annual_debt_service) / (12 x [(1 - vacancy)(1 - management) - maintenance - capex]), fixed costs = tax + insurance + HOA and other costs a year. null when no rent can break even (for example 100% vacancy).
data.projectionobject[]Five years: year, monthly_rent (grows by rent_growth_pct from year 2), noi (percentage costs follow the rent; tax, insurance, HOA and other costs grow by expense_growth_pct), annual_cash_flow (noi minus the loan payments still due that year: none once a short loan is paid off), cumulative_cash_flow, property_value (price x (1 + appreciation_pct)^year), loan_balance (after 12 x year payments), equity (property_value - loan_balance, before selling costs), total_profit (cumulative_cash_flow + equity - total_cash_needed) and total_return_pct (total_profit / total_cash_needed; null when nothing is invested).
data.warningsstring[]Inputs to check: an assumed interest rate, estimated insurance or taxes, a Zestimate used as the price, a rent Zestimate used as the rent, a missing HOA fee on a condo, a negative cash flow. Can be empty.
data.disclaimerstringNot financial advice: the figures are estimates for illustration.
metaobjectThe lookup's meta: credits (1 for a live lookup, 0 from the cache), cached, cache_key, fetched_at, source, release, took_ms, and warning when the lookup has one.

Example

Request
curl "https://api.propertiesapi.com/v1/zillow/rental-analysis" -H "x-api-key: $PROPERTIESAPI_KEY" \
  -H "content-type: application/json" \
  -d '{"url":"https://www.zillow.com/homedetails/2640-Steiner-St-San-Francisco-CA-94115/15073305_zpid/","interest_rate_pct":6.5}'
Response 200 (illustrative)
{
  "data": {
    "property": {
      "zpid": "15073305",
      "address": "2640 Steiner St, San Francisco, CA 94115",
      "detailUrl": "https://www.zillow.com/homedetails/2640-Steiner-St-San-Francisco-CA-94115/15073305_zpid/",
      "homeStatus": "FOR_SALE",
      "homeType": "SINGLE_FAMILY",
      "beds": 3,
      "baths": 2,
      "livingArea": 1840,
      "yearBuilt": 1998,
      "price": 525000,
      "zestimate": 512000,
      "rentZestimate": 2650,
      "monthlyHoaFee": null,
      "taxAnnualAmount": 9840,
      "taxAssessedValue": 498000,
      "propertyTaxRate": 1.98
    },
    "inputs": {
      "price": {
        "value": 525000,
        "source": "property",
        "basis": "list price"
      },
      "down_payment_pct": {
        "value": 20,
        "source": "default",
        "note": "Default 20% (an assumption; edit it)."
      },
      "interest_rate_pct": {
        "value": 6.5,
        "source": "request"
      },
      "loan_term_years": {
        "value": 30,
        "source": "default",
        "note": "Default 30 years (an assumption; edit it)."
      },
      "closing_costs_pct": {
        "value": 3,
        "source": "default",
        "note": "Default 3% of the price (an assumption; edit it)."
      },
      "monthly_rent": {
        "value": 2650,
        "source": "property",
        "basis": "rent Zestimate"
      },
      "vacancy_pct": {
        "value": 5,
        "source": "default",
        "note": "Default 5% of gross rent (an assumption; edit it)."
      },
      "management_pct": {
        "value": 8,
        "source": "default",
        "note": "Default 8% of rent collected (an assumption; edit it)."
      },
      "maintenance_pct": {
        "value": 5,
        "source": "default",
        "note": "Default 5% of gross rent (an assumption; edit it)."
      },
      "capex_pct": {
        "value": 5,
        "source": "default",
        "note": "Default 5% of gross rent, set aside for big repairs (an assumption; edit it)."
      },
      "annual_property_tax": {
        "value": 9840,
        "source": "property",
        "basis": "tax history (2025)"
      },
      "annual_insurance": {
        "value": 2625,
        "source": "default",
        "note": "An estimate of 0.5% of the price a year, not a quote (edit it)."
      },
      "monthly_hoa": {
        "value": 0,
        "source": "default",
        "note": "Auto-filled from the listing's HOA fee; default 0."
      },
      "other_monthly_expenses": {
        "value": 0,
        "source": "default",
        "note": "Utilities you pay, landscaping and so on; default 0."
      },
      "rent_growth_pct": {
        "value": 3,
        "source": "default",
        "note": "Projection only. Default 3% a year (an assumption; edit it)."
      },
      "appreciation_pct": {
        "value": 3,
        "source": "default",
        "note": "Projection only. Default 3% a year (an assumption; edit it)."
      },
      "expense_growth_pct": {
        "value": 3,
        "source": "default",
        "note": "Projection only: taxes, insurance, HOA and other costs. Default 3% a year (an assumption; edit it)."
      }
    },
    "metrics": {
      "down_payment": 105000,
      "loan_amount": 420000,
      "closing_costs": 15750,
      "total_cash_needed": 120750,
      "monthly_principal_and_interest": 2654.69,
      "annual_debt_service": 31856.23,
      "gross_monthly_rent": 2650,
      "gross_annual_income": 31800,
      "vacancy_loss": 1590,
      "effective_gross_income": 30210,
      "operating_expenses": {
        "management": 2416.8,
        "maintenance": 1590,
        "capex": 1590,
        "property_tax": 9840,
        "insurance": 2625,
        "hoa": 0,
        "other": 0
      },
      "total_operating_expenses": 18061.8,
      "noi": 12148.2,
      "annual_cash_flow": -19708.03,
      "monthly_cash_flow": -1642.34,
      "cap_rate_pct": 2.31,
      "cash_on_cash_pct": -16.32,
      "dscr": 0.38,
      "grm": 16.51,
      "one_percent_rule": {
        "passes": false,
        "rent_to_price_pct": 0.5
      },
      "break_even_rent": 4771.88
    },
    "projection": [
      {
        "year": 1,
        "monthly_rent": 2650,
        "noi": 12148.2,
        "annual_cash_flow": -19708.03,
        "cumulative_cash_flow": -19708.03,
        "property_value": 540750,
        "loan_balance": 415305.55,
        "equity": 125444.45,
        "total_profit": -15013.58,
        "total_return_pct": -12.43
      },
      {
        "year": 2,
        "monthly_rent": 2729.5,
        "noi": 12512.65,
        "annual_cash_flow": -19343.58,
        "cumulative_cash_flow": -39051.61,
        "property_value": 556972.5,
        "loan_balance": 410296.71,
        "equity": 146675.79,
        "total_profit": -13125.82,
        "total_return_pct": -10.87
      },
      {
        "year": 3,
        "monthly_rent": 2811.39,
        "noi": 12888.03,
        "annual_cash_flow": -18968.2,
        "cumulative_cash_flow": -58019.81,
        "property_value": 573681.68,
        "loan_balance": 404952.42,
        "equity": 168729.26,
        "total_profit": -10040.55,
        "total_return_pct": -8.32
      },
      {
        "year": 4,
        "monthly_rent": 2895.73,
        "noi": 13274.67,
        "annual_cash_flow": -18581.56,
        "cumulative_cash_flow": -76601.38,
        "property_value": 590892.13,
        "loan_balance": 399250.2,
        "equity": 191641.92,
        "total_profit": -5709.46,
        "total_return_pct": -4.73
      },
      {
        "year": 5,
        "monthly_rent": 2982.6,
        "noi": 13672.91,
        "annual_cash_flow": -18183.32,
        "cumulative_cash_flow": -94784.7,
        "property_value": 608618.89,
        "loan_balance": 393166.11,
        "equity": 215452.78,
        "total_profit": -81.91,
        "total_return_pct": -0.07
      }
    ],
    "warnings": [
      "monthly_rent is Zillow's rent Zestimate, an estimate. Pass monthly_rent if you know the market rent.",
      "annual_insurance is an estimate (0.5% of the price a year), not a quote. Pass a real quote.",
      "Cash flow is negative with these inputs: the rent doesn't cover the costs and the loan payment."
    ],
    "disclaimer": "Not financial advice. These figures are estimates for illustration: plain arithmetic on the inputs shown, several of which are assumptions or estimates (see inputs). The Zestimate and rent Zestimate are Zillow's estimates, not appraisals or offers. Check every input with a lender, an insurer and a local expert before you rely on it."
  },
  "meta": {
    "credits": 1,
    "cached": false,
    "cache_key": "zpid:15073305",
    "fetched_at": "2026-10-19T14:02:11.000Z",
    "source": {
      "note": "Read from the public Zillow page. Field availability varies by listing. PropertiesAPI is not affiliated with Zillow."
    },
    "release": "v1",
    "took_ms": 14236
  }
}

Example values are illustrative, not a real record. Fields Zillow doesn't show for a property come back as null. Data is provided as-is.

Not financial advice. The analysis is arithmetic on the inputs shown; several are assumptions or estimates (data.warnings lists them). Try it without a key in the free rental property calculator, or see the cap rate, cash-on-cash return and DSCR calculators.

Notes

  • Send exactly one of url, zpid or address, as JSON (POST) or as query parameters (GET). Every other field is an optional override, used as you pass it (source request).
  • The lookup is GET /v1/zillow/property's own: the same key, rate limits, credits and 24-hour cache. Your dashboard lists these calls as property lookups.
  • price and monthly_rent are never invented. When the home has no list price, sold price or Zestimate, or no rent Zestimate (or listed rent), and you didn't pass one, the answer is 422 rental_input_missing: details.missing names the input, and nothing else about the home is returned. The record is refused before it is cached or billed, so the 422 costs nothing; ask again with the input and it is a normal lookup (1 credit live, none from the cache).
  • interest_rate_pct defaults to an assumed rate, not a quoted or current mortgage rate. annual_insurance, and annual_property_tax when the home has no tax figure, are estimates as a share of the price. data.warnings lists every such input; pass your own numbers.
  • Override values are checked before the lookup: a bad value returns 400 bad_param (details.fields names it), and nothing is looked up or billed.
  • Money is in USD rounded to cents; percentages and ratios to 2 decimals. The formulas are listed under Response fields.
  • The analysis is plain arithmetic on the inputs, for illustration. It isn't financial advice, an appraisal or a loan quote (data.disclaimer). The same engine runs the free rental property calculator.

Errors

Errors are { error: { code, message, details? }, meta: { took_ms } } with status 400, 401, 404, 422, 500, 502, 503 or 504. Errors aren't billed. See errors.

Zillow is a trademark of Zillow, Inc. PropertiesAPI is an independent service and is not affiliated with, endorsed by or sponsored by Zillow.

Zillow rental analysis questions

Which inputs come from the property?+

The purchase price (the list or sold price, else Zillow's Zestimate), the monthly rent (Zillow's rent Zestimate), the property tax (the latest tax-history year, else the annual tax amount, else the assessed value times the local rate) and the HOA fee. data.inputs says where every value came from.

Is the interest rate a live mortgage rate?+

No. Without interest_rate_pct the analysis uses an assumed rate and says so in data.warnings. Pass the rate you were quoted.

What if the home has no rent Zestimate?+

Pass monthly_rent. Without it the answer is 422 rental_input_missing, which names the missing input and costs nothing; asking again with the rent is a normal lookup.

Can I try it without an API key?+

Yes: the free rental property calculator runs the same formulas in your browser, and can fill the inputs from an address.

Is this Zillow's official API?+

No. PropertiesAPI is an independent service and is not affiliated with, endorsed by or sponsored by Zillow. The data is provided as-is.

Do failed lookups cost anything?+

No. Only successful live lookups are billed. Errors are free, and repeat lookups of the same home within 24 hours come from cache for free.