# Willhaben Property Scraper - Austria Real Estate Data (`sian.agency/willhaben-property-scraper`) Actor

Scrape every willhaben.at property listing across Austria — apartments, houses, plots and commercial, to buy or to rent. Price, price per m², area, rooms, GPS, agency and photos on every row, plus the energy certificate and agency phone number on demand.

- **URL**: https://apify.com/sian.agency/willhaben-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.06 / 1,000 property 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?

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

## Willhaben Property Scraper — Austrian Real Estate Data 🏘️

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![ImmobilienScout24 Property Scraper](https://img.shields.io/badge/Store-ImmobilienScout24%20Property%20Scraper-FF3F19)](https://apify.com/sian.agency/immobilienscout24-property-scraper?fpr=sian) [![Immowelt Property Scraper](https://img.shields.io/badge/Store-Immowelt%20Property%20Scraper-009FE3)](https://apify.com/sian.agency/immowelt-property-scraper?fpr=sian) [![WG-Gesucht Property Scraper](https://img.shields.io/badge/Store-WG--Gesucht%20Property%20Scraper-1AE392)](https://apify.com/sian.agency/wg-gesucht-property-scraper?fpr=sian)

#### 🎉 200 listings per request, no depth limit — a 42,000-listing category comes out whole

##### Built for analysts, agencies and investors who need the Austrian market as a spreadsheet

### 🔎 What is the Willhaben Property Scraper — and when should you use it?

The **Willhaben Property Scraper** turns public property listings from willhaben.at, Austria's dominant classifieds portal into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** Austrian property listings in bulk: asking price or monthly rent, price per square metre, living area, plot area, room count, property type, fittings, outdoor space, postcode, district, province, GPS coordinates, the listing agency and every photo. Switch on full details and each row also carries the complete description, the energy certificate with its HWB value and class, heating and building type, monthly running costs, the availability date and the agency's phone number.

**Use something else when:** the property is not in Austria. Use [ImmobilienScout24 Property Scraper](https://apify.com/sian.agency/immobilienscout24-property-scraper?fpr=sian) for the German market, where ImmobilienScout24 plays the role willhaben plays in Austria. Use [Immowelt Property Scraper](https://apify.com/sian.agency/immowelt-property-scraper?fpr=sian) for Germany's second portal, useful when a German search needs a second source. Use [WG-Gesucht Property Scraper](https://apify.com/sian.agency/wg-gesucht-property-scraper?fpr=sian) for flatshares and student rooms, which willhaben barely carries. This actor covers willhaben's property section only. Cars, jobs and the general marketplace use different attribute sets and are out of scope.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/willhaben-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want Austrian property listings and prices from willhaben using the Apify Actor `sian.agency/willhaben-property-scraper`.

Use it when I need: Austrian property listings in bulk: asking price or monthly rent, price per square metre, living area, plot area, room count, property type, fittings, outdoor space, postcode, district, province, GPS coordinates, the listing agency and every photo. Switch on full details and each row also carries the complete description, the energy certificate with its HWB value and class, heating and building type, monthly running costs, the availability date and the agency's phone number.

Don't use it when: the property is not in Austria — use immobilienscout24-property-scraper or immowelt-property-scraper or wg-gesucht-property-scraper instead.

How to call it: pick a `propertyCategory` (`101` apartments for sale, `131` apartments for rent, `102` houses for sale, `14` plots, `90` everything) and optionally a `province` (`900` Wien, `3` Niederösterreich, `6` Steiermark, `all` for the country). Narrow with `minPrice`, `maxPrice`, `minLivingArea`, `maxLivingArea`, `rooms`, `outdoorSpace`, `availableNow`, `postedLast48Hours` or a German `keyword`, and cap the run with `maxResults`. `includeDetails` adds the full description, energy certificate and agency phone number for an extra charge per listing. To expand listings you already have, set `operation` to `detail` and pass `listingUrls`; to reuse a search you built on willhaben.at, paste it into `searchUrls`.

Start with this input:
{
  "operation": "search",
  "propertyCategory": "101",
  "province": "900",
  "minPrice": 300000,
  "maxPrice": 500000,
  "rooms": "3X3",
  "maxResults": 200
}

Ask me which property category and which province, and whether they want the full details with the energy rating and agency phone number, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull every three-room apartment for sale in Vienna between 300k and 500k and rank the districts by median price per square metre.*
- *Give me everything listed for rent in Steiermark in the last 48 hours, with the agency phone number, sorted newest first.*
- *Compare apartments for sale against apartments for rent in the same postcodes and show me gross rental yield by district.*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/willhaben-property-scraper.md](https://apify.com/sian.agency/willhaben-property-scraper.md).

### 📋 Overview

**willhaben.at is where Austrian property lives.** This actor turns any of its twelve property categories into clean rows: price, price per square metre, living area, rooms, location, GPS, agency and photos. Switch on full details and each row also carries the energy certificate and the agency's phone number.

**What you get:**

- ✅ **All twelve categories**: apartments, houses, plots, commercial, holiday property and new builds, to buy or to rent
- ⚡ **200 listings per request**: one call returns 200 parsed rows, so a 42,000-listing category is 210 requests
- 🎯 **No depth ceiling**: page 210 of a 42,000-listing sweep still returns rows, so you get the whole category rather than the first thousand
- 💰 **From $1.20 per 1,000 listings**: below every willhaben property specialist on the Store, with 25 rows free to try
- 💎 **The Energieausweis**: full details carry the HWB figure and its energy class, which Austrian law requires on every listing
- ✨ **A real search builder**: category, province, price band, area, rooms, outdoor space, availability and recency are all form fields, not a URL you have to construct

### ✨ Features

- 🏘️ **Twelve property categories**: pick one from a dropdown instead of hunting for the right willhaben URL
- 📍 **Province filter**: all nine Bundesländer, plus willhaben's cross-border bucket
- 🎛️ **The filters that matter**: price band, living area, exact room count, outdoor space, available now, posted in the last 48 hours
- 📄 **Full details on demand**: complete description, energy certificate, heating, building type and condition, running costs and the agency's direct phone number
- 🌐 **Paste a search instead**: any willhaben search URL works, including single-district searches the form does not expose
- 🖼️ **Every photo**: full-size image URLs, ready to download or display
- 🗺️ **GPS on most rows**: latitude and longitude, so listings drop straight onto a map
- 🏢 **Agency identity**: name and stable agency ID on every row, plus a private-seller flag
- 🔢 **Pay per row**: errors are never charged, and the run stops the moment your budget is reached

***

### 🎬 Quick Start

Pick a category, press Start, and the dataset fills with parsed rows. Nothing to configure — no key, no login, no proxy. The default input sweeps apartments for sale across Austria.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~willhaben-property-scraper/runs?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"operation":"search","propertyCategory":"101","province":"900","maxResults":200}'
```

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose what to sweep

Pick a **Property category** — apartments for sale, apartments for rent, houses, plots, commercial. Add a **Province** if you want one region rather than the whole country.

#### Step 2: Narrow it

Set a price band, a living-area range, a room count or an outdoor-space requirement. Switch on **Posted in the last 48 hours** if you plan to run this on a schedule.

#### Step 3: Press Start

Rows arrive 200 at a time. Export as JSON, CSV or Excel, or read them straight from the API.

**That's it. In about a minute, you'll have:**

- Every matching listing with price, area, rooms and location
- GPS coordinates on most rows, ready to map
- The agency behind each listing, or a private-seller flag

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|---|---|---|---|
| `operation` | string | No | `search` for a category sweep, `detail` for full listing data |
| `propertyCategory` | string | No | willhaben category id — `101` apartments for sale, `131` for rent, `102` houses, `14` plots, `90` everything |
| `province` | string | No | `all`, or a Bundesland id — `900` Wien, `3` Niederösterreich, `6` Steiermark |
| `keyword` | string | No | Free-text search across headline and body, in German |
| `maxResults` | integer | No | Row budget for the whole run. Default 100 |
| `includeDetails` | boolean | No | Add the full description, energy certificate and agency contact. Extra charge per listing |
| `minPrice` / `maxPrice` | integer | No | Price band in euro. Monthly rent on rental categories |
| `minLivingArea` / `maxLivingArea` | integer | No | Living-area range in square metres |
| `rooms` | string | No | Exact room count: `1X1` through `5X5`, `6X9`, `10X` |
| `outdoorSpace` | string | No | `20` balcony, `10` terrace, `60` garden, `30` loggia, `40` roof terrace, `50` winter garden |
| `availableNow` | boolean | No | Only listings marked as available immediately |
| `postedLast48Hours` | boolean | No | Only listings published in the last two days |
| `sort` | string | No | `1` newest, `3` cheapest, `4` dearest, `5` smallest, `6` largest, `7` relevance |
| `searchUrls` | array | No | Paste willhaben search URLs. Replaces the form for that run |
| `listingUrls` | array | No | For `detail`: willhaben listing URLs. Have only an ad id? Send it as `https://www.willhaben.at/iad/object?adId=<id>` |

**Example — three-room apartments in Vienna between €300k and €500k:**

```json
{
  "operation": "search",
  "propertyCategory": "101",
  "province": "900",
  "minPrice": 300000,
  "maxPrice": 500000,
  "rooms": "3X3",
  "maxResults": 500
}
```

**Example — expand listings you already have:**

```json
{
  "operation": "detail",
  "listingUrls": ["https://www.willhaben.at/iad/object?adId=1738704240", "https://www.willhaben.at/iad/object?adId=1706110198"]
}
```

***

### 📤 Output

Rows are saved to the Apify dataset with **50+ fields**. The most useful ones:

| Field | Type | Description |
|---|---|---|
| `adId` | string | willhaben's own listing id — the key for de-duplicating across runs |
| `listingTitle` | string | The headline the seller wrote |
| `url` | string | Direct link to the listing |
| `price` | number | Asking price, or monthly rent on rental categories |
| `pricePerSqm` | number | Price divided by living area, pre-computed |
| `livingArea` | number | Habitable floor area in m² |
| `rooms` | number | Room count as Austria counts it — the living room is included |
| `propertyType` | string | willhaben's own type label, e.g. Maisonette, Dachgeschoßwohnung |
| `features` | array | Fittings: lift, garage, cellar, fitted kitchen, step-free access |
| `outdoorSpace` | string | Balcony, terrace, garden, loggia, roof terrace or winter garden |
| `postcode` / `district` / `state` | string | Austrian postcode, Bezirk and Bundesland |
| `latitude` / `longitude` | number | GPS, on roughly nine rows in ten |
| `advertiserName` / `advertiserId` | string | The agency, or Privat for an owner |
| `energyClass` / `energyHwb` | string / number | Energy certificate class and heating demand — full details only |
| `contactPhone` / `contactWebsite` | string | Agency contact — full details only |
| `listingDescription` | string | The complete listing text, tags stripped — full details only |
| `imageUrls` | array | Every photo, full size |

**Example row:**

```json
{
  "adId": "1036472599",
  "listingTitle": "Lichtdurchflutete Dachgeschoss-Maisonette mit Galerie und großzügiger 29 m² Dachterrasse",
  "url": "https://www.willhaben.at/iad/immobilien/d/eigentumswohnung/wien/wien-1050-margareten/lichtdurchflutete-dachgeschoss-maisonette-1036472599/",
  "price": 649000,
  "priceText": "€ 649.000",
  "pricePerSqm": 5954.13,
  "currency": "EUR",
  "livingArea": 109,
  "rooms": 3,
  "propertyType": "Maisonette",
  "features": ["Storage room", "Furnished or part-furnished", "Lift"],
  "outdoorSpace": "Terrasse",
  "address": "Kohlgasse 17",
  "location": "Wien, 05. Bezirk, Margareten",
  "postcode": "1050",
  "state": "Wien",
  "latitude": 48.18422,
  "longitude": 16.3536,
  "advertiserName": "JP Immobilien",
  "advertiserId": "19086746",
  "isPrivateSeller": false,
  "publishedAt": "2026-08-29T18:13:00.000Z",
  "imageCount": 12,
  "categoryLabel": "Apartments for sale",
  "status": "success"
}
```

***

### 💼 Use Cases & Examples

#### 1. Austrian market analysis

**A property analyst who needs the national picture, not a sample.**

**Input:** Apartments for sale, one province per run, no keyword.
**Output:** Every live listing with price, price per m², area, rooms and energy class.
**Use:** Median price per m² by postcode, inventory counts by district, and a monthly time series once the run is scheduled.

#### 2. Agency and competitor monitoring

**An estate agency that wants to know what everyone else is holding.**

**Input:** A category and province, then group by `advertiserId`.
**Output:** Every agency's live book, with prices and how long each listing has been up.
**Use:** Spot who is winning instructions in your district, and which listings are going stale.

#### 3. Investment and yield screening

**An investor comparing districts rather than individual flats.**

**Input:** Two runs — apartments for sale and apartments for rent, same province.
**Output:** Price per m² on the sale side, rent per m² on the rental side.
**Use:** Gross yield by postcode falls out of a single division, because both sides arrive pre-computed.

#### 4. New-listing alerts and lead generation

**A buying agent who needs to be first to the phone.**

**Input:** Posted in the last 48 hours, sorted newest first, full details on, scheduled daily.
**Output:** Only what went up since yesterday, with the agency's direct number.
**Use:** You pay for the new rows rather than re-buying the whole market every morning.

#### 5. Energy and renovation targeting

**A heat-pump or insulation business looking for the worst-rated stock.**

**Input:** A province with full details on, then filter rows to energy class E, F or G.
**Output:** Buildings with a high HWB figure, their heating type and their year of construction.
**Use:** A territory list that is already qualified by the thing you actually sell against.

#### 6. Relocation and site selection

**A company moving staff, or a family moving country.**

**Input:** Apartments for rent, a price ceiling, a minimum living area and a room count.
**Output:** Everything available in budget, with GPS and the availability date.
**Use:** Map the shortlist against commute times before anyone books a viewing.

#### 7. Feeding a property portal or an AI agent

**A product team that needs Austrian inventory in their own database.**

**Input:** A scheduled sweep of the categories you cover.
**Output:** Stable `adId` keys, so today's run diffs cleanly against yesterday's.
**Use:** Keep a mirror in sync, or hand the dataset to a model that answers questions about the market.

***

### 🔗 Integration Examples

#### JavaScript / Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/willhaben-property-scraper').call({
  operation: 'search',
  propertyCategory: '131',
  province: '900',
  maxPrice: 1500,
  maxResults: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/willhaben-property-scraper').call(run_input={
    'operation': 'search',
    'propertyCategory': '101',
    'province': '900',
    'minPrice': 300000,
    'maxPrice': 500000,
    'maxResults': 500,
})

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['adId'], item.get('price'), item.get('livingArea'))
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~willhaben-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"search","propertyCategory":"102","province":"6","maxResults":200}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Schedule the run daily with **Posted in the last 48 hours** switched on
2. **HTTP Request**: Call the actor API and wait for the dataset
3. **Process**: Filter on price per m², energy class or agency
4. **Action**: Append to a sheet, upsert into a database, or push an alert to Slack

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run — every field, every category, same quality
- No credit card required
- Enough to see the row shape and check the fields you need are there

#### PAID Tier (Production Ready)

- **Unlimited** listings per run — a whole 42,000-listing category in one go
- Pay per row delivered: failed inputs are never charged
- Full details available as a per-listing add-on

💰 **From $1.20 per 1,000 listings** — below every willhaben property specialist on the Store.

🔗 [View current pricing](https://apify.com/sian.agency/willhaben-property-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: Do I need an API key, a willhaben login or a proxy?**
A: No. Pick a category and press Start.

**Q: How deep does a sweep go?**
A: All the way. Apartments for sale carries about 42,000 listings and the last page still returns its tail rows. Many property portals stop you at the first thousand results; willhaben does not.

**Q: Which property categories are covered?**
A: All twelve — apartments and houses to buy or rent, plots, commercial to buy or rent, holiday property to buy or rent, new-build projects, other property, and an all-property sweep.

**Q: What do full details add over a listing row?**
A: The complete description, the energy certificate (HWB value and class), heating and building type, monthly running costs, the availability date, and the agency's phone number, website and office address.

**Q: Does it return the exact street address?**
A: When the seller published one, yes — roughly a third of listings carry a street. Every listing carries the postcode and district, and most carry GPS, though willhaben blurs the point to a radius on some listings.

**Q: Is the price the asking price or the rent?**
A: Whatever willhaben shows on the card. Sale categories give the asking price; rental categories give the monthly rent, which also lands in its own Monthly rent column so the two never blur in a merged dataset.

**Q: Can I paste a willhaben search URL instead of using the filters?**
A: Yes. Put it in Search URLs and every parameter in it is honoured, including single-district searches and filters the form does not expose. A pasted search replaces the form for that run.

**Q: What output formats are available?**
A: JSON, CSV and Excel, exported straight from the Apify dataset, or read over the API.

**Q: Does it cover cars, jobs or the general marketplace?**
A: No. This actor is property-only, and the attribute set it parses is the property one.

***

### 🐛 Troubleshooting

**The run returned fewer rows than the category claims**

- The row budget in **Max listings** stops the run. Raise it.
- Free accounts are capped at 25 rows per run whatever the budget says.

**A pasted search URL was skipped**

- The URL has to be a willhaben property search, so its path starts with `/iad/immobilien`. Car and job searches are out of scope.
- A single listing pasted into Search URLs is refused on purpose — put it in **Listing URLs or ad IDs** and switch the operation to Property Detail.

**Energy class and the phone number are empty**

- Those live on the listing page, not on the results card. Switch on **Add full details**, or use Property Detail mode.

**A listing ID no longer resolves**

- willhaben removes a listing once it sells, so IDs from an older export expire. The row says so rather than failing the run, and expired listings are not charged.

**The room count looks one too high**

- That is Austrian convention: the room count includes the living room, so a two-room flat is a one-bedroom flat.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

willhaben is a trademark of willhaben internet service GmbH & Co KG. This actor is not affiliated with, endorsed by, or sponsored by willhaben.

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue in the actor's repository
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

🎯 **PICK ONE PER RUN.**

🔍 **Property Listing** — every listing in a willhaben property category that matches your filters. This is the one you want 95% of the time.

📄 **Property Detail** — you already have listing links or ad IDs and want the full description, the energy certificate and the agency's phone number for each.

💡 Want the details on a LISTING run instead? Leave this on Property Listing and switch on **Add full details** below.

## `propertyCategory` (type: `string`):

🏘️ **WHICH SECTION OF WILLHABEN** to sweep. All twelve property categories are here, exactly as willhaben splits them.

🏢 **Apartments for sale** is the biggest single category in Austria — roughly 42,000 live listings.

🗂️ **All property in one sweep** returns every section together when you want the whole market rather than one slice.

💡 Sale and rental prices live in the same Price column, so pick one category per run and merge afterwards.

## `province` (type: `string`):

📍 **WHICH PART OF AUSTRIA.** Leave it on All of Austria for a national dataset.

🏙️ **Wien** alone carries about half the country's apartment listings, so it is usually worth its own run.

🎯 Splitting a big category province by province is also the tidiest way to run several short scheduled jobs instead of one long one.

🌍 **Other countries** is willhaben's own bucket for cross-border listings advertised to Austrian buyers.

## `keyword` (type: `string`):

🔑 **WHAT TO LOOK FOR** — the same words you would type into willhaben's own search box. It matches the headline and the listing body, so `Altbau` also finds "charmante Altbauwohnung".

⬜ **Leave it empty to take the whole category.** That is the fastest way to build a full market dataset.

🇦🇹 Listings are written in German, so German words match far more than English ones.

💡 One keyword per run. To sweep several, schedule one run per keyword — each is billed only for the rows it returns.

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

🔢 **STOP AFTER THIS MANY LISTINGS**, counted across the whole run.

📦 Listings arrive 200 at a time, so the run finishes the page it is on and then stops — you may receive a few more than you asked for, and you are only charged for rows delivered.

💰 **Free accounts are capped at 25 rows per run** whatever you type here. Paid accounts are not.

🚀 There is no depth ceiling on willhaben, so a whole 42,000-listing category really does come out in one run.

## `includeDetails` (type: `boolean`):

📄 **OPENS EVERY LISTING PAGE AND READS IT.** Adds the full description, the energy certificate (HWB value and class), heating and building type, running costs, the availability date and the agency's phone number and website.

💰 **Charged per enriched listing** on top of the listing row. Leave it off and you pay listing rows only.

🎯 **Worth it for:** lead generation, renovation targeting and yield work.
❌ **Skip it for:** price tracking. The results card already carries price and area.

## `listingUrls` (type: `array`):

🔗 **FOR PROPERTY DETAIL MODE:** the willhaben listings you want expanded.

📱 Open the listing → copy the address bar. Both forms work: the full `…-1738704240/` address and the `willhaben.at/iad/object?adId=1738704240` short link. Have only the ad id? Wrap it in that short link — a bare number is rejected before the run starts.

📝 **Bulk edit** — one per line. 📁 **Upload a .txt file**. 🔗 **+ Add** — one at a time.

🕒 willhaben removes a listing once it sells, so an old id may not resolve.

## `searchUrls` (type: `array`):

🌐 **PASTE A WILLHABEN SEARCH INSTEAD OF FILLING THE FORM.** Set the filters on willhaben.at, copy the address bar, drop it here.

🎛️ **Every filter in that URL is honoured** — including ones the form does not expose, such as a single Viennese district, building type or a specific fitting.

⚠️ **A pasted search REPLACES the form:** with anything here, the category, province and filters above are ignored for the run.

## `minPrice` (type: `integer`):

💵 **CHEAPEST LISTING TO INCLUDE**, in euro.

⬜ **0 means no lower bound** — that is the default.

🔑 On rental categories this is the monthly rent, not a purchase price, so €500 means €500 a month.

🎯 Filtering happens at willhaben, so a price band makes the run faster and cheaper: you are not billed for rows you filtered out.

## `maxPrice` (type: `integer`):

💰 **MOST EXPENSIVE LISTING TO INCLUDE**, in euro.

⬜ **0 means no upper bound** — that is the default.

🎯 Pair it with Min price to walk a big category one band at a time, which is also how you keep each scheduled run short: €0-200k, then €200-400k, and so on.

## `minLivingArea` (type: `integer`):

📐 **SMALLEST LIVING AREA TO INCLUDE**, in square metres.

⬜ **0 means no lower bound** — that is the default.

🌳 Plots are measured by plot area rather than living area, so this filter does nothing on the land category.

## `maxLivingArea` (type: `integer`):

📏 **LARGEST LIVING AREA TO INCLUDE**, in square metres.

⬜ **0 means no upper bound** — that is the default.

🎯 Useful with Min living area to isolate one product type: 60-79 m² is the classic Austrian two-room flat.

## `rooms` (type: `string`):

🛏️ **EXACT ROOM COUNT**, as willhaben counts it.

⚠️ **An Austrian room count includes the living room**, so a two-room flat is a one-bedroom flat. Do not translate it straight into bedrooms.

🌳 Categories without rooms, such as plots, ignore this.

💡 To take a spread, run one number per run rather than guessing a range.

## `outdoorSpace` (type: `string`):

🌿 **ONLY LISTINGS THAT ADVERTISE THIS KIND OF OUTDOOR SPACE.**

🪟 Roughly two in five Austrian apartments carry a balcony, so this is a meaningful cut rather than a rare one.

🏛️ A **loggia** is a recessed balcony inside the building line — common in Viennese new builds and priced differently from a balcony.

💡 Leave it on Any to count the whole market.

## `availableNow` (type: `boolean`):

🚚 **ONLY LISTINGS THE SELLER MARKS AS AVAILABLE RIGHT AWAY.**

🔑 Most useful on rentals, where a flat free in six months is noise if you are moving next month.

📆 The exact handover date lands in the Available from column when full details are on.

## `postedLast48Hours` (type: `boolean`):

🆕 **ONLY WHAT WENT UP IN THE LAST TWO DAYS.**

⏰ **This is the scheduling switch.** Run the actor daily with this on and you pay for the new listings only, instead of re-buying the whole market every morning.

🎯 First-mover advantage on rentals in Wien, where a well-priced flat is gone within hours.

💡 Pair it with Sort by newest first.

## `sort` (type: `string`):

↕️ **WHICH LISTINGS COME FIRST** — and, when Max listings caps the run, which sample you actually keep.

🕒 **Newest first** for monitoring and lead generation.
⬆️ **Cheapest first** for bargain hunting.
🎯 **Most relevant** when you have typed a keyword.

💡 Sorting is willhaben's own, applied before anything is billed.

## Actor input object example

```json
{
  "operation": "search",
  "propertyCategory": "101",
  "province": "all",
  "keyword": "penthouse",
  "maxResults": 100,
  "includeDetails": false,
  "listingUrls": [],
  "searchUrls": [],
  "minPrice": 0,
  "maxPrice": 0,
  "minLivingArea": 0,
  "maxLivingArea": 0,
  "rooms": "any",
  "outdoorSpace": "any",
  "availableNow": false,
  "postedLast48Hours": false,
  "sort": "1"
}
```

# Actor output Schema

## `willhabenProperties` (type: `string`):

Every willhaben property listing this run returned — price, area, rooms, location, GPS, agency and photos.

## `scrapingSummary` (type: `string`):

HTML summary showing successful and failed results with key metrics

# 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 = {
    "operation": "search",
    "propertyCategory": "101",
    "province": "all",
    "keyword": "",
    "maxResults": 100,
    "includeDetails": false,
    "listingUrls": [],
    "searchUrls": [],
    "minPrice": 0,
    "maxPrice": 0,
    "minLivingArea": 0,
    "maxLivingArea": 0,
    "rooms": "any",
    "outdoorSpace": "any",
    "availableNow": false,
    "postedLast48Hours": false,
    "sort": "1"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/willhaben-property-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 = {
    "operation": "search",
    "propertyCategory": "101",
    "province": "all",
    "keyword": "",
    "maxResults": 100,
    "includeDetails": False,
    "listingUrls": [],
    "searchUrls": [],
    "minPrice": 0,
    "maxPrice": 0,
    "minLivingArea": 0,
    "maxLivingArea": 0,
    "rooms": "any",
    "outdoorSpace": "any",
    "availableNow": False,
    "postedLast48Hours": False,
    "sort": "1",
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/willhaben-property-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 '{
  "operation": "search",
  "propertyCategory": "101",
  "province": "all",
  "keyword": "",
  "maxResults": 100,
  "includeDetails": false,
  "listingUrls": [],
  "searchUrls": [],
  "minPrice": 0,
  "maxPrice": 0,
  "minLivingArea": 0,
  "maxLivingArea": 0,
  "rooms": "any",
  "outdoorSpace": "any",
  "availableNow": false,
  "postedLast48Hours": false,
  "sort": "1"
}' |
apify call sian.agency/willhaben-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/willhaben-property-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/cIkbBsMYB84RrfvZm/builds/UEDBQhsa1YcOqBFhd/openapi.json
