# Airbnb Scraper API - Prices, Reviews & Calendar (`codepoetry/airbnb-scraper`) Actor

Scrape whole cities or single listings. Extract prices with the full fee breakdown, all six rating categories, host details, amenities, photos, day-by-day availability and guest reviews — 99 fields per listing. Export to JSON, CSV or Excel, run via API, or schedule it. Failed listings are free.

- **URL**: https://apify.com/codepoetry/airbnb-scraper.md
- **Developed by:** [CodePoetry](https://apify.com/codepoetry) (community)
- **Categories:** Travel, Real estate
- **Stats:** 13 total users, 7 monthly users, 81.5% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.75 / 1,000 listings

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 Scraper

Airbnb Scraper API extracts public Airbnb listing data without an Airbnb API key, which
does not exist for developers. It returns 99 fields per property — nightly and total price
as numbers, all six rating categories, host details, amenities, day-by-day availability and
guest reviews — from any city, region or room URL, as JSON, CSV or Excel.

### 99 fields per listing, with the availability calendar in the same run

Airbnb has no public API, so most Airbnb scrapers hand you the search card: a title, a
price label and a rating. This one opens every property page and returns the price broken
down line by line as a number you can sort on, all six rating categories, the host, every amenity, day by
day availability, and every guest review if you ask for them.

You pay per listing returned. Walking the search pages to find a property is free, because
finding one is not a product. Search mode returns card-level records, billed per search
result. The prices for each, and the discounts your Apify plan earns, are on the Pricing tab
of this page.

Listings that fail are free too. If a property has been pulled, or Airbnb refuses the
request, you get a record with the id, the url and what went wrong, and you are not billed
for it.

Reviews are billed per review, and off unless you ask. A busy property carries several
hundred, so folding them into the listing price would charge everyone for something plenty
of callers do not want. Turn on `include_reviews` and you get every review a listing has, up
to the cap you set.

#### Measured, not claimed

Every number on this page comes from a run, on the date given, not from a spec sheet.

| What | Measured | When |
| --- | --- | --- |
| Fields per listing | 99 | 1 Sep 2026 |
| Currencies | 28, each run against Airbnb and returning that currency | 2 Sep 2026 |
| Languages | 18, each run and returned translated | 2 Sep 2026 |
| Default run | 20 listings, all 99 fields, 22 seconds | 2 Sep 2026 |
| Listings priced | 9 of 10 in Paris, Chamonix and Aspen alike | 2 Sep 2026 |
| Billing | 8 listings and 80 reviews delivered, 8 and 80 charged | 1 Sep 2026 |

Pass the dates you care about, because Airbnb quotes a different price for every stay.

### Airbnb data export: 99 fields, in tabs you can read

A record this wide is unreadable as one table, so the dataset arrives grouped. Seven tabs
above your results, each answering one question:

| Tab | What it answers |
| --- | --- |
| **Listings** | The whole picture: photo, name, city, type, capacity, all three prices with the stay they were quoted for, rating, review count, Guest Favourite, Superhost, occupancy and the booking terms |
| **Availability** | The day-by-day calendar, minimum and maximum nights, days free, days blocked, occupancy rate and the next free date |
| **Ratings & reviews** | All six category scores behind the star, the rating distribution, and the reviews themselves |
| **Host** | Host and co-hosts, Superhost status, licence, whether the address is verified |
| **Location** | Coordinates and whether they are exact rather than Airbnb's privacy circle, address, neighbourhood, map link |
| **Amenities & rules** | The full amenity list by category, direct flags for the ones people filter on, house rules, cancellation terms, safety features |
| **Description & photos** | The listing's own copy, highlights, sleeping arrangements, badges and every image |

Switch tabs at the top of the dataset, or export any of them to JSON, CSV or Excel. **All
fields** shows the raw record if you would rather have everything at once.

### Is there an Airbnb API?

Not a public one. Airbnb's API is closed to approved partners — channel managers and
property-management software — and there is no key you can sign up for as a developer.
Searching for an Airbnb API key, or for free Airbnb API access, turns up partner
application forms rather than documentation you can use.

This is the practical substitute: give it a location and it walks Airbnb's search results,
opens each property page, and returns one record per listing with 99 fields, through a REST
API you already have credentials for. No Airbnb login, no partner application, no rate-limit
negotiation. Export to JSON, CSV, Excel or HTML, or pull it straight from the API.

You can run it two ways. Full detail opens every property page and returns everything below.
Search mode reads only the results pages and returns the card-level fields for each listing,
billed per search result rather than per listing. Sweep a whole market in search mode, then go
deep on the properties that matter.

### What Airbnb data can you extract?

Every full detail record contains:

| Group | Fields |
| --- | --- |
| Identity | id, url, name, title, subtitle, description, description language, SEO title, thumbnail, images |
| Location | latitude, longitude, coordinates, neighbourhood, location descriptions, and whether the coordinates are the exact spot rather than Airbnb's privacy circle |
| Capacity | person capacity, bedrooms, beds, bathrooms, room type, property type, home tier |
| Price | nightly rate and stay total as numbers, currency, original and discounted price, nights, and the breakdown line by line. Airbnb quotes all-in prices and no longer itemises cleaning or service fees, so neither does this |
| Ratings | guest satisfaction overall, plus accuracy, check-in, cleanliness, communication, location and value |
| Host | name, id, profile URL, photo, superhost and verified status, years hosting, response rate and time, rating average and count, highlights, about (co-hosts are a separate top-level field) |
| Amenities | the complete list, plus direct flags for wifi, air conditioning, heating, kitchen, parking, washer, dedicated workspace and pets |
| Reviews | reviewer, date, rating, review text, highlights and the host response, up to a limit you set |
| Availability | day by day calendar, minimum and maximum nights, and from today on: days total, days available, days blocked and occupancy rate |
| Rules and policies | house rules, cancellation policy, check-in and check-out times, self check-in, smoking, parties, commercial photography, licence number |
| Metadata | instant book, highlights, scraped\_at timestamp |

Search mode returns what the result card carries: id, url, name, title, subtitle, thumbnail,
images, latitude, longitude and coordinates, nightly rate, stay total and original price as
numbers, nights, the price label and breakdown, the check\_in and check\_out it was quoted for,
rating, review count, Superhost, badges and the scraped\_at timestamp. Room type, capacity and
everything else below the card are full-detail fields.

### Airbnb prices as numbers, not screenshots of numbers

A price label tells you what a listing asks. "$2,119 for 5 nights" is a string; 2119 and
423.63 are numbers you can sort, filter and average. This returns the nightly rate and the
stay total as numbers, the pre-discount price where a stay is discounted, and whether the
listing can actually be booked for those dates at all — seven of eight listings sampled in
one city could not be.

Ratings work the same way. An overall 4.9 hides whether guests marked a place down on
cleanliness or on value, and six category scores tell you which.

Then there is the calendar. Nightly rates alone tell you what a market advertises. Rates
with occupancy tell you what it books.

### Airbnb API pricing: what a run costs

You are billed per event, at the prices on the Pricing tab of this page:

| Event | When it is billed |
| --- | --- |
| Listing | Each full-detail record returned, with its calendar |
| Search result | Each card-level record returned in search mode |
| Review | Each guest review returned, when you ask for them |
| Search page | Each search results page walked — free |

Volume discounts follow your Apify plan.

Reviews are the one line that depends on the properties rather than on how many you asked
for. A busy listing carries a couple of hundred, so pulling all of them costs far more than
the listing itself; `max_reviews_per_listing` caps it. If you are budgeting a run, this is the
number to look at twice.

#### Why pay per event

You are charged for listings the scraper returns, not for the work it did to find them.
Paginating a city of 240 listings takes about 14 search pages and costs nothing.

Failures are free as well. A removed property, or one Airbnb refuses to serve, still comes
back as a record carrying the id, the url and what happened, and that record is not billed.
You pay for listings you can use.

### How to scrape Airbnb listings without an API key

1. Add the locations you want under `location_queries`, or paste listing URLs into
   `start_urls`.
2. Set `check_in` and `check_out` for the stay you care about. Airbnb quotes a different
   rate for every stay, so leaving them empty prices a single night a month out instead —
   every record reports the `check_in` and `check_out` it was priced for.
3. Choose `mode`. Use `full` for complete property data, `search` for a quick sweep of the result cards.
4. Set `max_listings` to cap the run. Turn on `include_reviews` if you want reviews, and
   `max_reviews_per_listing` to bound how many of them you pay for.
5. Start the run. Results appear in the dataset while the run is still going, so you can
   begin reading before it finishes.

### Input

#### Search one city or many

Each location becomes its own search and all of them merge into a single dataset. Covering
ten cities takes one run rather than ten.

```json
{
  "location_queries": ["Porto, Portugal", "Lisbon, Portugal", "Braga, Portugal"],
  "mode": "full",
  "max_listings": 500
}
```

#### Set dates, guests and prices

Airbnb prices depend on the stay, so pass the nights you care about. Guest counts
change both the price and which listings appear.

```json
{
  "location_queries": ["Barcelona, Spain"],
  "check_in": "2026-09-10",
  "check_out": "2026-09-15",
  "adults": 2,
  "children": 1,
  "price_min": 80,
  "price_max": 300
}
```

#### Scrape Airbnb from another country

Airbnb ranks results and shows prices and availability differently depending on where you
browse from. A Paris search seen from France is not the same result set as the one you get
from a US connection — different ordering, different totals, sometimes different listings.

`proxy_country` picks the country to browse from. 23 markets are supported:

```json
{
  "location_queries": ["Paris, France"],
  "proxy_country": "FR"
}
```

| | |
| --- | --- |
| **Europe** | United Kingdom, France, Germany, Spain, Italy, Portugal, Netherlands, Poland, Sweden, Denmark, Austria, Ireland, Greece, Turkey |
| **Americas** | United States, Canada, Brazil, Mexico |
| **Asia-Pacific** | Japan, South Korea, India, Singapore, Australia |

Leave it empty and the market follows the language you chose, so `locale: "de-DE"` browses
Germany. Set both when you want them to differ — an English-speaking buyer researching the
German market, for example.

The scraper follows Airbnb's own country sites, so a German market run reads `airbnb.de` and
returns what a visitor there actually sees. China and Russia are not offered: Airbnb
withdrew from both, and a search from either returns nothing. Russian and Chinese are still
offered as languages, and left to follow the language they browse the United States.

#### Scrape specific listings

Skip search entirely when you already know the properties. `start_urls` accepts room URLs
and bare listing ids in the same list.

```json
{
  "start_urls": [
    "https://www.airbnb.com/rooms/691479",
    "https://www.airbnb.com/rooms/1478285053144011262",
    "1733326288002241501"
  ],
  "mode": "full"
}
```

#### Filter what comes back

```json
{
  "location_queries": ["Lisbon, Portugal"],
  "room_types": ["Entire home/apt"],
  "property_types": ["Apartment", "Loft"],
  "min_bedrooms": 2,
  "min_bathrooms": 1,
  "min_rating": 4.8
}
```

#### Scrape Airbnb reviews and the availability calendar

The calendar comes with every full listing. Reviews are opt-in and billed per review, so
ask for them when you want them — both arrive nested inside the listing record, so a
property and its history stay together.

```json
{
  "location_queries": ["Madrid, Spain"],
  "include_reviews": true,
  "max_reviews_per_listing": 20,
  "calendar_months": 3
}
```

`max_reviews_per_listing` defaults to 50, which keeps one very popular property from
dominating the bill. Set it to 0 to take every review a listing has.

#### All input options

| Option | Type | What it does |
| --- | --- | --- |
| `location_queries` | array | Locations to search. Each becomes its own search, merged into one dataset. |
| `start_urls` | array | Room URLs or bare listing ids to fetch directly, skipping search. Give this or `location_queries`, not both. |
| `mode` | string | `full` opens every property page. `search` reads results pages only. |
| `check_in`, `check_out` | string | Stay dates, so prices reflect a real booking. |
| `adults`, `children`, `infants`, `pets` | integer | Guest counts. These change price and availability. |
| `price_min`, `price_max` | integer | Nightly price bounds. |
| `min_beds`, `min_bedrooms`, `min_bathrooms` | integer | Size filters. |
| `room_types` | array | Entire home/apt, private room, shared room, hotel room. |
| `property_types` | array | Keep only listings matching these property types. |
| `min_rating` | number | Drop listings rated below this. |
| `max_pages` | integer | Search pages to walk per location. Usually leave empty; `max_listings` already bounds the run. |
| `max_listings` | integer | How many listings to return. Defaults to 20; 0 takes every listing found. |
| `include_reviews` | boolean | Fetch guest reviews. Off by default; billed per review. |
| `max_reviews_per_listing` | integer | Reviews per property, at most. Defaults to 50; 0 fetches every one. |
| `calendar_months` | integer | Months of availability to pull, from today. 0 skips the calendar. |
| `calendar_start_month`, `calendar_start_year` | integer | Start the calendar somewhere other than today. Defaults to the current month and year. |
| `currency` | string | Prices converted to this. 28 options, each checked against Airbnb. |
| `locale` | string | Language for review dates, house rules and cancellation terms. 18 options. |

### Output

#### Table view

| id | name | person\_capacity | price.label | rating.guest\_satisfaction | number\_of\_reviews |
| --- | --- | --- | --- | --- | --- |
| 691479 | Loft in Porto | 5 | $1,457 for 5 nights, originally $1,633 | 4.96 | 412 |
| 1478285053144011262 | Apartment in Porto | 4 | $487 for 5 nights | 4.99 | 128 |
| 1599392401671897626 | Apartment in Porto | 6 | $828 for 5 nights | 4.97 | 76 |

#### JSON

```json
{
  "id": "691479",
  "url": "https://www.airbnb.com/rooms/691479",
  "name": "Apartreboleira. Terrace with a view",
  "room_type": "Entire home/apt",
  "property_type": "Entire loft",
  "person_capacity": 6,
  "bedrooms": 3,
  "beds": 5,
  "bathrooms": 2,
  "latitude": 41.13951,
  "longitude": -8.61515,
  "is_super_host": true,
  "price": {
    "amount": null,
    "breakdown": [],
    "currency": "USD",
    "discounted_price": null,
    "label": null,
    "original_price": null,
    "qualifier": null
  },
  "rating": {
    "accuracy": 4.97,
    "checkin": 4.98,
    "cleanliness": 4.99,
    "communication": 4.99,
    "guest_satisfaction": 4.96,
    "location": 4.99,
    "value": 4.92
  },
  "host": {
    "about": "Native from Switzerland, leaving in Porto for more then thirty years. Working as an architect (among other act...",
    "details": [
      "Superhost"
    ],
    "highlights": [
      {
        "icon": "SYSTEM_EVENTS",
        "text": "Born in the 60s"
      }
    ],
    "id": "RGVtYW5kVXNlcjozNTM0ODY0",
    "is_super_host": true,
    "is_verified": true,
    "name": "Anne"
  },
  "amenities": [
    {
      "available": true,
      "icon": "SYSTEM_VIEW_OCEAN",
      "name": "River view"
    }
  ],
  "amenity_wifi": true,
  "amenity_kitchen": true,
  "images": [
    {
      "caption": "Terrace",
      "orientation": "LANDSCAPE",
      "url": "https://a0.muscache.com/im/pictures/9221831/8034b59a_original.jpg"
    }
  ],
  "reviews": [
    {
      "collection_tag": null,
      "created_at": "2026-08-10T13:42:09Z",
      "date": "2 weeks ago",
      "highlight_type": "LENGTH_OF_STAY",
      "id": "1749297646833504458",
      "language": "en",
      "photos": [],
      "rating": 5
    }
  ],
  "availability": [
    {
      "available": false,
      "available_for_checkin": false,
      "available_for_checkout": false,
      "bookable": false,
      "date": "2026-09-01",
      "max_nights": 30,
      "min_nights": 2
    }
  ],
  "availability_days_total": 30,
  "availability_days_available": 5,
  "occupancy_rate": 0.8333333333333334,
  "min_nights": 2,
  "check_in_time": "Check-in: 3:00 PM - 11:00 PM",
  "house_rules": [
    {
      "icon": "SYSTEM_CLOCK",
      "rule": "Check-in: 3:00 PM - 11:00 PM"
    }
  ],
  "scraped_at": "2026-08-28T00:49:37.684113927Z",
  "error": null
}
```

### What people use Airbnb data for

Property managers and hosts track what comparable listings nearby charge for the same
nights, and how their occupancy compares. The availability calendar and the price breakdown
together show what a market books at, rather than what it advertises.

Real estate investors screen neighbourhoods before buying by pulling every listing in an
area with occupancy rates and nightly rates attached.

Travel and booking sites build inventory feeds, comparing Airbnb prices against their own.

Researchers and journalists study short term rental density in cities considering
regulation, using coordinates, licence numbers and host portfolios.

Anyone doing due diligence on a host can pull their full portfolio through `start_urls` and
check ratings, response rates and review history across properties.

### How the Airbnb scraper handles blocks and failures

A listing that cannot be fetched becomes a record instead of disappearing. It carries the
id and url you asked for, plus an `error` array explaining what happened:

```json
{
  "id": "999999999999999",
  "url": "https://www.airbnb.com/rooms/999999999999999",
  "error": [
    {
      "scope": "listing",
      "type": "listing.state_missing",
      "message": "the detail page carried no listing state, so every field below the search card is null"
    }
  ]
}
```

The run carries on and finishes normally. One removed property does not cost you the other
499, and error records are not charged.

Problems that affect the whole run, such as a location Airbnb does not recognise, appear in
the run summary rather than being attached to a listing.

### Frequently asked questions

**Do I need an Airbnb API key?**
No. There is no public Airbnb API to get a key for — it is restricted to approved partner
integrations. This reads the same public pages a browser does, so there is nothing to apply
for and no quota to negotiate.

**Do I need an Airbnb account?**
No. The scraper reads public listing pages and needs no login or cookies.

**Can I call it from Python or n8n?**
Yes. It is an ordinary Apify Actor, so anything that can make an HTTP request can start a
run and read the dataset — the Python and JavaScript clients, n8n, Make, Zapier, or plain
`curl`. The API tab on this page has the exact call with your token filled in.

**Why are prices different from what I see on Airbnb?**
Airbnb quotes by stay, so the same listing has no single price. Without `check_in` and
`check_out` this prices one night about a month out and tells you which night on every
record. Pass your own dates and guest counts and the numbers match what a guest is shown.

**Can I get every listing in a city?**
Airbnb caps how deep its own search goes, so no scraper can return literally every property
from one query. Splitting a city into neighbourhoods or price bands and passing them as
separate `location_queries` reaches more of the inventory.

**How many reviews can I get?**
As many as a listing has, up to `max_reviews_per_listing` — 50 by default, or 0 for every one.
Reviews add time, so cap it when you are sweeping a whole market.

**What does search mode leave out?**
Everything that only exists on the property page: room type and capacity, the availability
calendar, reviews, the full amenity list, host details and house rules. Search mode gives you
the card: id, url, title, prices, rating, review count, coordinates, thumbnail and images.

**Is the output shape stable?**
Fields are consistent across records. A field Airbnb does not publish for a given listing
comes back null rather than being dropped, so a column that exists for one listing exists
for all of them.

**Can I run this on a schedule?**
Yes. Schedule it like any other Actor and results append to the dataset each run. The
`scraped_at` field on every record tells you which run it came from.

### Notes

This is an unofficial scraper. It is not affiliated with, authorised by, sponsored by or
endorsed by Airbnb, and "Airbnb" is used only to say which public website it reads.

Prices, availability and ratings change constantly. A record is a snapshot at `scraped_at`,
not a standing fact.

Review counts and calendar depth are the two settings that drive run length. A market sweep
with reviews off and `calendar_months` at 1 finishes far quicker than the same sweep with
every review and a year of availability.

### Start scraping

Paste a city into `location_queries`, set `check_in` and `check_out`, and run it.

# Changelog

This Actor's version history is a separate document: https://apify.com/codepoetry/airbnb-scraper/changelog.md

# Actor input Schema

## `location_queries` (type: `array`):

Cities, regions or neighbourhoods, e.g. \["Porto, Portugal", "Lisbon, Portugal"]. Each one is searched and the results land in the same dataset.

## `start_urls` (type: `array`):

Scrape these listings directly and skip the search. Airbnb room URLs or bare listing ids. Use this instead of a location, not as well as: a run given both stops before scraping anything and says so.

## `max_listings` (type: `integer`):

Stop after this many. 20 by default, which is a complete run of every field on a real market in about twenty seconds. Raise it for a full sweep, or set 0 to take every listing the search finds — a big city is thousands of them, so that is a deliberate choice rather than something to inherit.

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

Full opens every listing's own page for the complete record. Search only reads the result cards — much faster, but most fields come back empty. Each is billed as its own event; the Pricing tab shows both.

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

Prices come back converted to this. Every option here was checked against Airbnb and returns that currency; the list is what it accepts, not every ISO code.

## `check_in` (type: `string`):

YYYY-MM-DD. Defaults to the night before check-out when only check-out is given, otherwise to about a month from the run.

## `check_out` (type: `string`):

YYYY-MM-DD, at least one night after check-in; a run given a check-out on or before check-in stops and says so. Defaults to the night after check-in.

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

Guest count sent to Airbnb's search, which affects both availability and price.

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

Children in the party. Counts toward occupancy and can change the price.

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

Infants in the party. Most listings do not count them toward occupancy.

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

Pets in the party. Some listings price these separately, others refuse them.

## `price_min` (type: `integer`):

In the currency chosen above.

## `price_max` (type: `integer`):

In the currency chosen above.

## `min_beds` (type: `integer`):

Keep only listings with at least this many beds.

## `min_bedrooms` (type: `integer`):

Keep only listings with at least this many bedrooms.

## `min_bathrooms` (type: `integer`):

Keep only listings with at least this many bathrooms.

## `min_rating` (type: `number`):

Drop listings rated below this, out of 5. A brand-new listing has no rating yet and is dropped too.

## `property_types` (type: `array`):

Empty keeps all. These four are the whole set Airbnb's own filter panel offers.

## `room_types` (type: `array`):

Empty keeps all.

## `include_reviews` (type: `boolean`):

Off by default because reviews bill per review. Turn it on and you get every review a listing has, up to the cap below.

## `max_reviews_per_listing` (type: `integer`):

Only used when "Include guest reviews" is on. 50 by default; the busiest listing measured carried 537, so this is what stops one popular property dominating a run. Set 0 for every review, however many that is.

## `calendar_months` (type: `integer`):

How far forward the day-by-day calendar goes, counted from today. Three months covers the booking window most analysis uses; raise it to 12 for a full year, or set 0 to skip the calendar and make the run faster.

## `calendar_start_month` (type: `integer`):

1-12. Defaults to the month the run happens in, which is almost always what you want.

## `calendar_start_year` (type: `integer`):

Defaults to the year the run happens in. Set it together with the month above to look at a window that starts later than this month; a window starting before this month is refused, since every day in it has already happened.

## `max_pages` (type: `integer`):

Usually leave empty — "How many listings" already bounds the run, and search pages are free. About 18 listings per page.

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

The language Airbnb writes review dates, house rules and cancellation terms in. It does not change which listings come back.

## `proxy_country` (type: `string`):

Which country to search Airbnb from. Airbnb ranks listings, converts prices and shows availability differently depending on where the visitor is, so a Paris search seen from France is not the same result set you get from the United States — different ordering, different totals, sometimes different listings.

Pick the country your buyers browse from. The scraper reads that country's own Airbnb site (airbnb.de for Germany, airbnb.co.uk for the UK) and returns what a visitor there actually sees.

Leave it empty and it follows the language above, so choosing German browses Germany. Set both when they should differ — an English-speaking analyst researching the German market, for example.

China and Russia are not listed: Airbnb withdrew from both in 2022 and a search from either returns nothing. So Russian and Chinese, left to follow the language, browse the United States; pick a country here to browse somewhere else.

## Actor input object example

```json
{
  "location_queries": [
    "Paris, France"
  ],
  "start_urls": [],
  "max_listings": 20,
  "mode": "full",
  "currency": "USD",
  "min_rating": 0,
  "property_types": [],
  "include_reviews": false,
  "max_reviews_per_listing": 50,
  "calendar_months": 3,
  "max_pages": 0,
  "locale": "en-US",
  "proxy_country": ""
}
```

# Actor output Schema

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

The scraped records, one row each.

## `summary` (type: `string`):

Run-level fields: source, the run instant, any run-level errors, and `run` — how many records were delivered, how many were rejected before delivery, how many the platform itself refused, and `failuresDatasetId`, the dataset holding the rejected records themselves.

# 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_queries": [
        "Paris, France"
    ],
    "max_listings": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("codepoetry/airbnb-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 = {
    "location_queries": ["Paris, France"],
    "max_listings": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("codepoetry/airbnb-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 '{
  "location_queries": [
    "Paris, France"
  ],
  "max_listings": 20
}' |
apify call codepoetry/airbnb-scraper --silent --output-dataset

```

## MCP server setup

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