# AirDNA Scraper — STR Market Data & Airbnb Deals (`memo23/airdna-scraper`) Actor

Scrape AirDNA short-term-rental market metrics (revenue, occupancy, ADR, RevPAR, Market Score) and top Airbnb/Vrbo property deals from airdna.co.

- **URL**: https://apify.com/memo23/airdna-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Travel, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 market data rows

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

## AirDNA Scraper — STR Market Data & Airbnb Deals

**Turn AirDNA into structured short-term-rental market data.** Scrape any of the ~24,500 markets AirDNA publishes — active listings, annual revenue, occupancy, ADR and RevPAR, each with year-over-year change, plus the AirDNA Market Score and all five subscores. Switch modes and get the top 100 Airbnb/Vrbo listings in a market instead, with IDs, deep links, coordinates, nightly rate versus the market average, and a deal score. JSON, CSV or Excel out; you pay per result, not per run.

#### How it works

![How AirDNA Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-airdna.png)

#### ✨ Why use this scraper?

- **Two datasets, one actor.** Market-level performance metrics for investors and analysts, or individual property comps for hosts and pricing tools. `mode` picks; `both` writes them into the same dataset, tagged by `entityType`.
- **Whole-planet coverage without hunting URLs.** Enumeration reads AirDNA's own sitemap, so `country: "us"` gives every US market and `scrapeAllMarkets` gives all 24,564. No manual link collection, no pagination to configure.
- **Paste any link you happen to have.** A market URL and a top-deals URL describe the same place, so the actor rewrites whichever one you paste into the page the mode needs. You never have to know which family a link belongs to.
- **No proxy required.** AirDNA sits behind Cloudflare, but browser-grade TLS fingerprints pass it directly. That makes runs faster and cheaper than a proxied scraper, and a proxy is still there as an option if you want rotation.
- **Both display and numeric values.** AirDNA abbreviates money on the page (`$48.7K`). You get `annualRevenueDisplay: "$48.7K"` for reporting alongside `annualRevenue: 48700` for sorting and maths.
- **Caps that actually cap.** One top-deals page yields 100 rows at once. `maxItems` is claimed before rows are written, so a capped run stops exactly on the number instead of overshooting by up to 99 billable rows.

#### 🎯 Use cases

- **STR investment screening** — rank thousands of markets by RevPAR, revenue growth or Market Score to shortlist where to buy.
- **Regulatory and supply monitoring** — track active listing counts and their YoY change per market on a schedule to spot supply shocks or new restrictions biting.
- **Revenue benchmarking** — pull ADR and occupancy for a host's market and compare their listing against it.
- **Dynamic pricing inputs** — feed `marketAverageRate` and per-property `ratePerNight` into a pricing model.
- **Comp-set building** — property rows give bedrooms, bathrooms, guest count and coordinates, enough to assemble a comparable set around an address.
- **Market research and content** — the FAQ block on each market row is publication-ready Q\&A about that market's economics.
- **Lead generation for STR services** — property manager, cleaning and furnishing companies use active-listing density to pick which markets to enter.

#### 📥 Supported inputs

Four ways to choose markets. Combine them freely — results are merged and de-duplicated.

| Input | What it does | Example |
|---|---|---|
| `startUrls` | Any AirDNA market or top-deals URL | `https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview` |
| `country` | Every market in a country | `us`, `gb`, `fr`, `es`, `id` |
| `region` | Narrows to a state or region | `california`, `florida`, `london` |
| `searchTerms` | Market names in plain English | `["Los Angeles", "Big Bear Lake"]` |
| `scrapeAllMarkets` | All ~24,500 markets worldwide | `true` |

Leave all of them empty and the run defaults to AirDNA's 10 most-listed markets, so a bare run still returns something useful.

Both of these URL forms are accepted, and either works for either mode:

```
https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview
https://www.airdna.co/top/us/california/los-angeles
```

#### 🔄 How it works

1. **Select.** Your inputs are resolved into a list of markets. Anything that needs the full market list reads AirDNA's `sitemap-top-10.xml` once — a single request that yields all 24,564 published markets, which is why country and region filters are instant.
2. **Rewrite.** Each selected market is turned into the page family `mode` requires: the `/vacation-rental-data/app/…/overview` page for market metrics, the `/top/…` page for property deals, or both.
3. **Fetch.** Pages are pulled in a sliding-concurrency window across three independent HTTP stacks (impit, got-scraping, impers) with real browser TLS fingerprints. A slow page never blocks the next one from starting.
4. **Parse.** Market pages are read from their JSON-LD `Dataset` block plus the server-rendered stat cards; top-deals pages are read from the `__NEXT_DATA__` payload. No browser, no JavaScript execution.
5. **Write.** One row per market, or up to 100 rows per market for properties, straight to the dataset.

#### ⚙️ Input parameters

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | enum | `markets` | `markets`, `properties`, or `both`. |
| `startUrls` | array | — | AirDNA market or top-deals URLs. |
| `country` | string | — | Country slug as AirDNA spells it (`us`, `gb`, `fr`). |
| `region` | string | — | Region or state slug (`california`, `london`). |
| `searchTerms` | array | — | Market names in plain text. |
| `scrapeAllMarkets` | boolean | `false` | Walk every published market. |
| `maxItems` | integer | `1000` | Hard cap on dataset rows. |
| `maxConcurrency` | integer | `10` | Pages fetched at once. |
| `proxy` | object | — | Optional; AirDNA works fine without one. |

#### 📊 Output overview

One row per market in `markets` mode; one row per Airbnb/Vrbo listing in `properties` mode. In `both` mode the two shapes land in the same dataset and are separable by `entityType`. The dataset also ships two curated table views, **Market metrics** and **Property deals**, so the Output tab is readable without configuring columns.

#### 📦 Output sample

**Market row** (`entityType: "market"`), trimmed:

```json
{
  "entityType": "market",
  "url": "https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview",
  "marketId": "airdna-110",
  "appUrl": "https://app.airdna.co/data/us/airdna-110/overview",
  "country": "us",
  "region": "california",
  "city": "los-angeles",
  "countryName": "United States",
  "regionName": "California",
  "cityName": "Los Angeles",
  "marketName": "Los Angeles, California",
  "summary": "Los Angeles, California has 30,563 active short-term rental listings that earn an average of $48.7K per year, with 68% average occupancy and a $218 average daily rate.",
  "activeListings": 30563,
  "activeListingsDisplay": "30,563",
  "activeListingsYoYPct": 49.7,
  "annualRevenue": 48700,
  "annualRevenueDisplay": "$48.7K",
  "annualRevenueYoYPct": 173.2,
  "occupancyPct": 68,
  "occupancyYoYPct": 25.2,
  "averageDailyRate": 218,
  "averageDailyRateYoYPct": -19.1,
  "revpar": 147,
  "revparYoYPct": 11.1,
  "marketScore": 57,
  "scoreRentalDemand": 52,
  "scoreSeasonality": 94,
  "scoreRevenueGrowth": 82,
  "scoreInvestability": 47,
  "scoreRegulation": 59,
  "lastUpdated": "2026-09-05",
  "coverageStart": "2025-09-01",
  "coverageEnd": "2026-08-31",
  "faq": [
    {
      "question": "How much do Airbnbs make in Los Angeles?",
      "answer": "The average Los Angeles short-term rental earns $48.7K in annual revenue. Earnings vary by property type, bedroom count, and channel."
    }
  ],
  "nearbyMarkets": [
    { "name": "San Diego", "url": "https://www.airdna.co/vacation-rental-data/app/us/california/san-diego/overview" }
  ],
  "scrapedAt": "2026-09-08T15:19:32.791Z"
}
```

**Property row** (`entityType: "property"`):

```json
{
  "entityType": "property",
  "sourceUrl": "https://www.airdna.co/top/us/california/los-angeles",
  "airbnbId": "33251629",
  "vrboId": "4705618",
  "airbnbUrl": "https://www.airbnb.com/rooms/33251629",
  "vrboUrl": "https://www.vrbo.com/4705618",
  "vrboAffiliateUrl": "https://prf.hn/click/camref:1100ljbkY/destination:https%3A%2F%2Fwww.vrbo.com%2F4705618",
  "title": "Sheek and Shabby In L.A.",
  "propertyType": "Guesthouse",
  "bedrooms": 2,
  "bathrooms": 1,
  "guests": 6,
  "latitude": 34.0111,
  "longitude": -118.31527,
  "ratePerNight": 176,
  "marketAverageRate": 214,
  "rateDifferencePct": 18,
  "dealScore": 100,
  "imageUrl": "https://a0.muscache.com/im/pictures/airflow/Hosting-33251629/original/c1df5b16.jpg",
  "marketUrl": "https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview",
  "marketLocation": "Los Angeles, California",
  "country": "us",
  "region": "california",
  "city": "los-angeles",
  "scrapedAt": "2026-09-08T15:19:32.791Z"
}
```

#### 🗂 Key output fields

**Market rows**

| Field | Meaning |
|---|---|
| `activeListings` | Listings available or booked in the trailing 12 months, de-duplicated across Airbnb, Vrbo and Booking.com. |
| `annualRevenue` | Trailing-twelve-month earnings of a typical active listing, before host expenses. |
| `occupancyPct` | Share of available nights booked, averaged across active listings. Whole number, so `68` means 68%. |
| `averageDailyRate` | Average nightly price actually paid across booked nights. |
| `revpar` | Occupancy × ADR. AirDNA's truest measure of earning power per available night. |
| `*YoYPct` | Year-over-year change for the metric, as a signed percentage (`-19.1` = down 19.1%). |
| `marketScore` | AirDNA Market Score, 40–100, benchmarked against other markets in the same country. |
| `scoreRentalDemand`, `scoreSeasonality`, `scoreRevenueGrowth`, `scoreInvestability`, `scoreRegulation` | The five subscores behind the Market Score, each 0–100. |
| `*Display` | The abbreviated string AirDNA rendered (`"$48.7K"`, `"30,563"`), alongside the numeric field. |
| `coverageStart` / `coverageEnd` | The data window the figures describe, distinct from `lastUpdated` (when the page was refreshed). |
| `marketId` / `appUrl` | AirDNA's internal market identifier and the deep link into its app. |
| `faq` | The market's published Q\&A pairs, typically nine. |
| `nearbyMarkets` | Sibling markets in the same region, with URLs — handy for expanding a crawl. |

**Property rows**

| Field | Meaning |
|---|---|
| `airbnbId` / `vrboId` | Platform listing identifiers. `vrboId` is null for Airbnb-only listings. |
| `airbnbUrl` / `vrboUrl` | Direct listing links. The Vrbo link is unwrapped from AirDNA's affiliate redirect and stripped of its date parameters; the original wrapper is kept in `vrboAffiliateUrl`. |
| `ratePerNight` | This listing's nightly rate. |
| `marketAverageRate` | The market's average rate for comparable listings. |
| `rateDifferencePct` | How far the listing sits below its market average, as a percentage. **Positive means cheaper than average** — `18` is 18% below `marketAverageRate`, and a negative value means the listing is priced above it. |
| `dealScore` | AirDNA's 0–100 ranking of the listing as a deal. |
| `latitude` / `longitude` | Listing coordinates. |
| `marketUrl` | The market page this property belongs to, for joining property rows back to market rows. |

#### ❓ FAQ

**Do I need an AirDNA account or API key?**
No. The actor reads only AirDNA's public, free-to-view market pages — the ones marked `isAccessibleForFree` in AirDNA's own structured data. Nothing behind a login or a paid plan is touched.

**Do I need a proxy?**
No. AirDNA is behind Cloudflare, but the actor's browser-grade TLS fingerprints pass it on a direct connection. The `proxy` input exists if you want IP rotation for very large runs.

**How current is the data?**
AirDNA refreshes market pages monthly. Every row carries `lastUpdated` (when AirDNA last refreshed the page) and `coverageStart`/`coverageEnd` (the months the figures actually describe), so you can tell the two apart.

**Why is `scoreInvestability` sometimes null?**
AirDNA omits subscores it lacks the underlying data for — investability depends on local home prices, which it doesn't have everywhere. London, for example, publishes four subscores rather than five. The field is null rather than zero so a missing score never gets averaged in as a real one.

**Why is `nearbyMarkets` sometimes empty?**
Markets that are their own region — London, for instance — have no sibling markets to list, and AirDNA omits the section entirely. That's the source page, not a parse failure.

**How exact is `annualRevenue`?**
AirDNA only publishes an abbreviated figure on the free page (`$48.7K`), so `annualRevenue` is that abbreviation expanded to `48700`. It is precise to the abbreviation, not to the dollar. `annualRevenueDisplay` preserves exactly what AirDNA showed.

**Can I get more than 100 properties per market?**
No. AirDNA's public top-deals page publishes 100 listings per market, and that is all the actor can see. Scrape more markets to get more properties.

**How do I limit results?**
Set `maxItems`. The cap is claimed before rows are written, so a properties run stops precisely on the number even though pages arrive in blocks of 100.

**How does billing work?**
Pay-per-event, with two row prices because the two row types differ enormously in scarcity and value. A **market row** is $0.02: only ~24,500 exist worldwide and each carries 25+ analytic fields including AirDNA's Market Score and its five subscores. A **property row** is $0.002: they are abundant, at 100 per market. Rows are charged only after they land in the dataset, so a failed page costs nothing, and skipped empty markets are never billed.

**What happens to a market that no longer exists?**
Retired slugs render a page shell with no metrics. Those are logged and skipped rather than pushed, so you are never billed for an empty row.

#### 💬 Support

- For issues or feature requests, please use the **Issues** tab on the actor's Apify Console page.
- Author's website: <https://muhamed-didovic.github.io/>
- Email: <muhamed.didovic@gmail.com>

#### 🛠 Additional services

- Custom output shape, additional fields, or one-off datasets: <muhamed.didovic@gmail.com>
- Need a similar scraper for other short-term-rental or travel sources (Airbnb, Vrbo, Booking.com, Agoda)? Drop an email.
- For API access (no Apify fee, just a usage fee for the API): <muhamed.didovic@gmail.com>

#### 🔎 Explore more scrapers

If this AirDNA Scraper was useful, see other scrapers and actors at [memo23's Apify profile](https://apify.com/memo23) — covering short-term rentals, travel, real estate, job boards, social media, and more.

***

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/airdna-scraper`).

**Purpose:** Scrapes short-term-rental market metrics and top Airbnb/Vrbo property deals from airdna.co's public pages, covering ~24,500 markets worldwide.

**Minimal input:**

```json
{
  "mode": "markets",
  "startUrls": ["https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview"],
  "maxItems": 50
}
```

**Bulk input by geography:**

```json
{
  "mode": "both",
  "country": "us",
  "region": "florida",
  "maxItems": 500
}
```

**Output — market rows:** entityType, url, marketId, appUrl, country, region, city, countryName, regionName, cityName, marketName, summary, activeListings(+Display,+YoYPct), annualRevenue(+Display,+YoYPct), occupancyPct(+Display,+YoYPct), averageDailyRate(+Display,+YoYPct), revpar(+Display,+YoYPct), marketScore, scoreRentalDemand, scoreSeasonality, scoreRevenueGrowth, scoreInvestability, scoreRegulation, lastUpdated, coverageStart, coverageEnd, faq\[{question,answer}], nearbyMarkets\[{name,url}], scrapedAt.

**Output — property rows:** entityType, sourceUrl, airbnbId, vrboId, airbnbUrl, vrboUrl, vrboAffiliateUrl, title, propertyType, bedrooms, bathrooms, guests, latitude, longitude, ratePerNight, marketAverageRate, rateDifferencePct, dealScore, imageUrl, marketUrl, marketLocation, country, region, city, scrapedAt.

**Behaviors an agent should know:**

- `mode` selects the entity: `markets` (one row per market), `properties` (up to 100 rows per market), `both` (both shapes in one dataset, split on `entityType`).
- Market selection sources combine: `startUrls`, `country`/`region`, `searchTerms`, `scrapeAllMarkets`. With none set, the run defaults to 10 markets.
- Either URL family is accepted for either mode; links are rewritten automatically, so no need to construct the `/top/` form yourself.
- `country` and `region` take AirDNA's own URL slugs, not display names — `us` and `california`, not `United States` and `California`. Unmatched values are logged and produce no rows.
- `searchTerms` resolve against city slugs, exact matches first, capped at 25 markets per term.
- Always set `maxItems`; `scrapeAllMarkets` addresses ~24,500 markets, which in `properties` mode is millions of rows.
- `occupancyPct` is a whole number (68 = 68%). `rateDifferencePct` is positive when a listing is *cheaper* than its market average.
- Nullable by design: `scoreInvestability` where AirDNA lacks home-price data, `nearbyMarkets` for markets with no siblings, `vrboId`/`vrboUrl` for Airbnb-only listings.
- Money fields come in pairs — numeric (`annualRevenue: 48700`) and the source's abbreviation (`annualRevenueDisplay: "$48.7K"`).
- Only public pages are read; no login, no paid AirDNA API. No proxy is required.
- Pay-per-event billing with two row prices: `market-row` at $0.02 and `property-row` at $0.002, plus the standard actor-start event. Rows are charged only after a successful dataset write. In `markets` mode, cost is `maxItems x $0.02`; in `properties` mode, `maxItems x $0.002`.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by AirDNA, Airbnb, Vrbo, Expedia Group, Booking.com, or any of their subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available market and top-deals pages on airdna.co — no authenticated endpoints, no paid AirDNA API, and no content behind an AirDNA subscription. Market figures are AirDNA's own published estimates, reproduced as shown; they are not independently verified and should not be treated as investment advice. Users are responsible for ensuring their use complies with airdna.co's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.

***

### SEO Keywords

airdna scraper, scrape airdna, airdna api, airdna.co scraper, Apify airdna, airdna alternative, short term rental data scraper, str market data api, airbnb market data scraper, vacation rental analytics scraper, airbnb occupancy data, airbnb revenue data scraper, str revenue estimator data, revpar by market data, adr average daily rate scraper, airbnb market research tool, vacation rental market analysis, short term rental investment data, airbnb investment research scraper, str market score data, airbnb comps scraper, vrbo listing data scraper, airbnb pricing benchmark data, rental arbitrage market data, airdna market explorer scraper

# Actor input Schema

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

markets = one row per market (active listings, revenue, occupancy, ADR, RevPAR, Market Score). properties = one row per Airbnb/Vrbo listing on that market's deals page (up to 100 per market). both = both kinds in one dataset, separable by the entityType field.

## `startUrls` (type: `array`):

Paste any airdna.co market URL (https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview) or deals URL (https://www.airdna.co/top/us/california/los-angeles). Either form works for either mode — the actor rewrites the link to whichever page it needs.

## `country` (type: `string`):

Two-letter country slug exactly as it appears in AirDNA URLs: us, gb, fr, es, it, de, id, mx, ca, au. Scrapes every market AirDNA publishes for that country.

## `region` (type: `string`):

Region or state slug as it appears in AirDNA URLs, e.g. california, florida, texas, london, ile-de-france. Combine with the country slug to avoid matching a same-named region elsewhere.

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

Market names in plain text, e.g. Los Angeles, Big Bear Lake, Paris. Each is resolved against AirDNA's published market slugs, with exact matches ranked ahead of partial ones and at most 25 markets returned per term.

## `scrapeAllMarkets` (type: `boolean`):

Walk all ~24,500 markets AirDNA publishes, ignoring the country, region and name filters above. maxItems is the only brake on a run this size, so set it deliberately before switching this on.

## `maxItems` (type: `integer`):

Hard cap on dataset rows. Free-plan users are additionally capped at 100 rows per run.

## `maxConcurrency` (type: `integer`):

How many AirDNA pages to fetch at once. 10 is a good balance; raise it for large runs if your memory allocation allows.

## `minConcurrency` (type: `integer`):

Lower bound on parallel requests. Only applies to the Crawlee branch.

## `maxRequestRetries` (type: `integer`):

How many times to retry a page that fails to load. Only applies to the Crawlee branch — the default pipeline runs its own six-attempt ladder across three HTTP stacks.

## `proxy` (type: `object`):

Apify proxy settings. Leave unset to connect directly.

## Actor input object example

```json
{
  "mode": "markets",
  "startUrls": [
    "https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview"
  ],
  "country": "us",
  "region": "california",
  "searchTerms": [
    "Los Angeles",
    "Miami"
  ],
  "scrapeAllMarkets": false,
  "maxItems": 1000,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 5
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "startUrls": [
        "https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/airdna-scraper").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 = { "startUrls": ["https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview"] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/airdna-scraper").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 '{
  "startUrls": [
    "https://www.airdna.co/vacation-rental-data/app/us/california/los-angeles/overview"
  ]
}' |
apify call memo23/airdna-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/airdna-scraper"
        }
    }
}

```

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/dtKPigz2Udeq4dtSf/builds/7LjnDktPckTZF2Gp8/openapi.json
