Zillow to Airbnb Investment Calculator & STR Analysis avatar

Zillow to Airbnb Investment Calculator & STR Analysis

Pricing

from $150.00 / 1,000 analysis completes

Go to Apify Store
Zillow to Airbnb Investment Calculator & STR Analysis

Zillow to Airbnb Investment Calculator & STR Analysis

Analyze a Zillow listing as a short-term rental: comparable Airbnb rates, financing, and expenses projected into cap rate, cash flow, and break-even occupancy.

Pricing

from $150.00 / 1,000 analysis completes

Rating

0.0

(0)

Developer

Zapticx

Zapticx

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

10 days ago

Last modified

Share

🏡 Found a Zillow property. Could it actually work as an Airbnb?

Normally that means opening a spreadsheet, hunting down Airbnb comps by hand, guessing at a mortgage payment, and building your own cap-rate formula before you even know if the property is worth a second look. This Actor answers the question in one run.

Zillow property → Airbnb comparables → STR investment analysis

Give it a Zillow listing URL (or just a city/ZIP if you haven't found one yet) and get back:

  • Purchase price → observed from Zillow
  • Airbnb nightly rates → observed from comparable listings in the same market area
  • Financing + expenses → your explicit, adjustable assumptions
  • Cap rate · cash flow · cash-on-cash · DSCR → calculated
  • Break-even occupancy → calculated
  • Conservative / Base / Optimistic → three scenarios, side by side

No spreadsheets, no manually cross-referencing Airbnb listings, no guessing at a mortgage payment — just the numbers, each one clearly labeled by where it actually came from.

Worth 30 seconds: check Annual insurance. Zillow never publishes it, and rather than invent a number this Actor returns cap rate, cash flow, and break-even occupancy as null when the cost basis is incomplete. The Store example pre-fills an illustrative $4,800/yr so the example run can show a complete analysis — that figure is your assumption, not an observation and not an Actor estimate, so replace it with a real quote for your own property. Clear the field and insurance goes back to unknown, never guessed. See When the evidence isn't strong enough.

Independent tool — not affiliated with, endorsed by, or sponsored by Zillow Group, Inc. or Airbnb, Inc. "Zillow" and "Zestimate" are trademarks of Zillow, Inc.; "Airbnb" is a trademark of Airbnb, Inc.

Observed data, your assumptions, and calculated projections — kept strictly separate

This is the part that makes the numbers trustworthy: this Actor never blurs observed fact into a projection. Every output record is four separated blocks — what Zillow actually reported about the property, what Airbnb actually reported about comparable nightly rates nearby, exactly which assumptions drove the math (and where each one came from — Zillow's own data, you, or genuinely unknown), and the calculated projections built on top of them. The projections are always clearly labeled as estimates derived from your assumptions — never presented as facts, market predictions, or guarantees of future occupancy, revenue, or returns.

This Actor orchestrates this account's own zillow-market-intelligence and airbnb-market-intelligence Actors rather than re-scraping either site.

What this Actor does

Give it a single Zillow listing URL, and it fetches that exact property, searches for comparable Airbnb nightly rates in the same market (bedroom-matched when possible — see What the comparable set actually covers), and runs the numbers: loan amount, monthly mortgage payment, gross revenue, operating expenses, NOI, cash flow, cap rate, cash-on-cash return, DSCR, and break-even occupancy — for a conservative (P25 nightly rate), base (median), and optimistic (P75) scenario.

No listing URL yet? Give it a location instead (city, state, or ZIP) and it deterministically selects one representative active listing from that market — never an arbitrary first result, and never chosen based on projected return (see How the representative property is selected).

Why use it?

Most STR calculators either require you to manually gather comps, or quietly bake in national default assumptions for property tax and insurance that don't apply to your market. This Actor does neither:

  • Property tax uses Zillow's own reported rate for that property when available — never a national or state average. The annual amount is derived from it as price × propertyTaxRatePercent / 100, which is why it can differ from the tax history Zillow shows for the current owner — a prior owner's assessed value is not your purchase price.
  • Insurance has no default anywhere. Zillow doesn't publish it, so it's either what you enter or explicitly unknown — never a guessed number disguised as a real one.
  • Occupancy is always labeled as your own adjustable assumption, never presented as a market estimate.
  • When the Airbnb comparable evidence is too thin to support a credible nightly-rate estimate, revenue-driven numbers come back null with a reason — not a number that merely looks precise.

Who is it for?

Individual STR buyers evaluating a specific property, real estate agents building investor-ready numbers for a listing, and analysts who want a defensible, source-separated model they can audit line by line rather than a black-box "cash flow" figure.

Input

Property (choose exactly one)

FieldRequiredDescription
zillowListingUrlOne property inputA single zillow.com/homedetails/... URL. The primary, serious-investment workflow — always takes precedence and skips property selection entirely.
locationOne property inputCity, state, or ZIP. Resolves one currently active listing in that market — see property selection.

Financing

FieldDefaultDescription
downPaymentPercent20Percent of price paid as down payment.
interestRatePercent7.0Illustrative default — check current rates and adjust.
loanTermYears30Amortization period.
closingCostsPercent2.5Percent of price added to total cash invested.
furnishingBudget0One-time STR setup cost, added to total cash invested.

Operating expenses (no hidden defaults)

FieldDefaultDescription
propertyTaxAnnual(none)Leave blank to use Zillow's own reported rate for this listing when available. Otherwise marked unknown, never guessed.
insuranceAnnual(none)No default anywhere — Zillow doesn't publish this. Leave blank to mark unknown.
hoaMonthlyOverride(none)Leave blank to use Zillow's own reported HOA fee when available. On a condo, townhouse, or apartment an unknown HOA is treated as missing data (see below), so set it here if Zillow doesn't report one.
managementFeePercent15Illustrative default for full-service management; set to 0 if self-managing.
maintenanceReservePercent8Illustrative reserve for repairs/upkeep.
platformFeePercent3Booking platform fee — adjustable, not a universal constant.
utilitiesAnnual0STR hosts typically cover utilities, unlike long-term rentals.

Occupancy scenarios (explicit assumptions, never a market prediction)

FieldDefaultPaired with
conservativeOccupancyPercent40Airbnb comparable set's 25th-percentile nightly rate
baseOccupancyPercent60Median nightly rate
optimisticOccupancyPercent8075th-percentile nightly rate

Comparable set

FieldDefaultDescription
maxComparables20Airbnb comparables to collect, 8–100. Larger samples cost more (each is billed by the Airbnb Actor) but improve confidence.

Example inputs

A specific property (the primary workflow)

{
"zillowListingUrl": "https://www.zillow.com/homedetails/247652439_zpid/",
"insuranceAnnual": 12000
}

No listing yet — analyze a representative property in a market

{
"location": "Miami Beach, FL"
}

Adjusting the financing and occupancy assumptions

{
"zillowListingUrl": "https://www.zillow.com/homedetails/46291510_zpid/",
"insuranceAnnual": 2200,
"downPaymentPercent": 40,
"baseOccupancyPercent": 55
}

Output

One str_analysis record per run in the default dataset, always these five top-level parts:

  • propertySelection — how the analyzed listing was chosen: user_provided_url (you gave the exact listing) or representative_location_listing (deterministically picked from a location search), plus a plain-English explanation and the market Zillow actually searched.
  • observedZillow — straight from the property: price, size, beds/baths, Zestimate, Zillow's own reported property-tax rate and HOA fee when published. Nothing computed except priceVsZestimatePercent, a direct comparison of two observed values.
  • observedAirbnbComparables — straight from the Airbnb comparable search: sample size, confidence, and P25/median/P75 nightly rates. Returned in full even when the sample is too weak to drive a projection.
  • assumptions — every financing/expense input actually used, with a Source field (user_provided / observed_from_zillow / unknown) for property tax, insurance, and HOA.
  • projections — the calculated three-scenario output, with a standing disclaimer and explicit completeness signals (see below). Never presented as fact.

Complete example (abbreviated)

Produced by this Actor's own engine from the captured Zillow and Airbnb child payloads in tests/fixtures/, using the Store example's input. Abbreviated for readability — only the base scenario is shown, and observedZillow/assumptions are trimmed to the fields the numbers below depend on. Every figure reconciles under the formulas in Understanding the numbers; tests/test_actor_schemas.py re-derives this case on every test run.

{
"recordType": "str_analysis",
"propertySelection": {
"mode": "representative_location_listing",
"resolvedLocation": "Miami Beach, FL",
"sampleSize": 20
},
"observedZillow": {
"zpid": "43886242",
"addressStreet": "5401 Collins Ave APT 826",
"addressCity": "Miami Beach",
"addressState": "FL",
"homeType": "CONDO",
"price": 499000,
"bedrooms": 2,
"bathrooms": 1,
"propertyTaxRatePercent": 1.84,
"monthlyHoaFee": 108,
"detailSource": "for_sale_priority"
},
"observedAirbnbComparables": {
"searchLocation": "Miami Beach, FL",
"bedroomsFilter": 2,
"stayCheckIn": "2026-10-16",
"stayCheckOut": "2026-10-20",
"stayLengthNights": 4,
"comparableSampleSize": 18,
"confidence": "medium",
"medianNightlyPrice": 241.75,
"priceP25": 180.06,
"priceP75": 302.38,
"medianTotalPriceForStay": 967,
"nightlyRateBasis": "Observed guest-facing Airbnb pricing for one sampled stay window, not a host payout and not a seasonality model. ...",
"sampleCoverage": {
"listingsCollected": 20,
"listingsAcceptedForPricing": 18,
"listingsExcludedFromPricing": 2,
"exclusionReasons": { "incompatible_stay_context": 2 },
"truncated": true
},
"geographicScope": {
"dominantAreaLabel": "South Beach",
"dominantAreaLabelSharePercent": 65,
"distinctAreaLabelCount": 5,
"areaLabelCounts": { "South Beach": 13, "Downtown Miami": 2, "Miami": 2, "Ocean Front": 2, "North Beach": 1 },
"medianDistanceFromCentroidKm": 2.67,
"maxDistanceFromCentroidKm": 6.9,
"boundaryCheckPerformed": false
},
"limitations": [
{ "code": "results_include_nearby_areas", "message": "Airbnb may include nearby areas when local inventory is limited. ..." },
{ "code": "sample_truncated", "message": "Collection reached maxResults before search exhaustion." }
]
},
"assumptions": {
"downPaymentPercent": 20,
"interestRatePercent": 7,
"loanTermYears": 30,
"closingCostsPercent": 2.5,
"furnishingBudget": 0,
"propertyTaxAnnual": 9181.6,
"propertyTaxSource": "observed_from_zillow",
"insuranceAnnual": 4800,
"insuranceSource": "user_provided",
"hoaAnnual": 1296,
"hoaSource": "observed_from_zillow",
"managementFeePercent": 15,
"maintenanceReservePercent": 8,
"platformFeePercent": 3,
"utilitiesAnnual": 0
},
"projections": {
"loanAmount": 399200,
"totalCashInvested": 112275,
"monthlyMortgagePayment": 2655.89,
"projectionCompleteness": "complete",
"missingAssumptions": [],
"scenarios": [
{
"scenario": "base",
"nightlyRateSource": "airbnb_median",
"nightlyRate": 241.75,
"occupancyPercent": 60,
"grossAnnualRevenue": 52943.25,
"totalOperatingExpensesAnnual": 29042.85,
"excludedExpenseCategories": [],
"noiAnnual": 23900.41,
"annualDebtService": 31870.65,
"annualCashFlow": -7970.25,
"monthlyCashFlow": -664.19,
"capRatePercent": 4.79,
"cashOnCashReturnPercent": -7.1,
"dscr": 0.75,
"breakEvenOccupancyPercent": 72.21,
"breakEvenAchievable": true,
"suppressedReasons": []
}
]
}
}

Reading it: the property covers its own operating costs (cap rate 4.79%) but not the mortgage on top of them at 60% occupancy (DSCR 0.75, cash flow −$7,970/yr) — it would need about 72% occupancy to break even under these assumptions. Those assumptions are yours to change, and the occupancy figure in particular is an input, not a market forecast.

When the evidence isn't strong enough

If the Airbnb comparable sample's confidence is low or insufficient, every revenue-dependent field comes back null with a reason — observedZillow, observedAirbnbComparables (including the real sample size and confidence), and assumptions are still returned in full:

{
"scenario": "base",
"nightlyRate": null,
"grossAnnualRevenue": null,
"noiAnnual": null,
"capRatePercent": null,
"breakEvenOccupancyPercent": null,
"breakEvenAchievable": null,
"suppressedReasons": ["insufficient_airbnb_comparables"]
}

HOA is judged by property type. On a condo, townhouse, or apartment — where a monthly fee is effectively universal — an unknown HOA counts as genuinely missing data and suppresses the NOI family, because silently omitting a few hundred dollars a month would overstate returns. On a detached single-family home, no reported HOA usually means no HOA, so the projection still completes and simply lists hoa under excludedExpenseCategories. Supplying hoaMonthlyOverride (including an explicit 0) always resolves it.

The same applies, independently, when property tax or insurance is unknown: revenue stays visible (it doesn't depend on expenses) but every field that combines revenue with an incomplete cost basis — NOI, cash flow, cap rate, cash-on-cash, DSCR, break-even — is suppressed rather than silently computed on known costs only. projections.missingAssumptions and projections.projectionCompleteness (complete / partial_expenses / revenue_unavailable) summarize this at a glance; scenario.suppressedReasons explains each one.

Understanding the numbers

  • Break-even occupancy is never clamped to 100% — a deal that can't work even at full occupancy still shows its real value (e.g. 354%), paired with breakEvenAchievable: false so it's machine-readable without misreading an oversized percentage as a typo.
  • Cash flow, cash-on-cash return, and cap rate are never floored at zero — a losing deal shows a real negative number.
  • Cap rate excludes debt service (NOI ÷ price); it can stay positive even when cash flow (which includes the mortgage payment) is negative.
  • DSCR (debt service coverage ratio) is NOI ÷ annual debt service — below 1.0 means the property's own operations don't cover the mortgage payment.

What the comparable set actually covers

Three things about the Airbnb comparable set are easy to assume and wrong, so the output states each of them explicitly rather than leaving you to infer it.

searchLocation is the search request, not a boundary. It is built from the subject property's own city and state and handed to the Airbnb Actor. Airbnb widens a search into nearby areas when local inventory is thin — especially when the bedroom filter is restrictive for that market — so some comparables can sit outside the named municipality. Nothing here geocodes the request or checks municipal boundaries. What you get instead is the evidence:

  • observedAirbnbComparables.geographicScope — the Airbnb Actor's own measurements of where the delivered listings actually are: dominantAreaLabel and dominantAreaLabelSharePercent, the full areaLabelCounts distribution, the centroid, and median/p90/max distance from it.
  • observedAirbnbComparables.limitations — passed through verbatim and never filtered. A results_include_nearby_areas entry means exactly that: the sample is not confined to searchLocation. Check geographicScope before treating the statistics as a single-city market.

The nightly rates are guest-facing prices for one sampled stay window. The Actor asks for a four-night stay about a month out and reads the resulting per-listing nightly prices. Where Airbnb labels no per-night price, the Airbnb Actor derives one as the displayed stay total divided by the number of nights — so a rate can include guest-facing fees such as cleaning and service fees that are contained in that displayed total. observedAirbnbComparables.nightlyRateBasis says this on every record, alongside stayCheckIn, stayCheckOut, stayLengthNights, and medianTotalPriceForStay so the relationship between the nightly and total figures is visible.

This means the rates are market evidence for comparison, not a guaranteed host payout, and this is not a seasonality model: annual revenue extrapolates one sampled window across a full year at the occupancy you supply. Occupancy remains entirely your assumption throughout.

It is a capped sample, not a census. observedAirbnbComparables.sampleCoverage reports listingsCollected, listingsAcceptedForPricing (the ones that actually drove the rates), listingsExcludedFromPricing with per-reason counts, and truncated — true whenever collection stopped at your maxComparables before the search was exhausted. Listings priced for a different stay length are excluded rather than mixed in.

How the representative property is selected

When you provide location instead of a specific listing, the Actor fetches a sample of ~20 active Zillow listings for that market, filters to ones with enough data to analyze (a real price, bedroom count, and listing URL), then picks the one closest to the sample's median price among listings sharing the sample's most common bedroom count — ties broken deterministically. It never considers projected revenue, occupancy, or any other return signal, and it is never presented as a recommendation.

Before doing any of this, the Actor cross-checks the requested location against the addresses Zillow's search actually returned. If they don't plausibly match — which can happen because Zillow doesn't error on an unrecognized location; it can silently substitute a nearby fallback region and still return real-looking listings from there — the run fails with a clear message rather than silently analyzing the wrong market.

Data quality and limitations

  • V1 is single-property analysis only. No batch mode or cross-location ranking yet.
  • Insurance has no default and is never inferred — Zillow does not publish it for any listing. Provide insuranceAnnual for a complete cost basis, or the NOI-family metrics stay null.
  • Occupancy percentages are your own assumption, not a market forecast, regardless of how they're labeled elsewhere in this description.
  • The Airbnb comparable set is a live sample, not a certified market report — its size, confidence, coverage, geographic spread, and every limitation the Airbnb Actor reported are disclosed alongside the rates. There is no comparable radius and no city-boundary check; see What the comparable set actually covers.
  • A representative-location analysis is a reference point, not a recommendation — for a real purchase decision, use zillowListingUrl with the exact property.
  • This Actor performs no new scraping of its own — it orchestrates this account's Zillow and Airbnb Actors and does the financial math; data quality limitations of those Actors (documented in their own READMEs) apply here too.

Zillow Showcase listings return fewer fields

Some Zillow listings are served as Showcase properties, whose detail payload is a different one from Zillow's standard for-sale detail page. A Showcase record commonly omits fields such as monthlyHoaFee, propertyTaxRatePercent, yearBuilt, zestimate, days on Zillow, and broker/image metadata.

When that happens:

  • The missing values stay null. This Actor never replaces an unavailable Zillow observation with an invented one, and never treats a missing cost as $0.
  • If a material assumption is among them — property tax, or HOA on a condo/townhouse — the metrics that depend on a complete cost basis (NOI, cap rate, cash flow, cash-on-cash, DSCR, break-even occupancy) are suppressed rather than computed on a partial basis. The observed Airbnb rates and gross revenue are still shown, and projections.suppressedReasons names each missing assumption. See When the evidence isn't strong enough.
  • observedZillow.detailSource tells you which payload the observation came from — "for_sale_priority" for a standard detail page, "showcase" for a Showcase one, or null when the Zillow Actor didn't report it. It is passed through verbatim, never inferred, so a sparse observedZillow block is easy to tell apart from a fault.

You can always supply propertyTaxAnnual and hoaMonthlyOverride (and insuranceAnnual) yourself to get a complete analysis for a Showcase property.

Integrations

Standard Apify dataset output — export to JSON/CSV/Excel, or feed it into Make, n8n, Zapier, Google Sheets, Airtable, webhooks, or a custom workflow.

Performance

Measured directly on the Apify platform (256MB, default settings):

  • Location-only run: ~35–40 seconds end to end (one Zillow search call, one Zillow target-listing call, one Airbnb comparable search), ~45–65MB peak memory.
  • Direct-URL run: ~25–30 seconds (skips the Zillow search call), similar memory.
  • A target listing with no usable price (off-market/unpriced) fails in ~16 seconds, before any Airbnb comparable search is spent on it.
  • Zero retries and no proxy traffic across every run measured in production testing.

Pricing

Complete analyses cost $0.15 (analysis_complete) and insufficient-evidence analyses cost $0.05 (analysis_insufficient), plus the underlying Zillow and Airbnb Actor charges used to retrieve property and comparable data. Failed runs are not charged by this Actor — this only fires once a full analysis record has actually been produced.

Those child-Actor charges run under and bill to your account directly, at their own published per-event prices — this Actor calls this account's zillow-market-intelligence and airbnb-market-intelligence Actors internally, and Apify's platform model bills nested Actor calls to whoever's account is running the calling Actor, not to us. Apify's pricing tab shows only this Actor's own per-event price, so budget for the child charges on top of it.

Measured on the Apify platform at the default maxComparables of 20:

RunThis ActorZillow childAirbnb childTotal
zillowListingUrl (one listing lookup)$0.15$0.002$0.040~$0.192
location (market search plus listing lookup)$0.15$0.042$0.040~$0.232

Child usage varies with the market, so treat these as a guide rather than a fixed price. The Airbnb portion scales directly with maxComparables — at 100 comparables it is about $0.20 instead of $0.04, adding roughly $0.16 to either row. An analysis_insufficient run costs $0.05 instead of $0.15 for this Actor's share. Failed runs are not charged by this Actor at all.

Troubleshooting

Run fails with "does not appear to match the market Zillow actually searched." Your location wasn't recognized by Zillow and it silently substituted a nearby region — try a more specific city/state, or a ZIP code.

Run fails with "no usable price." The target listing is off-market, an unpriced lot/auction listing, or otherwise lacks a price Zillow can report — this fails fast, before spending an Airbnb comparable search on it.

Every scenario's revenue fields are null. Check observedAirbnbComparables.confidence — if it's low or insufficient, the comparable sample wasn't strong enough to support a defensible nightly-rate estimate. Try a larger maxComparables, or expect this for very unusual properties (extreme bedroom counts, remote markets) where comparable Airbnb listings are genuinely scarce.

NOI, cash flow, and cap rate are null even though revenue shows a number. Check projections.missingAssumptions — property tax or insurance is unknown. Provide insuranceAnnual (always required — Zillow never reports it) and/or propertyTaxAnnual if Zillow doesn't publish a rate for this listing.

FAQ

Does this recommend properties or predict returns?

No. Property selection (when using location) is deterministic and based only on price and bedroom count — never on projected return. Projections are clearly labeled estimates based on your stated assumptions, never facts, market predictions, or guarantees.

Why is insurance never filled in automatically?

Zillow doesn't publish insurance costs for any listing, and insurance varies enormously by location, coverage, and whether a policy allows short-term rental use. A national or regional average would materially mislead a specific property's numbers, so this Actor never guesses it.

Can I run this for multiple properties or rank locations?

Not in V1 — that's planned as a separate batch/ranking mode. This version is single-property analysis only.

What happens if I give both a URL and a location?

The input schema requires exactly one — the run is rejected with a clear validation error before either Actor is called.