# Airbnb Availability Calendar & Occupancy Scraper (`woonmapao/airbnb-calendar-scraper`) Actor

Airbnb availability calendar for any listing: 12 months of day-by-day availability, min/max nights, check-in rules, optional nightly prices, monthly occupancy, and booking-change monitoring. HTTP-only, no browser.

- **URL**: https://apify.com/woonmapao/airbnb-calendar-scraper.md
- **Developed by:** [Patarapong Limvipaveeanan](https://apify.com/woonmapao) (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 $1.00 / 1,000 calendar days

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Airbnb Availability Calendar & Occupancy Scraper do?

**Airbnb Availability Calendar Scraper** takes **Airbnb listing URLs** and returns each listing's **day-by-day availability calendar for up to 12 months**: whether each date is open, whether guests can check in or out that day, **minimum and maximum nights**, and optionally the **nightly price** for upcoming bookable days. It also writes a **monthly occupancy summary** and can run in **monitoring mode**, outputting only the days that were **booked or reopened** since the last run.

It reads the calendar Airbnb already serves to its own website, over plain HTTP with no headless browser. **One request returns a full year for a listing**, so it's fast and cheap: a full year for one listing costs about **$0.37**. On Apify you also get API access, scheduling, integrations (Google Sheets, Slack, webhooks) and monitoring.

### Why scrape Airbnb availability calendars?

- **Occupancy and booking pace**: see how many nights competitors have filled this month and next.
- **Revenue management for hosts and property managers**: compare your open dates, minimum stays and nightly rates against the listings you compete with.
- **Investment analysis**: estimate occupancy and nightly rates for an area before you buy.
- **Booking alerts**: schedule a daily run with **Only output changed days** and get just the newly booked or newly opened dates.
- **Market research and data products**: build occupancy datasets without browser automation.

### How to scrape an Airbnb calendar

1. Collect the listing URLs you care about (`https://www.airbnb.com/rooms/<id>`, any Airbnb domain works).
2. Paste them into **Room URLs** and choose how many **Months ahead** you need.
3. Tick **Include nightly prices** if you want nightly rates (the next 30 bookable days by default).
4. Click **Start**. Download the calendar as JSON, CSV, Excel or HTML, or fetch it through the Apify API.
5. For monitoring, save the run as a task, tick **Only output changed days** and schedule it daily.

### Input

| Field | Description |
|---|---|
| `startUrls` | Airbnb room URLs like `https://www.airbnb.com/rooms/12345`. Other URLs are skipped. |
| `months` | Months of calendar to return, starting today (1-12, default 12). |
| `includePrices` | Also return the nightly rate for days guests can check in (default off). Slower: one extra request per priced day. |
| `maxPricedDays` | With prices on: price at most this many bookable check-in days per listing, from today (default 30). Airbnb slows down bursts of price requests, so large values make runs much longer. |
| `onlyChanges` | Monitoring mode: output only days that became booked or reopened since this Actor's previous run on your account. The first run outputs nothing and saves the baseline. |
| `adults`, `currency` | Guests and currency for prices (default 2, `USD`). |
| `proxyConfiguration` | Optional. Usually not needed. Turn on Apify Proxy only if you see repeated HTTP 403 or 429 errors. |

```json
{
    "startUrls": [
        { "url": "https://www.airbnb.com/rooms/32422325" },
        { "url": "https://www.airbnb.co.uk/rooms/1764409719853216298" }
    ],
    "months": 6,
    "includePrices": true,
    "currency": "EUR"
}
```

### Output example

One row per listing per day:

```json
{
    "listingId": "1764409719853216298",
    "url": "https://www.airbnb.com/rooms/1764409719853216298",
    "date": "2026-10-13",
    "available": true,
    "availableForCheckin": true,
    "availableForCheckout": true,
    "minNights": 3,
    "maxNights": 365,
    "pricePerNight": 51.23,
    "currency": "USD",
    "change": null
}
```

And a monthly summary per listing in the run's key-value store, record `OCCUPANCY` (free, not charged):

```json
{
    "32422325": [
        { "month": "2026-11", "days": 30, "unavailableDays": 8, "occupancyPct": 26.7, "avgPricePerNight": 124.51 }
    ]
}
```

### Data fields

| Field | Description |
|---|---|
| `date`, `available` | Calendar date and whether it can be booked |
| `availableForCheckin`, `availableForCheckout` | Whether a stay can start or end that day (Airbnb's check-in-day and gap rules) |
| `minNights`, `maxNights` | Minimum and maximum stay starting that day |
| `pricePerNight`, `currency` | Nightly rate for the shortest allowed stay from that day, from Airbnb's price breakdown (only with **Include nightly prices**, only for check-in days) |
| `change` | `booked` or `opened` compared to the previous run, otherwise `null` |
| `occupancyPct` (OCCUPANCY record) | Share of the month's days that are unavailable |

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### How much does it cost to scrape Airbnb calendars?

You pay **$1 per 1,000 calendar days** (plus a tiny start fee per run), nightly prices included, with no subscription. That's **about $0.37 for a full year of one listing**. In monitoring mode you only pay for days that changed. The Apify free plan's monthly credits cover thousands of days, so you can test for free. Set a maximum cost per run in the run options and the scraper stops cleanly when it's reached.

### Tips

- **Occupancy is an estimate.** Airbnb's calendar shows a day as unavailable whether it's booked or blocked by the host, and this scraper can't tell the two apart. Hosts who block long periods will look fully occupied.
- Use **Months ahead** to pay only for the window you need: 3 months of calendar is a quarter of the cost of 12.
- Prices are for the shortest allowed stay starting that day, so weekly or monthly discounts aren't reflected.
- Removed, unlisted or invalid listings are skipped and not charged.

### FAQ

**Is it legal to scrape Airbnb?** This scraper collects only publicly visible calendar data and doesn't log in. It doesn't collect host names, profiles or reviews. Check Airbnb's terms and make sure your use complies with the laws that apply to you, including GDPR.

**Need listing details (title, rating, amenities) too?** Use our [Airbnb Rooms Scraper](https://apify.com/woonmapao/airbnb-rooms-scraper) with the same URLs.

**Something broke or you need another field?** Open an issue on the Issues tab. Custom solutions are available on request.

# Actor input Schema

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

Airbnb listing URLs like https://www.airbnb.com/rooms/12345. Any Airbnb domain works (airbnb.co.uk, airbnb.fr, ...).

## `months` (type: `integer`):

How many months of calendar to return, starting today (1-12).

## `includePrices` (type: `boolean`):

Also fetch the nightly rate for the first bookable check-in days (see Max priced days). One extra request per priced day, so it is slower than the calendar alone.

## `maxPricedDays` (type: `integer`):

With nightly prices on: price at most this many bookable check-in days per listing, starting from today. Airbnb slows down bursts of price requests, so large values make runs much longer.

## `onlyChanges` (type: `boolean`):

For scheduled runs: output only days that became booked or reopened since the previous run of this Actor on your account. The first run outputs nothing and just saves the baseline.

## `adults` (type: `integer`):

Number of adult guests used for prices.

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

Currency for prices, e.g. USD, EUR, GBP, THB.

## `proxyConfiguration` (type: `object`):

Usually not needed. Turn on Apify Proxy if you see repeated HTTP 403 or 429 errors.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.airbnb.com/rooms/32422325"
    }
  ],
  "months": 12,
  "includePrices": false,
  "maxPricedDays": 30,
  "onlyChanges": false,
  "adults": 2,
  "currency": "USD",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `occupancy` (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": [
        {
            "url": "https://www.airbnb.com/rooms/32422325"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("woonmapao/airbnb-calendar-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": [{ "url": "https://www.airbnb.com/rooms/32422325" }],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("woonmapao/airbnb-calendar-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": [
    {
      "url": "https://www.airbnb.com/rooms/32422325"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call woonmapao/airbnb-calendar-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,woonmapao/airbnb-calendar-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/6CqwFVHJ8HigYePM8/builds/ulNwuNOybOx3dkNW5/openapi.json
