# Short Term Rental Data API - Airbnb Revenue, Occupancy (`nabeelbaghoor/short-term-rental-data-api`) Actor

Get short term rental market data, Airbnb and Vrbo listing revenue, occupancy and daily rates, monthly market metrics with percentiles, forward pricing, comparable rentals near any address, and projected revenue estimates for any address worldwide.

- **URL**: https://apify.com/nabeelbaghoor/short-term-rental-data-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 $12.00 / 1,000 short term rental 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

## Short Term Rental Data API - Airbnb Revenue, Occupancy

Find out what any short term rental market earns, what every listing in it actually books, and what a specific address would make as an Airbnb, from one actor.

### What this actor does

- **Revenue estimate for any address.** Paste addresses, get projected revenue for the next twelve months with a lower and upper bound, projected occupancy and projected average daily rate. Turn on full detail for the month by month forward curve, the history, and every comparable rental behind the estimate.
- **Listing level performance.** Search the individual rentals inside a market, submarket, country or a radius around an address. Every row carries revenue and revenue potential over the last twelve months, occupancy rate, average daily rate, nights available, blocked and reserved, reservation count, cleaning fee, and the Airbnb, Vrbo and Booking.com identifiers.
- **Market and submarket scores.** Market score, average revenue, occupancy, average daily rate and RevPAR for the last twelve months, plus the market type and active listing count.
- **Monthly market metrics.** Seven series - occupancy, average revenue, average daily rate, RevPAR, booking lead time, average length of stay and active listing count - one row per month, with the month on month and year on year change and an optional percentile spread so you see the range across the market rather than only its average.
- **Forward pricing.** What listings in a market are priced at for dates that have not happened yet.
- **Filter on 20+ real attributes.** Guest capacity, bedrooms, bathrooms, occupancy, nights available, rating, review count, price tier, listing type, property type, booking channel, 16 amenities, superhost, instant book, professional management, and the provider's own investability, demand, revenue growth, seasonality and regulation scores.
- **Pay per result.** You are charged for rows that carry a real record. Addresses the provider cannot place are free.

### Bring your own key

This actor calls the provider with **your own API key**. 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.

The provider sells its data in four packages - market data, listings and comparables, address level estimates, and dynamic rate recommendations - and a key is entitled to the ones you bought. A key that is valid but not entitled to a package returns a 403, and this actor reports that as an entitlement problem rather than a bad key, so you are not left changing a key that was never wrong.

### Start here

Every mode except market search and the address modes needs a market ID, and market search is how you get one. Run it first with a place name, read the `regionId` column, then feed that into market details, market metrics or a listings search.

### Example output

```json
{
  "recordType": "listing",
  "requested": "market airdna-163",
  "found": true,
  "propertyId": "airbnb-31977147",
  "title": "Sunny loft in LoHi with mountain views",
  "marketName": "Denver",
  "cityName": "Denver",
  "stateName": "Colorado",
  "zipCode": "80211",
  "latitude": 39.762,
  "longitude": -105.014,
  "exactLocation": false,
  "listingType": "entire_place",
  "propertyType": "loft",
  "bedrooms": 2,
  "bathrooms": 1,
  "accommodates": 4,
  "revenueLtm": 48120,
  "revenuePotentialLtm": 61340,
  "occupancyRateLtm": 0.72,
  "averageDailyRateLtm": 218.4,
  "daysAvailableLtm": 302,
  "daysReservedLtm": 218,
  "numReservationsLtm": 74,
  "rating": 4.91,
  "reviews": 186,
  "superhost": true,
  "professionallyManaged": false,
  "hostSize": "2-5",
  "currency": "usd"
}
```

### FAQ

#### How do I estimate what an address would earn as a short term rental?

Use rental estimate mode and paste the address. The actor returns projected revenue for the next twelve months with a lower and upper bound, projected occupancy and projected average daily rate. Leave the subject bedrooms, bathrooms and guest capacity empty and the provider fills them in from its own records, which is what you want when working from a list of addresses. Turn on full detail to also get the month by month curve and the comparable rentals the estimate was built from.

#### What is the difference between revenue and revenue potential?

Revenue is what the listing actually earned over the last twelve months. Revenue potential is what it would have earned had it been available for booking every night of that year. A listing that was only open for three months shows a low revenue and a high potential, so comparing the two tells you whether a weak number means weak demand or simply a closed calendar.

#### Why is occupancy a decimal rather than a percentage?

The provider expresses occupancy as a share of availability between 0 and 1, so 0.72 means seventy two percent of the nights the listing was open were booked. The filters use the same scale, which is why the occupancy filter takes `>=0.6` rather than `>=60`.

#### Are the listing coordinates exact?

Not always, and the row tells you which you have. The `exactLocation` flag is true when the latitude and longitude are the listing's real position and false when the provider has scrambled them within about 500 metres, which it does for listings whose exact address it will not publish. Treating a scrambled pin as exact is the usual mistake when mapping this data.

#### How do I compare two markets side by side?

Run market search on both names to get their IDs, then market details with both IDs in one run. That returns one row each with the market score, average revenue, occupancy, average daily rate and RevPAR on the same basis. For the trend rather than the level, run market metrics with both IDs and twelve months, which gives one row per month per series.

#### What do the percentiles add?

An average hides the spread. Asking for 0.25, 0.5 and 0.75 on the occupancy, revenue or daily rate series returns those percentiles alongside the mean, so you can see whether a market's average revenue comes from a broad middle or from a handful of high performers. Only those three series accept percentiles; the actor attaches them per series rather than to everything, because sending them to a series that does not take them is a rejected request.

#### Can I find every rental within a mile of a property?

Yes. Area comparables mode takes an address or a latitude and longitude plus a radius in metres, and returns the listings inside it with their full performance figures. Sort by proximity for a true comparables set, or by revenue to see the top performers nearby.

#### Which booking platforms does this cover?

Airbnb, Vrbo and Booking.com. Each listing row carries the identifier and URL it has on each platform, so a blank Vrbo ID means the listing is not advertised there. The booking channel filter narrows by platform, and the match setting controls whether you want listings on any of the chosen platforms, only on those, or on exactly those and no others.

#### Why are there only 25 rows per request?

That is the provider's ceiling on every paged endpoint, not a setting in this actor. It means a run over a whole market is many requests rather than a few, so if your plan is metered per request, set the maximum rows and requests per minute with that in mind. The actor pages automatically and stops at your row cap.

#### What does it cost?

Pricing is pay per result: 0.012 USD per listing, 0.008 USD per market or submarket record, 0.006 USD per month of market metrics or day of forward pricing, and 0.02 USD per revenue estimate, with Apify platform usage included. Rows the provider found nothing for are not charged. You also need your own account with the data provider, which bills on its own plans.

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

No. A missing key, a rejected key, a key not entitled to the package you asked for, an exhausted plan allowance or an empty input all end the run cleanly with a message saying what to change. Only a real outage or a bug fails the run.

### Keyword map

short term rental data API, Airbnb data API, Airbnb revenue estimate, Vrbo data, STR market data, vacation rental analytics, Airbnb occupancy rate, average daily rate ADR, RevPAR short term rental, rentalizer, Airbnb comps, short term rental market research, vacation rental revenue projection, STR investment analysis, Airbnb listing scraper alternative, short term rental regulation score, booking lead time, seasonality score

# Actor input Schema

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

Market search finds the provider's market and submarket IDs, which every other mode needs. Market details reads the score and last twelve months for those IDs. Market metrics reads the monthly series behind them. Listings searches the individual rentals inside a market, submarket or country. Area comparables searches within a radius of an address. Rental estimate takes plain addresses and returns projected revenue.

## `searchTerms` (type: `array`):

Market search mode. One place name per line, for example Denver, or Cornwall, or a ZIP code. Each one returns the markets and submarkets the provider matches to it, with the IDs the other modes need.

## `regionIds` (type: `array`):

One market or submarket ID per line, as returned by market search. Used by market details, market metrics, future pricing and listings. In explore mode a single market ID lists that market's own submarkets instead.

## `regionKind` (type: `string`):

Whether the IDs above are markets or submarkets. A submarket is a neighbourhood sized area inside a market, so the same ID is not valid for both.

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

Explore markets mode, and listings mode when no market ID is set. A two letter country code such as us, gb, fr or au.

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

Listing details and listing comparables modes. One listing ID per line, as returned in the propertyId column of a listings search.

## `addresses` (type: `array`):

Rental estimate and area comparables modes. One address per line. The provider geocodes each one, so a full street address with city and region matches best.

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

An alternative to a place name or address in market search, area comparables and rental estimate modes. Give a longitude with it.

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

An alternative to a place name or address in market search, area comparables and rental estimate modes. Give a latitude with it.

## `radiusMeters` (type: `integer`):

Area comparables mode. How far from the address or point to search, in metres. 1600 is about one mile.

## `metrics` (type: `array`):

Market metrics mode. Which monthly series to read. Each one produces one row per month. Occupancy, average revenue and average daily rate are read when none is chosen.

## `numMonths` (type: `integer`):

Market metrics and future pricing modes. How many months to read. Twelve months of history is the usual basis for a year on year comparison.

## `percentiles` (type: `array`):

Market metrics mode, on the occupancy, revenue and daily rate series only. One decimal per line between 0 and 1, for example 0.25, so you get the spread across the market rather than only its average.

## `currency` (type: `string`):

The three letter currency code money figures are returned in, lower case, for example usd, eur or gbp. The provider converts on its side.

## `accommodates` (type: `string`):

Guest capacity. Write an exact number such as 8, a comparison such as >=6, or a range such as 2-8. The same three spellings work on every numeric filter below.

## `bedrooms` (type: `string`):

An exact count such as 3, a comparison such as >=2, or a range such as 2-4.

## `bathrooms` (type: `string`):

An exact count such as 2, a comparison such as >=1.5, or a range such as 1-3.

## `occupancyRateLtm` (type: `string`):

Expressed as a decimal share rather than a percentage, so 0.6 means sixty percent. A comparison such as >=0.6 or a range such as 0.6-1 both work.

## `daysAvailableLtm` (type: `string`):

How many nights the listing was open for booking. A high value separates a full time rental from an occasional one, for example >=300.

## `ratings` (type: `string`):

Out of five. A comparison such as >=4.5 keeps only well reviewed listings.

## `reviewsCount` (type: `string`):

How many reviews the listing has. A comparison such as >=20 filters out listings too new to judge.

## `listingCount` (type: `string`):

Explore markets mode. How many active listings a market has, for example >=500 to keep only markets with real depth.

## `investability` (type: `string`):

The provider's 0 to 100 score for a market as an investment. A comparison such as >=60 works.

## `rentalDemand` (type: `string`):

The provider's 0 to 100 demand score for a market, for example >=70.

## `revenueGrowth` (type: `string`):

The provider's 0 to 100 revenue growth score for a market.

## `seasonality` (type: `string`):

The provider's 0 to 100 seasonality score. A low score means demand is spread evenly through the year.

## `regulation` (type: `string`):

The provider's 0 to 100 score for how permissive a market's short term rental rules are. A high score means fewer restrictions.

## `listingType` (type: `array`):

Keeps only listings of these types. Entire place is the whole property; private room and shared room are parts of one.

## `propertyType` (type: `array`):

Keeps only listings of these property types, in the provider's own spelling, for example house, apartment, condominium, townhouse, villa, cabin, cottage or loft.

## `realEstateType` (type: `array`):

A coarser grouping than property type, useful when you want every kind of house or apartment without listing each spelling.

## `priceTier` (type: `array`):

The provider's price banding for a listing within its own market, so upscale means upscale locally rather than in absolute terms.

## `marketType` (type: `array`):

Explore markets mode. Keeps only markets of these kinds.

## `marketIds` (type: `array`):

A filter rather than a location: keeps only records belonging to these market IDs. Useful when exploring a country and you want a named subset of it.

## `channels` (type: `array`):

Keeps only listings advertised on these platforms.

## `channelMatch` (type: `string`):

Any means the listing is on at least one of them. Only these means it is on no others. Exactly these means it is on all of them and no others.

## `amenitiesRequired` (type: `array`):

Keeps only listings with all of these.

## `amenitiesExcluded` (type: `array`):

Keeps only listings without any of these. An amenity named on both lists is treated as required, since that is the deliberate half of the contradiction.

## `instantBook` (type: `boolean`):

Leave this alone to ignore it. Ticked keeps only instant book listings; the filter is applied only when you set it either way.

## `superhost` (type: `boolean`):

Leave this alone to ignore it. Ticked keeps only listings whose host holds superhost status.

## `professionallyManaged` (type: `boolean`):

Leave this alone to ignore it. Ticked keeps only listings run by a management company rather than an individual host.

## `listingSortOrder` (type: `string`):

Listings mode. Results come back highest first.

## `compsSortOrder` (type: `string`):

Area comparables mode. Proximity returns the nearest listings first, which is usually what a comparables set should be.

## `marketSortOrder` (type: `string`):

Explore markets mode. Results come back highest first.

## `detailedEstimates` (type: `boolean`):

Rental estimate mode. Off returns the headline projection and batches up to 25 addresses per request, which is much faster and cheaper. On returns the month by month forward curve, the history and every comparable behind the estimate, one address per request.

## `estimateBedrooms` (type: `integer`):

Rental estimate mode. Describes the property being valued. Leave empty to have the provider fill it in from its own records, which is usually what you want when working from a list of addresses.

## `estimateBathrooms` (type: `integer`):

Rental estimate mode. Describes the property being valued. Leave empty to have the provider fill it in.

## `estimateAccommodates` (type: `integer`):

Rental estimate mode. How many guests the property sleeps. Leave empty to have the provider fill it in.

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

The most rows this run will save and charge for. This is the spending control on both sides.

## `pageSize` (type: `integer`):

How many rows to ask for at a time. The provider's ceiling is 25 on every paged endpoint, so a whole market takes many requests.

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

How fast to call the provider. Lower this if your plan is metered tightly, since the 25 row page cap means row counts and request counts are close together.

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

Only set this if the provider has given you a different host. Leave empty to use the documented one.

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

Your own API key for the short term rental data provider. This actor is bring your own key: it never uses anyone else's credentials, and the key is stored as a secret. A leading Bearer is stripped for you if you paste one.

## Actor input object example

```json
{
  "mode": "marketSearch",
  "regionKind": "market",
  "radiusMeters": 1600,
  "numMonths": 12,
  "currency": "usd",
  "channelMatch": "any",
  "listingSortOrder": "revenue",
  "compsSortOrder": "revenue",
  "marketSortOrder": "market_score",
  "detailedEstimates": false,
  "maxResults": 1000,
  "pageSize": 25,
  "requestsPerMinute": 120
}
```

# Actor output Schema

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

One row per record, alongside the market, listing or address 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/short-term-rental-data-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/short-term-rental-data-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/short-term-rental-data-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/short-term-rental-data-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/kh0ZpQb4qCcFtGsfu/builds/gL32FvppfRKE8psaT/openapi.json
