# Real Estate Investment API - Airbnb ROI, Rents, Comps (`nabeelbaghoor/real-estate-investment-api`) Actor

Analyse any US rental property: Airbnb and long term rental income, occupancy, cap rate, cash on cash return and cash flow side by side, plus rental comps, rent estimates by bedroom count, property records, sale and tax history, market revenue statistics and short term rental regulations by city.

- **URL**: https://apify.com/nabeelbaghoor/real-estate-investment-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Real estate, Travel, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 listing returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Real Estate Investment API - Airbnb ROI, Rents, Comps

Run the numbers on any US rental property. Short term and long term income, occupancy, cap rate, cash on cash return and cash flow - side by side on the same row, never blended - plus the comps behind them, the market around them, and whether short term letting is even legal there.

### What this actor does

- **Both strategies, always separate.** Every property, listing and market row carries an Airbnb figure and a traditional figure in their own columns: rental income, cap rate and cash on cash return for each. Averaging the two answers no question anyone actually has.
- **A full investment analysis per property.** Cap rate, cash on cash return, monthly cash flow, total expenses and ROI, with your own assumptions for purchase price, down payment, loan term, interest rate, occupancy, maintenance, management, tax, insurance and startup cost.
- **Rental comps that are actually comparable.** Nearby short term rentals with their nightly rates, occupancy and earnings, and nearby long term rentals with their rents - sorted by similarity, distance, occupancy, price or income.
- **Rent estimates by bedroom count.** Studio through four bedroom values for a city, ZIP code or neighborhood, plus a detail row per bedroom tier with the minimum, maximum, average and median rent, the sample count, and the rent adjusted for vacancy.
- **Property records.** Beds, baths, square footage, year built, lot size, parcel number, the full sale and loan history, the assessment and tax history, and what several valuation houses each think the property is worth.
- **Short term rental listings in depth.** One Airbnb or VRBO listing with its nightly rate, modelled revenue, occupancy, reviews, capacity and whether it is still live - plus its last twelve months and its forward projections.
- **Whole markets.** Active listings, market summaries, occupancy for every listing in a market, revenue percentiles, the property type mix, what each amenity is associated with, twelve months of history, top cities and neighborhoods, and an investment heatmap across a map box.
- **Short term rental regulations.** Legal status, permit requirements, occupancy limits and minimum stays by city, with a link to the official source. The one lookup that can invalidate every other number on this page.
- **Pay per result.** You are charged for rows carrying a real record. Addresses the provider cannot match, markets with no coverage and searches that find nothing are free.

### Bring your own key

This actor calls the provider with **your own API key**, from your developer account. Paste it into the API key field, or set it as the `DATA_API_KEY` secret. Nothing runs on anyone else's credentials, and a run without a key ends cleanly with an explanation rather than failing.

### Set the state, and check the city name

Every endpoint on this API requires the two letter state code. This is not a formality: the provider validates parameters **before** it checks your key, so a request without a state comes back as a bare rejection that mentions nothing else - and would come back the same way with a perfect key. This actor refuses such a run up front and says so, and never reports a missing-parameter rejection as a credential problem.

City names are the other quiet trap. The provider drops "City" and "Town" suffixes by its own naming rules, so "Ashville City" finds nothing while "Ashville" works. This actor strips those suffixes automatically, and **validate city** mode checks a name and returns the canonical spelling plus suggestions before you spend anything on it.

### Occupancy is two different numbers

The provider reads the occupancy you supply as a **percentage of the year** or as **nights per year**, depending on a separate flag that defaults to percentage. Sending 65 meaning "65 percent" while the flag says nights is a silent five-fold error that propagates through every return it calculates, and nothing in the response says it happened.

So this actor takes the unit explicitly - percentage or nights - derives the flag from it, and writes the unit onto every investment row. You cannot get it wrong by accident, and you can tell afterwards which you used.

### What this actor will not do

The provider's API also returns property owners' contact details, demographics, household income and wealth scores. Those endpoints are deliberately not implemented here. This actor reads property and market data, not personal information about named individuals.

### Example output

```json
{
  "recordType": "investment",
  "requested": "5505272",
  "found": true,
  "propertyId": "5505272",
  "address": "1823 Schyler Love Lane",
  "city": "El Paso",
  "state": "TX",
  "listPrice": 289000,
  "occupancyUnit": "percent",
  "airbnbRentalIncome": 3235,
  "airbnbOccupancy": 62,
  "airbnbCapRate": 7.41,
  "airbnbCashOnCash": 9.34,
  "airbnbCashFlow": 1204,
  "traditionalRentalIncome": 1270,
  "traditionalOccupancy": 95,
  "traditionalCapRate": 3.18,
  "traditionalCashOnCash": 1.92,
  "traditionalCashFlow": 213
}
```

### FAQ

#### How do I calculate Airbnb ROI for a property?

Run **investment performance** with the property ID and your own assumptions - purchase price, down payment, loan term, interest rate, occupancy, running costs. It returns cap rate, cash on cash return, monthly cash flow, total expenses and ROI for the short term strategy and the long term strategy in separate columns, so you can see which one the property is actually for. **Investment breakdown** does the same one strategy at a time with a monthly and annual split.

#### What is the difference between cap rate and cash on cash return?

Cap rate is net operating income over the purchase price, ignoring how you paid for it. Cash on cash return is annual cash flow over the cash you actually put in, so it moves with the mortgage. A cash purchase makes the two converge; a heavily financed one pulls them apart. Both are returned for both strategies.

#### How do I find Airbnb rental comps near a property?

Run **Airbnb comps** with the neighborhood ID and, optionally, the property ID of the subject. It returns nearby short term rentals with matching bedroom and bathroom counts, each with its nightly rate, occupancy, modelled income, review count and distance, sorted by similarity, occupancy, income or distance. The provider's own default page size is three, which is not a comp set, so this actor asks for twenty unless you say otherwise. **Long term comps** does the equivalent for traditional leases by city or ZIP code.

#### What rent can I get for a property in this area?

Run **rent estimate** with a city, ZIP code or neighborhood and a strategy. It returns the studio through four bedroom values for the area, the sample count behind them, and a detail row per bedroom tier with the minimum, maximum, average and median rent - plus the rental income adjusted for the provider's vacancy assumption, which is the number to use in an underwriting model rather than the raw average.

#### Is short term renting legal in a given city?

Run **short term regulations** with a state and city. It returns the legal status, the regulation rating, whether a permit is required, occupancy limits, minimum stay requirements and a link to the official source. Worth running before any of the revenue modes: a strong Airbnb cap rate in a city that bans short lets is not an investment case.

#### What market data can I get for a city or ZIP code?

Market lookup gives cap rate, occupancy, median home price, nightly rate and rental income for a city, ZIP, neighborhood or address. Revenue stats adds the percentiles behind those medians. Property types breaks the market down by home type with counts and per-type income. Market history returns rental income, nightly rate and occupancy month by month with year on year changes. Amenity performance says what each amenity is associated with in revenue terms. Top markets, top Airbnb cities and top neighborhoods rank locations within a state.

#### How do I find a neighborhood ID?

Run **city neighborhoods** with a state and city. Every other neighborhood-level mode takes that identifier. **Top neighborhoods** returns the highest-occupancy ones directly.

#### Why can I only see inactive MLS listings?

Because MLS redistribution rules restrict what can be shared through a third-party API. The provider states that MLS data shared this way is limited to inactive listings. Active for-sale inventory comes through the listing search and nearby property modes instead.

#### Can I get owner contact details?

Not through this actor. The provider's API does expose owner contact, demographic and financial endpoints, and they are deliberately left out here - this actor returns property and market data, not personal information about named individuals.

#### What does it cost?

Pricing is per result. You pay for rows that carry a real record: a listing, a property, an investment analysis, a rent estimate, a short term listing, a performance period, a market, a statistic, a tax or sale record, a valuation, a regulation or a school. Addresses the provider cannot match, markets with no coverage and searches that find nothing are all free. Apify platform usage is included in the per-result price.

#### Does the actor fail if my key is wrong?

No. A missing key, a refused key, an exhausted plan allowance and an input that needs filling in all end the run cleanly with the reason as the run's status message. Only a real fault - a provider outage, or a bug here - fails a run.

### Keyword map

real estate investment API, Airbnb data API, short term rental data API, rental property ROI calculator API, cap rate API, cash on cash return data, Airbnb occupancy rate data, Airbnb revenue estimate API, rental comps API, long term rental comps, rent estimate by ZIP code, US property records API, property sale history API, property tax history data, MLS listings data, real estate market data API, short term rental regulations by city, VRBO listing data, investment property search API, neighborhood investment data.

# Actor input Schema

## `mode` (type: `string`):

Listing search finds properties for sale in a market. The property modes read one property's record, taxes, sales history and valuations. Investment performance runs the deal on both strategies. The comps modes find what similar properties actually earn. Rent estimate prices an area by bedroom count. The market modes read revenue statistics, property mix and history. The short term modes read one listing or a whole market, and regulations reads whether letting is even permitted.

## `state` (type: `string`):

Two letter state code, for example CA or TX. Every endpoint on this API requires it, and a request without one is rejected before the key is even checked.

## `city` (type: `string`):

City name, for example Austin. A trailing "City" or "Town" is dropped automatically, because the provider's own naming rules reject those suffixes and answer with an empty result rather than an error. Validate city mode checks a name before you spend anything on it.

## `zipCode` (type: `string`):

Five digit ZIP code, as an alternative to a city for most market modes.

## `neighborhoodId` (type: `string`):

The provider's own neighborhood identifier, for a market read at neighborhood level. City neighborhoods mode lists them for a city.

## `address` (type: `string`):

Street address for a property lookup or an address level market read. An address level market read also needs the latitude and longitude, and the provider quietly falls back to the city without them.

## `latitude` (type: `string`):

Decimal latitude, required alongside an address for an address level market read.

## `longitude` (type: `string`):

Decimal longitude, required alongside an address for an address level market read.

## `propertyId` (type: `string`):

A single property identifier, for the property lookup, nearby properties and comps modes.

## `parcelNumber` (type: `string`):

Assessor parcel number, as another way to identify a property.

## `mlsId` (type: `string`):

MLS listing identifier. Note that MLS data shared through this API is limited to inactive listings, because of MLS redistribution rules.

## `propertyIds` (type: `array`):

One property ID per line for the taxes, transactions, estimates, schools and investment modes.

## `neighborhoodIds` (type: `array`):

One neighborhood ID per line for the comps and neighborhood overview modes.

## `listingIds` (type: `array`):

One Airbnb or VRBO listing ID per line for the listing, history and projection modes. Active listings mode lists them for a market.

## `strategy` (type: `string`):

Which letting strategy to read. Short term and long term are modelled separately throughout and are never blended into one figure, because an Airbnb cap rate and a long lease cap rate answer different questions.

## `bedrooms` (type: `integer`):

Bedroom count. On listing search this is a minimum; on the comps and market modes it selects a bedroom tier.

## `bathrooms` (type: `integer`):

Bathroom count. On listing search this is a minimum.

## `homeType` (type: `string`):

Property type for the market calculator modes.

## `propertyType` (type: `string`):

Property type for listing search and the listing price trend, for example Single Family Residential or Condo/Coop.

## `minPrice` (type: `integer`):

Lowest listing price to include. A range typed backwards is corrected rather than sent, because the provider answers it with an empty market rather than an error.

## `maxPrice` (type: `integer`):

Highest listing price to include.

## `minSqft` (type: `integer`):

Smallest floor area to include in a listing search.

## `includeForeclosures` (type: `boolean`):

Include foreclosed properties in a listing search. Off by default, as on the provider.

## `excludeRented` (type: `boolean`):

Long term comps: leave out properties already marked rented, so the comp set reflects what is currently available.

## `occupancyUnit` (type: `string`):

Whether the occupancy figures you supply are a percentage or nights per year. This matters: the provider reads the same field both ways depending on a flag that defaults to percentage, so 65 meaning 65 percent sent as nights is a silent five-fold error in every return it produces. The unit is also written onto every investment row.

## `airbnbOccupancy` (type: `integer`):

Override the provider's short term occupancy assumption, expressed in the unit chosen above.

## `traditionalOccupancy` (type: `integer`):

Override the provider's long term occupancy assumption, expressed in the unit chosen above.

## `airbnbMonthlyRent` (type: `integer`):

Override the modelled monthly short term rental income, in dollars.

## `traditionalMonthlyRent` (type: `integer`):

Override the modelled monthly long term rent, in dollars.

## `purchasePrice` (type: `integer`):

Price to run the deal at, instead of the listing price. This is the number to change when you are testing an offer.

## `paymentType` (type: `string`):

Whether the deal is financed or bought outright. A cash purchase makes cash on cash and cap rate converge.

## `downPayment` (type: `integer`):

Down payment in dollars, for a financed deal.

## `loanTermYears` (type: `integer`):

Mortgage term, for example 30.

## `interestRate` (type: `string`):

Mortgage interest rate as a percentage, for example 6.5.

## `startupCost` (type: `integer`):

One-off setup cost in dollars. The provider assumes 8000 when this is blank, which is furnishing a short term rental.

## `airbnbMaintenanceCost` (type: `integer`):

Monthly maintenance cost for the short term strategy, in dollars.

## `traditionalMaintenanceCost` (type: `integer`):

Monthly maintenance cost for the long term strategy, in dollars.

## `airbnbManagementCost` (type: `integer`):

Monthly management cost for the short term strategy, in dollars.

## `traditionalManagementCost` (type: `integer`):

Monthly management cost for the long term strategy, in dollars.

## `airbnbPropertyTax` (type: `integer`):

Annual property tax to assume for the short term strategy, in dollars.

## `traditionalPropertyTax` (type: `integer`):

Annual property tax to assume for the long term strategy, in dollars.

## `airbnbInsurance` (type: `integer`):

Monthly homeowner insurance for the short term strategy, in dollars.

## `traditionalInsurance` (type: `integer`):

Monthly homeowner insurance for the long term strategy, in dollars.

## `includeValuationScore` (type: `boolean`):

Ask the provider for its property valuation score alongside the investment figures.

## `compsSortBy` (type: `string`):

Which field to order a comp set by. The two comp endpoints accept different vocabularies, so a value the endpoint does not know is ignored rather than rejected.

## `compsOrder` (type: `string`):

Ascending or descending. The provider defaults to descending.

## `compsPerPage` (type: `integer`):

How many comparables to fetch. The provider's own default is three, which is too few to be a comp set, so this actor asks for twenty when you leave it blank.

## `fullHistory` (type: `boolean`):

Market history mode: return more than the most recent twelve months.

## `regulationRating` (type: `string`):

Short term regulations: only return cities whose rules carry this rating.

## `countryCode` (type: `string`):

Two letter country code for the short term rental modes. The provider defaults to US.

## `heatmapMetric` (type: `string`):

Which measure to map across the box.

## `southWestLatitude` (type: `string`):

Heatmap: latitude of the box's south west corner. A box given corner-swapped is put back in order, because the provider answers an inverted box with an empty map rather than an error.

## `southWestLongitude` (type: `string`):

Heatmap: longitude of the box's south west corner.

## `northEastLatitude` (type: `string`):

Heatmap: latitude of the box's north east corner.

## `northEastLongitude` (type: `string`):

Heatmap: longitude of the box's north east corner.

## `maxResults` (type: `integer`):

Stop after this many rows. Each row is one charged result, so this is the ceiling on what a run can cost.

## `requestsPerMinute` (type: `integer`):

How fast to call the provider. Rate limits depend on your plan, and a rate limit response is honoured with the wait the provider publishes.

## `baseUrl` (type: `string`):

Only set this if the provider has given you a different host. Leave blank for the standard one.

## `apiKey` (type: `string`):

Your own real estate investment data API key, from your developer account. Leave blank to use the DATA\_API\_KEY environment secret instead.

## Actor input object example

```json
{
  "mode": "listingSearch",
  "strategy": "airbnb",
  "homeType": "",
  "includeForeclosures": false,
  "excludeRented": false,
  "occupancyUnit": "percent",
  "paymentType": "",
  "includeValuationScore": false,
  "compsSortBy": "",
  "compsOrder": "",
  "fullHistory": false,
  "regulationRating": "",
  "heatmapMetric": "AirbnbCoc",
  "maxResults": 100,
  "requestsPerMinute": 60
}
```

# Actor output Schema

## `records` (type: `string`):

One row per record, alongside the property, market or listing that produced it.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/real-estate-investment-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/real-estate-investment-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call nabeelbaghoor/real-estate-investment-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/real-estate-investment-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ZQBaKkdzqBcciBJpY/builds/aaPNzZBwwEmIbn8a1/openapi.json
