# Airbnb Search Snapshots: Listings and Display Prices (`varnmill/airbnb-search-snapshots`) Actor

Export one public Airbnb search page with listing IDs, rounded display prices, ratings and explicit stay/coverage evidence. No host profiles or full inventory.

- **URL**: https://apify.com/varnmill/airbnb-search-snapshots.md
- **Developed by:** [Jay Novello](https://apify.com/varnmill) (community)
- **Categories:** Travel, Real estate
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.99 / 1,000 public search listing cards

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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 public search snapshots

On November 6, 2026, a cloud run returned 18 public London search cards for December 6–7, two adults, in 3.592 seconds. One actual row:

```json
{
  "id": "1785620906517933133",
  "name": "Central Room Near King\u2019s Cross & Euston",
  "title": "Room in Camden",
  "url": "https://www.airbnb.com/rooms/1785620906517933133",
  "displayPrice": "$92",
  "priceQualifier": "for 1 night",
  "checkIn": "2026-12-06",
  "checkOut": "2026-12-07",
  "rating": 5,
  "reviewCount": 7,
  "searchComplete": false,
  "scrapedAt": "2026-11-06T08:31:44.752709+00:00"
}
```

Export a dated first-page observation for rental-market spreadsheet review. This is a bounded search snapshot, not a full market inventory. Paid demand is unproven. The example is one owner test, not a speed guarantee or a customer sale.

### Input and output

```json
{"location":"London, United Kingdom","adults":2,"maxListings":18}
```

Omitting both dates selects one night 30 days from UTC today. Supply both dates for a reproducible comparison. Every run resolves and saves its dates. USD and English public cards only;1–16 adults,1–28 nights, ASCII destination names. If the source rewrites the destination or stay in a way we cannot verify, the run fails explicitly. Nearby recommended listings may appear; this is not a geographic inventory.

Download JSON/CSV. Filter `type=listing` for cards and `type=search_report` for the one-page observation. The report includes source count/IDs, requested and resolved destination, stay and pagination evidence. `searchComplete=false` always: this actor retrieves one page, at most 18 cards, without following pagination. `OUTPUT.snapshotDelivered` means the requested bounded snapshot was delivered, not that all available properties were scraped.

Prices are the source's rounded display strings with their qualifiers, not exact nightly quotes or totals at checkout. `displayAmount` parses only a dollar-prefixed numeric display string; `exactCheckoutPrice` is always null. Per-card date overrides are explicit. New/unrecognized ratings and missing prices remain null, never zero. Identity and pagination drift fail the whole page before its first billable delivery. No host profiles, personal contacts, precise coordinates, reviews, amenities, property detail pages or booking actions.

### Pricing

| Event | Base and all paid tiers |
|---|---:|
| Public listing card | $0.99/1,000 |
| First-page search report, including explicit empty source results | $0.0025/report |
| Actor start | $0.00005/start at 512 MB |

One 18-card snapshot: $0.02037. One-card snapshot: $0.00354. Explicit empty-page report: $0.00255. These include start; the maximum charge is a ceiling, not the invoice. No charge for an undelivered report/card; source errors still incur the start event. A cap can deliver the report plus an affordable prefix of cards. Inspect OUTPUT and row count before using a snapshot. Repeated independent runs bill unchanged rows again; no watcher is offered. Platform compute, storage and transfers are included; no separate proxy or model fees. Set a ceiling of at least $0.00255; allow $0.02037 for all 18 cards.

### Recovery and limits

The immutable first source observation is saved before delivery. Cancellation/resurrection uses that observation and the actual dataset ledger, preventing a changed live page from silently replacing the observation. Only delivered rows count as complete. Changed input, corrupt saved state, duplicates or unexpected dataset contents fail recovery; start a separate run for a new query. Independent concurrent runs have separate storage and bill separately. Manual edits to a run's storage are unsupported.

HTTP refusals/redirects are not bypassed or retried. One bounded retry is allowed for transient transport/server errors, with a five-second deadline per attempt and a 3 MB response bound. No login, model inference, cookies supplied by the customer or paid proxy service. Public-source availability can change.

### Spreadsheet recipe

1. Save the exact input and run ID. Check `OUTPUT.snapshotDelivered` and source coverage before using rows; a successful capped run can still be partial.
2. Export JSON or CSV and keep both row types. The report carries scope, counts and pagination evidence; listing cards carry public URLs and capture times.
3. For a later independent run, keep the same destination, dates, adults and limit. Compare matching listing IDs and price qualifiers. Repeated cards are billed again; missing cards reflect bounded source coverage, not a delisting.
4. Resurrection resumes the saved observation, with another start event. It does not refresh prices. Start a new run for fresh data.

### FAQ

**Is this a full Airbnb market dataset?** No. It is a small dated snapshot of one public results page, with source URLs and explicit coverage.

**Can I compare prices across dates?** Save separate inputs and snapshots. Match listing IDs and stay/guest scope; inspect price qualifiers and overrides. Rankings and rounding can vary; no checkout equivalence is promised.

**Is it cheaper than every alternative?** No. The advantage under test is the total base price for the same bounded first page versus tri_angle/airbnb-scraper. That actor offers broader coverage and lower per-listing prices at some tiers; curious_coder is also cheaper on paid tiers. On identical Stanley, Falkland Islands / December 1–2 / two-adult / USD input, both actors returned listing ID 1618374567122337756. Our configured one-card whole-run base charge is $0.00354; the leader charged $0.00410 and supplied broader property details. This is one scoped identity/price comparison, not a universal accuracy or coverage claim.

### Changelog

0.1.2 — first-page parser, strict location/stay scope, dated report, cap/recovery ledger, explicit sparse/empty results and bounded retry. Initial private tests covered 1/10/18 cards, genuine 1-card/empty sources, report-only/final-row caps and cached resurrection; final release qualification is recorded separately.

# Actor input Schema

## `location` (type: `string`):

Plain ASCII destination, preferably city and country. The response query must match; ambiguous or rewritten destinations fail explicitly.

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

YYYY-MM-DD, today through365 days ahead. Omit both dates for30 days from UTC today.

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

YYYY-MM-DD,1–28 nights after check-in. Required together with checkIn; omit both for a one-night stay.

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

Number of adult guests,1–16. Children, pets and advanced filters are unsupported.

## `maxListings` (type: `integer`):

Return up to1–18 cards from one source page. Report is charged once even for an explicit empty page. No pagination.

## Actor input object example

```json
{
  "location": "London, United Kingdom",
  "adults": 2,
  "maxListings": 18
}
```

# Actor output Schema

## `dataset` (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 = {
    "location": "London, United Kingdom",
    "adults": 2,
    "maxListings": 18
};

// Run the Actor and wait for it to finish
const run = await client.actor("varnmill/airbnb-search-snapshots").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 = {
    "location": "London, United Kingdom",
    "adults": 2,
    "maxListings": 18,
}

# Run the Actor and wait for it to finish
run = client.actor("varnmill/airbnb-search-snapshots").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 '{
  "location": "London, United Kingdom",
  "adults": 2,
  "maxListings": 18
}' |
apify call varnmill/airbnb-search-snapshots --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,varnmill/airbnb-search-snapshots"
        }
    }
}
```

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/KjUYI3DyyMOtX03Sl/builds/Cp4fHFlN5wedlAETv/openapi.json
