# Airbnb Listings & Stay Prices — Independent Scraper (`peerless_columbine/airbnb-public-listings-round29`) Actor

Collect public Airbnb search results with detailed listings, amenities, photos and displayed stay prices. Track observed dates, currency and rounded-total flags. No exact nightly or tax guarantee.

- **URL**: https://apify.com/peerless\_columbine/airbnb-public-listings-round29.md
- **Developed by:** [tingyou333 zhuang](https://apify.com/peerless_columbine) (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 $0.90 / 1,000 listing rows

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Airbnb Listings & Stay Prices — Independent Scraper

Collect public Airbnb search results with detailed listing descriptions, amenities, photos, review aggregates and displayed stay prices. Each quote includes observed dates and currency, price precision and source timestamps so you can distinguish a rounded headline from an explicitly itemized total.

Use this Actor for rental inventory research, property comparison and dated price snapshots. It is an independent tool, not affiliated with or endorsed by Airbnb. It does not access guest accounts, private messages or reservations.

### Quickstart

Paste this input into the Actor's Input tab, then run with 256 MB memory and a 120-second timeout. Inspect both the dataset and the `SUMMARY` record in the default key-value store. The **overview** and **prices** dataset views make listings and price semantics easier to review.

```json
{
  "locationQueries": ["London"],
  "maxResults": 3,
  "checkIn": "2026-11-10",
  "checkOut": "2026-11-13",
  "adults": 2,
  "locale": "en-US",
  "currency": "USD",
  "maxPages": 2,
  "maxConcurrency": 2,
  "maxRunSeconds": 100
}
```

These are the actual inputs for the recorded cloud example. Replace the fixed dates for your own research. A location or search URL is required; the Console's London prefill is not an API default. Start with a small `maxResults`, especially when adding locations or enabling profile enrichment.

### Supported inputs

| Input | Type / default | Behavior and limits |
|---|---|---|
| `locationQueries` | string array; no runtime default | Up to 100 place queries. Airbnb may return recommendations for an unknown place; check observed location. |
| `startUrls` | object array; `[]` | Up to 100 objects such as `{"url":"https://www.airbnb.com/s/London/homes"}`. Search URLs only, not room URLs. Bare strings are supported by the local runtime, not the cloud schema. |
| `maxResults` | integer ≥1; not set | Run-wide row cap across all targets. When omitted, request, page and time limits still apply. Console prefill: 3. |
| `checkIn`, `checkOut` | `YYYY-MM-DD` strings; not set | Supply both with checkout after check-in. Selected source dates must match; unconfirmed or substituted dates are rejected. |
| `adults` | integer ≥1; not set | Requested party size. Two adults is verified by the cloud example. |
| `children`, `infants`, `pets` | integers ≥0; not set | Forwarded as party filters. Anonymous direct observations on September 30, 2026 confirmed all three at 1 with two adults on two London search pages and one complete detail. Other combinations are not established by this sample. |
| `locale`, `currency` | strings; `en-US`, `USD` | Choose from the input schema enums. Requested and observed currency remain separate. London/USD/en-US, Paris/EUR/fr-FR and Tokyo/JPY/ja-JP have recorded source checks; other combinations are unverified. |
| `priceMin`, `priceMax` | integers ≥0; not set | Native source price range, currently **trip price including fees**, not a certified nightly-price filter. Minimum must not exceed maximum. |
| `minBeds`, `minBedrooms`, `minBathrooms` | integers ≥0; not set | Native search filters. If a source clamps a value, the Actor reports an unconfirmed filter instead of a false empty result. |
| `enrichUserProfiles` | boolean; `false` | Requests public primary-host and cohost facts when identity is confirmable. Explicit source ID joins are used first; an image-path candidate must match the returned profile ID and original image path. Adds requests; unavailable/unconfirmed profiles create diagnostics and retain the detailed row. Generic cohost avatars can leave identity unresolved. |
| `calendarMonths` | integer 0–12; `0` | Optional actual daily calendar from the check-in month or run month. One additional request per detailed listing; availability and price coverage are separate. |
| `includeBookingQuote` | boolean; `false` | Optional separate public BookIt quote for paired dates and the requested party. One additional request per detailed listing; existing search price values remain unchanged. |
| `maxPages` | integer 1–100; `15` | Page cap per target. Actual available pages depend on Airbnb. |
| `maxRequests` | integer 1–10000; `100` | Shared HTTP attempt budget, including details, enrichment and retries. |
| `maxRunSeconds` | integer 1–110; `100` | Collection deadline; reaching it can produce partial results. |
| `maxConcurrency` | integer 1–20; `2` | Concurrent detail requests. Higher values may require more memory. |
| `requestTimeoutSeconds` | integer 1–30; `15` | Timeout per HTTP request. |
| `maxRetries` | integer 0–2; `1` | Bounded retries for transient failures; an HTTP 403 is terminal. |
| `requestDelaySeconds` | number 0.05–10; `0.2` | Minimum spacing between HTTP request starts. |
| `dnsResolver` | `system` or `google-doh`; `system` | Explicit DoH option for local fake-IP networks; public-IP checks and TLS verification remain enforced. |
| `useProxy`, `proxyConfiguration` | `false`, `{"useApifyProxy":false}` | Optional existing Apify Proxy entitlement or user-owned `proxyUrls` (maximum 20). Explicit proxy settings can enable the proxy; configuration failures are reported. No proxy is needed for the recorded cloud example. Paid live proxy behavior is unverified. |

Explicit top-level fields override the same URL parameters; defaults only fill missing URL values. Unknown input fields and unsupported URL parameters are rejected. There is no general `sortBy` input. Search order is preserved; requested URL sort/filter values must match selected source state on each page. A September 30, 2026 anonymous direct observation ignored `sort=price_asc`; the Actor rejects that response as `SOURCE_FILTER_NOT_CONFIRMED`.

### Output fields

The default dataset contains one detailed record per delivered listing/stay/party combination. It never contains error rows. Fields absent from the source remain `null`; empty source arrays remain `[]`.

| Fields | Output / meaning |
|---|---|
| `id`, `url`, `title` | String listing ID, public room URL and source title. |
| `description`, `descriptionOriginalLanguage`, `subDescription` | Detailed source text, language and overview facts. |
| `coordinates` | Public latitude/longitude object. `_source.isExactLocationReported` is a source claim, not independently verified address accuracy. |
| `roomType`, `personCapacity`, `homeTier`, `isSuperHost` | Listing classification, capacity and source status flags. Optional values can be unknown. |
| `rating` | Numeric review aggregates where exposed. `guestSatisfaction` is the overall score; `value` is value-for-money. |
| `amenities`, `houseRules`, `highlights`, `locationDescriptions` | Grouped public detail content. Amenity availability is boolean or unknown, not an empty-string flag. |
| `host`, `coHosts` | Public host information only. Enrichment adds `publicProfile` and hashed `publicProfileSource` to each confirmable host/cohost. Legacy `coHosts[].id` remains unchanged; sourced profile IDs are in `publicProfile.id`, with the contextual ID kept separate. Complete cohost identity/enrichment is not guaranteed. |
| `images`, `thumbnail`, `androidLink`, `iosLink` | Source image and listing links; images are not downloaded. |
| `locale`, `language` | Observed source locale and language; the requested locale is recorded separately in `_source.requestedLocale`. |
| `price` | Original formatted amount, label, qualifier and available base-price breakdown. Promotional labels are preserved. |
| `_pricing` | Stay/nightly basis, observed/requested dates and currency, total precision, explicit price lines, tax knowledge and a labelled derived average. |
| `_source` | Search/detail URLs, observation times, response hashes, page/rank, selected query and missing-field notices. Search provenance also retains verified filter state and price-filter basis. Detail currency and language conflicts cause the row to be skipped and diagnosed. |
| `calendar` | Present when `calendarMonths>0`; full source days/metadata, separate availability/price coverage and hashed request provenance. Null with a diagnostic on failure. |
| `bookingQuote` | Present when `includeBookingQuote=true`; source BookIt details, explicit Total when present and hashed provenance. Unavailable stays retain source messages and nullable prices. |

Enriched profile values come from the separate public profile response; its URL, hash, capture time and identity evidence are recorded in `publicProfileSource`. An unavailable or unconfirmed profile leaves `publicProfile` absent and produces a summary diagnostic. Image-based candidates support both `/im/pictures/user/User-ID/original/...` and the observed older `/im/users/ID/profile_pic/.../original.jpg` format; either requires the returned profile ID and original image path to match before enrichment. `host.contextualId` is nullable, distinct from its legacy `id`. `_source.profileIdentityMappings` contains only unambiguous explicit source joins, and is empty when none exist. `_source.detailCurrencyObserved` and `detailLocaleObserved` can be null; they describe the detail response and do not replace the search quote's date/currency evidence. `detailQuoteAvailable` reports whether the listing's `bookIt.structuredDisplayPrice` is present, without fabricating a quote.

The selected real output fields below illustrate the nested price object. Export your own run as JSON to retain nested detail fields; the Output fields table explains their meanings.

#### Read prices correctly

- `price.amount` is a formatted display string. Inspect `_pricing.basis` before treating it as a nightly amount.
- `_pricing.stayTotal` uses an explicit itemized total when available. `totalBasis=itemized_total` and `totalPrecision=itemized_exact` identify that case. A headline-only total is `display_headline` / `display_rounded`.
- `_pricing.nightlyBaseBeforeDiscounts` is an explicitly displayed base rate. It is not the final nightly price. `_pricing.averagePerNightDerived` is total divided by nights, not an observed nightly quote.
- Tax and fee information stays unknown unless the source supplies it. A search filter labelled “includes all fees” does not establish a listing's tax/fee breakdown.
- Original, discounted and “price after discount” lines retain their source labels. A promotional line is not relabelled as an exact, all-inclusive final total.
- Individual calendar-night prices are not filled from a stay average. The optional calendar preserves `price.localPriceFormatted` exactly, including null; all 60 daily price fields in the two anonymous calendar observations below were null.

#### Actual cloud example

On 2026-09-26 UTC, the quickstart returned three London listings with **USD 846, 593 and 774** displayed totals for November 10–13, two adults. All were `display_rounded`; nightly final prices and taxes were unknown. Four HTTP responses were 200, with no diagnostics. This is a dated three-row sample, not current pricing or complete London inventory.

Excerpt of the first real row (selected fields only):

```json
{
  "id": "1770523688441051954",
  "url": "https://www.airbnb.com/rooms/1770523688441051954",
  "price": {
    "label": "$846 for 3 nights",
    "amount": "$846",
    "qualifier": "for 3 nights"
  },
  "_pricing": {
    "requestedCurrency": "USD",
    "observedCurrency": "USD",
    "observedCheckIn": "2026-11-10",
    "observedCheckOut": "2026-11-13",
    "basis": "stay",
    "nights": 3,
    "stayTotal": 846,
    "totalBasis": "display_headline",
    "totalPrecision": "display_rounded",
    "nightly": null,
    "nightlyBaseBeforeDiscounts": 281.75,
    "averagePerNightDerived": 282,
    "taxAmount": null,
    "taxStatus": "unknown",
    "feesIncluded": null
  }
}
```

These selected values are copied from the dated cloud dataset. See [Latest acceptance sample](#latest-acceptance-sample) for its capture time and result count. Repeating the query can return different listings and prices.

### Coverage and limitations

Pagination follows source cursors and suppresses duplicates while preserving source order. Collection stops at source exhaustion, an empty page, a repeated page/cursor, no new listings or a configured limit. Distinct stay dates, party sizes, locales and currencies are kept as distinct quotes.

`SUMMARY.status` distinguishes `succeeded`, `limited`, `partial` and `failed`. `complete` only becomes true when all targets reach an explicit source end/empty result without diagnostics. The three-row example is correctly **`limited`**, with `stopReason=max_results` and `complete=false`. A successful platform run does not mean full search coverage. Inspect `targets`, `stopReason` and `diagnostics` before using the output downstream.

Recorded local checks followed two pages each in London, Paris and Tokyo. Paris skipped one listing lacking required details and is explicitly partial. Unavailable details are skipped and diagnosed; short search cards are not substituted for detailed records. Unknown places can receive source recommendations. September 30 anonymous checks confirmed positive children/infants/pets filters through a real cursor transition. More regions/currencies and arbitrary sorting remain unverified.

This is not a reservation guarantee, occupancy or revenue estimator, exact-address service, or full replacement for every competitor feature. Nightly-price-filter equivalence, actual individual-night amounts, source-selected listing sort and complete cohost enrichment remain unresolved contract gaps. The dated HTML can contain null quote/calendar placeholders; the optional public frontend requests described below fetch actual calendar days and stay quote details separately.

#### Optional daily availability and public stay quote

Set `calendarMonths` to 1–12 to add `calendar` to each complete listing. The default is 0: existing input behavior, row values and request count are unchanged. The calendar starts in the requested check-in month, or the run month without dates, and uses one anonymous public `PdpAvailabilityCalendar` request per listing. Its days and metadata preserve the source fields, including `calendarDate`, `available`, `availableForCheckin`, `availableForCheckout`, `bookable`, `minNights`, `maxNights` and `price.localPriceFormatted`. Unavailable dates can be host blocks or booked dates; the response does not distinguish them. The calendar is not party-specific.

`calendar.availabilityComplete` describes availability coverage only. `nightlyPriceComplete` is separate, and `coverage` reports expected/observed days, months and days with a nonempty source price. A complete month with 30 null prices has complete availability and incomplete price coverage. `source.requestedCurrency` records the request; `source.priceCurrencyObserved` stays null unless the API itself declares a currency. A request for USD never supplies an observed currency.

Set `includeBookingQuote=true` with paired dates to add one anonymous `StaysPdpBookItQuery` request and a separate `bookingQuote`. It preserves the actual `bookIt` price details, selected guest option, stay availability and nullable heatmap. `explicitStayTotal` is populated only from a source Total line; it does not replace the existing `price` or `_pricing` values. Taxes, included fees and API-observed currency remain unknown/null unless stated by that source. A source `3 nights x $218.51` label is a stay-window rate, not three dated final nightly amounts. A one-night window rejected for minimum stay has a null quote price and the actual unavailability message; no price is invented.

Both optional requests use the public frontend key shipped in the same listing HTML, fixed public read-only persisted queries, existing TLS/public-IP validation and zero API retries. No login, user cookies or private host-calendar endpoint is used. Request/time/fee limits still apply; calendars and quotes are nested in the same listing row and do not create additional billable rows. If an optional API fails, the detailed listing is retained with `calendar`/`bookingQuote` null and a `SUMMARY` diagnostic. Partial actual calendar data is retained with `availabilityComplete=false`. Query rotation or an unexpected response fails closed.

These API responses may not echo the listing ID, ISO stay dates or currency. `source.identityEvidence` explicitly records request-ID binding when the response lacks an ID; the identity is bound by the validated listing URL and outgoing variables, not an independently echoed response ID. Each optional result retains its URL, hash, observation time, request variables and the key-bearing detail source hash. Inspect those fields when joining observations.

In a dated anonymous direct observation on September 30, 2026 UTC, listing `1228272866919264441` returned all 30 November calendar days. November 12 was available but not eligible for check-in; November 13 was unavailable but eligible for check-out. The public three-night quote for November 10–13, two adults, had an explicit Total of `$655.54` and a rounded display of `$656`; the API did not declare a currency and the heatmap was null. November 11–12 returned `Minimum stay is 2 nights`. Listing `902912917354258483` returned another 30 actual November days, also with null daily prices. These are source observations, not a reservation or deployment acceptance claim.

For example, add `"calendarMonths": 1` and `"includeBookingQuote": true` to the dated search quickstart. Direct room URLs remain unsupported as input; listing IDs are discovered through the existing search traversal.

The cloud example succeeded with **256 MB and a 120-second run limit**, using no proxy. That proves this small workload only; larger workloads or higher concurrency may need more memory. Collection is capped at 110 seconds per run. No browser fallback, login or challenge bypass is included. Private destinations, unsafe redirects and credential-bearing target URLs are rejected.

### Pricing

The paid unit is **one valid listing row saved in the default dataset**. Each separately saved record is another row. Inline arrays do not create extra row events. Failed requests, duplicate rows and diagnostic records do not create result events. A valid source record may have nullable optional fields; a row charge does not guarantee every field.

| Apify plan | USD per row | USD per 1,000 rows |
|---|---:|---:|
| FREE | 0.003 | 3.00 |
| BRONZE | 0.0018 | 1.80 |
| SILVER | 0.00135 | 1.35 |
| GOLD | 0.0009 | 0.90 |
| PLATINUM | 0.0009 | 0.90 |
| DIAMOND | 0.0009 | 0.90 |

There is no startup event fee. FREE names the Apify subscription tier; it does not mean results are free. The Pricing tab shows the active rate before a run.

**Apify platform compute, storage and transfer are charged separately**, including for failed or empty runs. An explicitly enabled proxy can add provider fees. A row limit is not an all-inclusive dollar cap. Use small inputs first and inspect actual run usage. Historical owner test runs are not customer revenue or cost forecasts.

### API example

Install `apify-client`, save the quickstart JSON as `input.json`, and supply your Apify token through the `APIFY_TOKEN` environment variable. This example starts a run and can incur the live Actor/platform charges.

```python
import json
import os
from decimal import Decimal
from pathlib import Path
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("SVh5NigvngTp7kOE7").call(
    run_input=json.loads(Path("input.json").read_text()),
    memory_mbytes=256,
    timeout_secs=120,
    max_total_charge_usd=Decimal("0.05"),
)
if not run or run["status"] != "SUCCEEDED":
    raise RuntimeError("Inspect the run status and SUMMARY before using results")
record = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("SUMMARY")
summary = record["value"] if record else {}
print(summary.get("status"), summary.get("complete"))
if summary.get("status") in {"partial", "failed"}:
    raise RuntimeError("Inspect SUMMARY diagnostics before accepting this sample")
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["id"], row["_pricing"])
```

### FAQ

**Can I provide a room URL?** No. Start with locations or search URLs. The Actor then fetches details for the returned listings.

**Why is the total different from an itemized price line?** A headline can round up, while a base or discount line has cents. Only an explicit total can be classified as `itemized_exact`; do not promote a base/discount line into a final total.

**Why did I receive fewer rows than requested?** The source may be empty, details may be unavailable, or a limit/failure may have stopped collection. Read `SUMMARY`; zero rows are not automatically a successful empty search.

**Is this a drop-in replacement for another Airbnb scraper?** No full parity is claimed. Compare field types, trip-price filter semantics, price precision and host-enrichment scope before migrating. Review [Output fields](#output-fields), [Read prices correctly](#read-prices-correctly), and [Coverage and limitations](#coverage-and-limitations) for the supported field meanings and migration limits.

**Does the Actor use my browser session or guest data?** No. It accesses anonymous public pages only. Host information is limited to public source content.

The icon is Airbnb's original 180×180 public website asset, shown without cropping, recoloring or upscaling. Use of the mark identifies the data source and does not imply affiliation or endorsement.

### Latest acceptance sample

The quickstart input was checked in Apify Cloud on 2026-09-26 (UTC; run finished at 2026-09-26T18:40:04.708Z). It saved 3 valid rows. The output example on this page copies real source values from that dataset; it is a dated sample, not current inventory or a current quote.

Three London listings returned displayed USD stay totals of 846, 593 and 774 for November 10–13, 2026 and two adults. All totals were display-rounded; final nightly prices and taxes were unknown. SUMMARY was `limited`, with `complete=false` and `stopReason=max_results`.

# Actor input Schema

## `locationQueries` (type: `array`):

List of location queries to scrape. Example: London, Manchester, Birmingham, etc.

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

Maximum results to return from this run

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

Airbnb search URLs only; direct property URLs are not supported. Use objects such as {"url": "https://www.airbnb.com/s/London/homes"}. Explicit top-level filters override matching URL parameters.

## `enrichUserProfiles` (type: `boolean`):

If enabled, the actor makes extra requests for each host/co-host in every listing to get more detailed user info. This increases cost and runtime. If a profile is private or there's an unexpected error, it will be skipped and won't appear in the output.

## `checkIn` (type: `string`):

Date must be in <code>YYYY-MM-DD</code> format with zero-padded month and day, e.g., <code>2022-02-20</code>.

## `checkOut` (type: `string`):

Date must be in <code>YYYY-MM-DD</code> format with zero-padded month and day, e.g., <code>2022-02-20</code>.

## `locale` (type: `string`):

Localized results in this locale will be extracted (language and region).

## `priceMin` (type: `integer`):

Minimum Airbnb search price in the selected currency. The verified source uses trip price including fees; nightly-filter parity remains unverified.

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

Currency that will be extracted for prices.

## `priceMax` (type: `integer`):

Maximum Airbnb search price in the selected currency. The verified source uses trip price including fees; nightly-filter parity remains unverified.

## `minBeds` (type: `integer`):

Minimum number of beds requested through Airbnb's public search filter.

## `minBedrooms` (type: `integer`):

Minimum number of bedrooms. If Airbnb clamps this value, collection reports an unconfirmed filter instead of a successful empty result.

## `minBathrooms` (type: `integer`):

Minimum number of bathrooms requested through Airbnb's public search filter.

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

Number of adults in the search party; forwarded to dated search and listing-detail requests.

## `children` (type: `integer`):

Number of children in the search party. Positive values have not yet completed source acceptance.

## `infants` (type: `integer`):

Number of infants in the search party. Positive values have not yet completed source acceptance.

## `pets` (type: `integer`):

Number of pets in the search party. Positive values have not yet completed source acceptance.

## `maxPages` (type: `integer`):

A safety bound. Hitting the limit is recorded as incomplete; no completeness guarantee.

## `maxRequests` (type: `integer`):

A safety bound. Hitting the limit is recorded as incomplete; no completeness guarantee.

## `maxRunSeconds` (type: `integer`):

A safety bound. Hitting the limit is recorded as incomplete; no completeness guarantee.

## `requestTimeoutSeconds` (type: `integer`):

A safety bound. Hitting the limit is recorded as incomplete; no completeness guarantee.

## `maxRetries` (type: `integer`):

A safety bound. Hitting the limit is recorded as incomplete; no completeness guarantee.

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

A safety bound. Hitting the limit is recorded as incomplete; no completeness guarantee.

## `requestDelaySeconds` (type: `number`):

Minimum delay between HTTP request starts, in seconds; applied together with the concurrency and request limits.

## `dnsResolver` (type: `string`):

Explicit local Google DoH mode for fake-IP networks; TLS and public IP checks remain enabled.

## `useProxy` (type: `boolean`):

Opt in. No paid proxy is enabled by default.

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

Optional existing Apify entitlement or user-owned proxyUrls. Configuration failures are fatal. Paid proxy route is mock tested only.

## `calendarMonths` (type: `integer`):

0 keeps the original output and request count. 1–12 adds anonymous day-by-day availability to each detailed listing, starting in the check-in month or the run month. Calendar prices stay null when the source hides them. This calendar is not party-specific and does not guarantee a reservation.

## `includeBookingQuote` (type: `boolean`):

Add one anonymous frontend BookIt query for the requested dates/party. Keeps the existing search price unchanged and returns actual source price details, availability and selected guest options separately. Source amounts, unknown currency/taxes/fees and unavailable-stay messages are preserved; this is not per-date nightly pricing.

## Actor input object example

```json
{
  "locationQueries": [
    "London"
  ],
  "maxResults": 3,
  "startUrls": [],
  "enrichUserProfiles": false,
  "locale": "en-US",
  "currency": "USD",
  "maxPages": 15,
  "maxRequests": 100,
  "maxRunSeconds": 100,
  "requestTimeoutSeconds": 15,
  "maxRetries": 1,
  "maxConcurrency": 2,
  "requestDelaySeconds": 0.2,
  "dnsResolver": "system",
  "useProxy": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "calendarMonths": 0,
  "includeBookingQuote": false
}
```

# Actor output Schema

## `listings` (type: `string`):

No description

## `summary` (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 = {
    "locationQueries": [
        "London"
    ],
    "maxResults": 3,
    "locale": "en-US",
    "currency": "USD"
};

// Run the Actor and wait for it to finish
const run = await client.actor("peerless_columbine/airbnb-public-listings-round29").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 = {
    "locationQueries": ["London"],
    "maxResults": 3,
    "locale": "en-US",
    "currency": "USD",
}

# Run the Actor and wait for it to finish
run = client.actor("peerless_columbine/airbnb-public-listings-round29").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 '{
  "locationQueries": [
    "London"
  ],
  "maxResults": 3,
  "locale": "en-US",
  "currency": "USD"
}' |
apify call peerless_columbine/airbnb-public-listings-round29 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,peerless_columbine/airbnb-public-listings-round29"
        }
    }
}
```

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/SVh5NigvngTp7kOE7/builds/jGMU6ChMx3KO4bGiC/openapi.json
