# immowelt Scraper (`lowlanddata/immowelt-scraper`) Actor

Property offers from immowelt.de and immowelt.at as clean JSON: price, price per m², rooms, living and plot area, energy class, condition, district, photos; expose pages add year built, costs and features. Agency or private as a flag; contact data never collected. Pay per result.

- **URL**: https://apify.com/lowlanddata/immowelt-scraper.md
- **Developed by:** [Lowland Data](https://apify.com/lowlanddata) (community)
- **Categories:** Real estate, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 results

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

## immowelt Scraper — property offers from Germany and Austria, GDPR-safe

Extract property offers from **immowelt.de** and **immowelt.at** — one of the two big property portals of the German-speaking market — as clean, structured JSON. Price, price per square metre, rooms, living and plot area, floor, availability, energy class, condition, posting and update time, postcode, city, district and photos on every row; the full description, year built, heating, energy certificate, commission, running costs, feature list and the site's own price comparison for the area when you ask for the expose pages. Ready for price monitoring, investment screening, market research and data pipelines.

**No agent or owner personal data, ever.** This scraper is built GDPR-first: agency names, contact persons, phone numbers, street addresses and coordinates never appear in the output — not as an option you have to remember to switch off, but by design. The only seller information included is whether the offer comes from an agency or a private owner.

### Quick start (30 seconds)

1. Put the town into **location** — e.g. `berlin`, `muenchen`, `frankfurt-am-main`, a district such as `berlin-koepenick`, or a postcode. For Austria set **country** to `at` and type `wien` or `graz`.
2. Click **Start**. That's the whole minimum setup: apartments and houses for sale, newest first.
3. When the run finishes, open the dataset's **Overview** tab for a clean table, or **Export** it as CSV/Excel/JSON.

Switch **offerType** to rent, pick **propertyTypes** (apartments, houses, plots), add price, room and living-area filters, keep **sortBy** on newest and put the run on a schedule for a daily watch.

### What you can build with it

- **Screen a town for investment flats.** Search `location: leipzig`, `offerType: buy`, `propertyTypes: ["apartment"]`, `priceMaxEur: 150000`, `roomsMin: 2` and get every matching offer with `priceCents`, `pricePerSqmCents`, `livingAreaSqm`, `energyClass`, `condition` and `district` — a yield screen in one run, and with `scrapeDetails` on, the site's own `areaPricePerSqmAverage` to compare against.
- **Watch a district for new listings.** Keep `sortBy: newest`, cap `maxItems` at a page, and schedule the run daily; the newest Köpenick houses land in your sheet or Slack with the price already parsed and `postedAt` on every row.
- **Follow the rental market.** `offerType: rent` on `muenchen` returns the headline rent as `priceCents` with its label (`Kaltmiete`), and the expose page adds the running costs by name, so a rent index per district is a pivot table away.
- **Feed an AI agent clean data.** Every field is structured, predictable and free of personal data, so an assistant or pipeline can consume it directly — no scrubbing, no compliance review before you store it.

### What you get

Each offer is one dataset item:

```json
{
  "listingId": "26GVA4CMMEGB",
  "url": "https://www.immowelt.de/expose/571738be-0e83-45ae-850b-b7bcb3d3e1be",
  "exposeId": "571738be-0e83-45ae-850b-b7bcb3d3e1be",
  "title": "Wohnung zum Kauf",
  "headline": "Bezugsfrei! Tolle 2-Zimmer Wohnung Mit Balkon zum Garten in Süd-West Ausrichtung!",
  "description": "Diese charmante 2-Zimmer-Wohnung befindet sich im 2. Obergeschoss eines gepflegten Mehrfamilienhauses aus dem Jahr 1931 ...",
  "offerType": "buy",
  "propertyType": "apartment",
  "priceCents": 16900000,
  "currency": "EUR",
  "priceDisplay": "169.000 €",
  "pricePerSqmCents": 310300,
  "rooms": 2,
  "livingAreaSqm": 54.46,
  "floor": "2.",
  "energyClass": "G",
  "condition": "well_kept",
  "brokerageFee": false,
  "postedAt": "2026-07-12T14:20:08.623Z",
  "updatedAt": "2026-10-22T09:28:22.233Z",
  "status": "published",
  "countryCode": "DE",
  "postcode": "13583",
  "city": "Berlin",
  "district": "Spandau",
  "sellerType": "professional",
  "imageUrls": ["https://mms.immowelt.de/a/b/0/6/ab06bd2b-1b29-4582-a1eb-9ca406b3ee95.jpg"]
}
```

With **Fetch expose pages** on (or for offers named in `listingIds`), each item also carries the full `description`, `locationDescription`, `additionalInfo`, `yearBuilt`, `heating`, `energySource`, `energyCertificate`, `commissionFee`, `additionalCosts`, `features`, `reference`, `areaPricePerSqmAverage`, `areaPricePerSqmLow` and `areaPricePerSqmHigh` — the expose page's whole fact sheet.

Field notes, so you know exactly what you are buying:

- `priceCents` is the headline figure a visitor reads: the purchase price, or the rent before costs. `priceLabel` carries the site's label for it on rentals (`Kaltmiete`, `Miete`). On Austrian rentals the site keeps a total rent including costs beside the headline; it arrives as `totalPriceCents` whenever it differs.
- `pricePerSqmCents` is the site's own per-square-metre figure, present on sales.
- `condition` is the site's code on search rows (`well_kept`, `need_of_renovation`, `first_occupancy`, ...) and its label on expose pages (`Gepflegt`, `Neubau, Erstbezug`).
- `floor` is the site's text: `EG`, `2.`, `1/3`.
- `postedAt` and `updatedAt` are full timestamps on every row.
- `postcode`, `city` and `district` are municipality-level; street and coordinates are never collected, for agencies as for private owners, even where the site publishes the street.
- Labels (`heating`, `energySource`, `features`, `additionalCosts` keys) are the site's German words.
- `exposeId` is the id in the offer's address; `listingId` is the Online-ID the page shows. `listingIds` takes either.

### How much does it cost to scrape immowelt?

$3.00 per 1,000 offers delivered, pay-as-you-go: no subscription, and you pay per result rather than per hour. A run that finds nothing still costs the $0.005 actor start. In plain dollars:

- **100 offers ≈ $0.30** — a daily district watch.
- **500 offers ≈ $1.50** — a solid town snapshot.
- **A 4,000-offer crawl ≈ $12.00** — a whole city, deduplicated.

The price is all-inclusive: your runs' platform usage, including the residential proxy, is covered by it. immowelt answers only requests from consumer networks, so the actor runs through an Apify residential proxy by default — that is the form's default, nothing to configure, and nothing extra on the bill.

Free-plan runs are limited to a sample of 5 items, enough to evaluate the output format against your real query.

### Not technical? Let your AI assistant set it up

Copy this into ChatGPT, Claude or any AI assistant, fill in the one line, and follow the conversation:

```text
Help me set up the "immowelt Scraper" actor on Apify
(https://apify.com/lowlanddata/immowelt-scraper). Guide me one step at a time.

What I want to watch: [E.G. "2-room flats for sale in Leipzig under 150,000 euro"]

Guide me to:
1. Propose my input values: location (a town, district or postcode, e.g. leipzig or
   berlin-koepenick), country (de or at), offerType (buy or rent), propertyTypes
   (apartment, house, land), the price, rooms and living-area filters I need, sortBy
   "newest" for monitoring, and maxItems.
2. Decide whether I need scrapeDetails (the full description, energy data, costs and
   feature list from each expose page) or whether the search rows are enough.
3. Create a free Apify account (apify.com), open the actor page, paste the values
   into the Input form, and start a run.
4. Set up a daily Schedule in the Apify Console with the same input, plus an email
   or Slack integration so new results reach me automatically.
5. Show me how to export results as CSV/Excel, or read them from the API if I code.
6. If the results are what I wanted, remind me at the end to leave a quick rating on the actor page, and to report anything broken or missing on its Issues tab.
```

### Input

| Field                                  | Description                                                                                                                                                                             |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `location`                             | Town, district (`berlin-koepenick`) or postcode, spelled with umlauts written out (`koeln`, `muenchen`); plain spelling is normalised. A search address copied from the site works too. |
| `country`                              | `de` (default) or `at`.                                                                                                                                                                 |
| `offerType`                            | `buy` (default) or `rent`.                                                                                                                                                              |
| `propertyTypes`                        | Any of `apartment`, `house`, `land`. Default: apartments and houses.                                                                                                                    |
| `listingIds`                           | Re-check known offers by id or address instead of searching; each read from its own page; gone offers are skipped and not billed. Up to 50.                                             |
| `priceMinEur`, `priceMaxEur`           | Price band in euros (purchase price, or monthly rent).                                                                                                                                  |
| `roomsMin`, `roomsMax`                 | Room count band.                                                                                                                                                                        |
| `livingAreaMinSqm`, `livingAreaMaxSqm` | Living area band in square metres.                                                                                                                                                      |
| `sortBy`                               | `newest` (default), `price_asc`, `price_desc`, `relevance`.                                                                                                                             |
| `maxItems`                             | Stop after this many offers (default 1000).                                                                                                                                             |
| `scrapeDetails`                        | Read each offer's expose page for the full fact sheet. One extra request per offer.                                                                                                     |

A run needs a `location` or a list of `listingIds`; anything else is optional. An unknown place, an inverted band or an empty property-type list fails before the run starts, with the reason in the status message.

#### Finding a location

Type the town as the site spells it in its addresses: `https://www.immowelt.de/suche/koeln/wohnungen/kaufen` means `location: koeln`. Districts are town-district (`berlin-koepenick`, `muenchen-schwabing`), postcodes work as they are, and Austrian towns go with `country: at`. Capitals and umlauts are normalised for you ("Köln" becomes `koeln`).

### Use it from your code

Run the actor and get items straight back with one HTTP call (fine for scoped runs up to ~5 minutes):

```bash
curl "https://api.apify.com/v2/acts/lowlanddata~immowelt-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"location": "berlin", "propertyTypes": ["apartment"], "maxItems": 100}'
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/immowelt-scraper').call({
  location: 'berlin',
  propertyTypes: ['apartment'],
  maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/immowelt-scraper").call(
    run_input={"location": "berlin", "propertyTypes": ["apartment"], "maxItems": 100})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

For large crawls, start the run asynchronously and fetch the dataset when the finished-run webhook fires. Schedules (e.g. a daily price snapshot), webhooks and the Make/Zapier/n8n integrations all work out of the box — this is a standard Apify actor.

### Use it with AI agents (MCP)

Claude, Cursor and other MCP-capable agents can run this scraper as a tool through Apify's hosted MCP server: the agent fills in the search itself, starts the run and reads the results — no glue code.

Claude Code:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/immowelt-scraper"
```

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

```text
https://mcp.apify.com?actors=lowlanddata/immowelt-scraper
```

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp), or start from this actor's own MCP page: [apify.com/lowlanddata/immowelt-scraper/api/mcp](https://apify.com/lowlanddata/immowelt-scraper/api/mcp).

Prompts that work once connected:

- "Find the 50 cheapest two-room flats for sale in Leipzig on immowelt and give me the price per square metre by district."
- "Snapshot every house for sale in berlin-koepenick and tell me the median price and the share rated energy class D or worse."
- "List today's newest rentals in Wien under 1,200 euro on immowelt.at and flag any with a garden in the features."

### Beyond the first page

immowelt serves every page of a query, 30 offers at a time, up to the count it reports — a town with ten thousand flats comes through whole when `maxItems` asks for it. Narrow queries (a district, a price band, a property type) run in seconds; a whole city is a few minutes of paced pages.

### Is it legal to scrape immowelt?

Public listing data — prices, areas, energy classes, locations, photos — is public commercial information, and this scraper is built so that the hard part of the question never arises: **no personal data enters your dataset in the first place.** German and Austrian data-protection authorities are strict on personal data; an output that carries none is the point of this actor, not an afterthought.

The output is produced by a whitelist: only named, non-personal fields are read from each offer; the contact block — agency, contact person, phone numbers, profile and imprint links — and the street and coordinates are never touched, for agencies as for private owners, and a test on every build fails if any of them appears. Requests are paced, run through a residential proxy as a visitor's would be, and nothing is done to defeat the site's access controls.

One honest limit: headlines and descriptions are the seller's own words, delivered as-is. If a seller chooses to type an address or contact details into their text, that text is not rewritten — the guarantee covers the data fields, not the content sellers publish about themselves.

### Is there an immowelt API alternative?

immowelt publishes no public API for its listings. This actor is the practical alternative: the same offers as structured JSON through one HTTP call (`run-sync-get-dataset-items`), on a schedule, or as an MCP tool for AI agents — with the GDPR question already answered in the data itself.

### Does immowelt block scrapers?

immowelt serves its search results and expose pages to ordinary consumer traffic, with the data embedded in the page, and answers requests from datacenter networks with a block. This actor stays inside that welcome: it reads the pages the way a visitor does, through a residential exit, paced, with the load kept negligible. No CAPTCHA fights, no bot-wall cat-and-mouse — which is also why runs are fast and reliable enough for daily schedules. Should the site refuse a request anyway, the run retries on a fresh proxy exit a few times, then stops and says in its status how many offers it collected.

### How do I monitor immowelt prices?

Keep `sortBy: newest` with your location and filters, cap `maxItems` to a page or two, and add a daily (or hourly) Schedule in the Apify Console with an email/Slack integration on the runs — every new offer lands in your inbox with the price already parsed. To follow particular offers over time, put their ids into `listingIds`: each run returns their current price and status, and a sold or withdrawn offer is reported in the log and not billed. The AI-assistant prompt above walks a non-technical user through exactly this setup.

### FAQ

**Can I get agency or owner contact details?** No — by design. That is the product: data you can store, share and process without a GDPR review. The output tells you only whether the offer comes from an agency or a private owner.

**Which sites does it cover?** immowelt.de for Germany and immowelt.at for Austria, chosen with `country`. Same columns on both.

**Can I get only the newest offers?** Sort by `newest` and cap `maxItems`; every row carries `postedAt`, so a daily schedule with a small cap is a daily watch.

**How fresh is the data?** Live at run time — every run queries the site directly. For continuous freshness, schedule the actor.

**Can I export to Excel or CSV?** Yes — every dataset exports as CSV, Excel, JSON or XML from the Apify Console or API.

**What happens on a big town?** The run walks every page the site serves, 30 offers each, until `maxItems`; raise it and the whole town comes through.

**Do I get the full fact sheet?** Search rows carry price, price per m², rooms, areas, floor, availability, energy class, condition and dates. Turn on `scrapeDetails` for the expose page's full description, year built, heating, energy source and certificate, commission, running costs, features, reference number and the area price comparison.

**Do I need residential proxies for immowelt?** Yes, immowelt only answers requests from consumer networks. The actor's default proxy setting is already an Apify residential proxy; leave it as it is. The price covers it.

**Does it work with Make, Zapier or n8n?** Yes — it is a standard Apify actor; all platform integrations, webhooks and schedules apply.

### Related scrapers

Working the German-speaking property market? The same GDPR-clean guarantee, same output shape:

- [Kleinanzeigen Scraper](https://apify.com/lowlanddata/kleinanzeigen-scraper) — Germany's classifieds site, property included.
- [willhaben Scraper](https://apify.com/lowlanddata/willhaben-scraper) — Austria's marketplace.
- [Immoweb Scraper](https://apify.com/lowlanddata/immoweb-scraper) — Belgium's property portal.

### Troubleshooting

The actor fails fast with the reason in the run's status message:

- **"immowelt.de knows no place called ..."** — spell the town as the site's addresses do (`koeln`, `muenchen`, `frankfurt-am-main`), a district as town-district (`berlin-koepenick`), or use a postcode.
- **"Provide a location to search (e.g. berlin), or the listingIds to re-check."** — the form was submitted without either.
- **"immowelt returned no readable results before anything could be fetched."** — the site refused every proxy exit tried; retry in a few minutes.
- **Fewer items than requested on a free plan** — the 5-item free sample cap; run on a paid Apify plan for full results.

### Support

Found an issue or missing a field you need? Open an issue on the actor's **Issues tab** — reports get fixed, this actor is actively maintained.

Working well for you? A **rating on this page** takes ten seconds and helps other buyers find a GDPR-clean option among the lookalikes — it is also the clearest signal of what we should build next.

# Actor input Schema

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

The town, district or postcode to search: <code>berlin</code>, <code>muenchen</code>, <code>frankfurt-am-main</code>, <code>berlin-koepenick</code>, <code>10115</code>, <code>wien</code> (with <b>country</b> at). Umlauts are written out for you. A search address copied from the site works too. Leave it out only when you re-check offers through <b>listingIds</b>.

## `country` (type: `string`):

immowelt.de for Germany or immowelt.at for Austria. The columns are the same on both.

## `offerType` (type: `string`):

Offers for sale or for rent.

## `propertyTypes` (type: `array`):

Apartments, houses, plots of land, or any mix. Defaults to apartments and houses.

## `listingIds` (type: `array`):

Re-check offers you already know instead of searching: one per line, as the id at the end of the offer address (the <code>exposeId</code> of every dataset item), the Online-ID shown on the page (the <code>listingId</code>), or the offer's full address. Each one is read from its own page, so it carries the full description, the energy data, the costs and the feature list. An offer that is gone from the site is skipped, named in the log and not billed. <b>When given, the search fields of this form are ignored</b> and the run status says which; <b>country</b> still picks the site. Up to 50.

## `priceMinEur` (type: `integer`):

Only include offers priced at least this many euros (the purchase price, or the rent).

## `priceMaxEur` (type: `integer`):

Only include offers priced at most this many euros.

## `roomsMin` (type: `number`):

Only include offers with at least this many rooms.

## `roomsMax` (type: `number`):

Only include offers with at most this many rooms.

## `livingAreaMinSqm` (type: `integer`):

Only include offers with at least this living area in square metres.

## `livingAreaMaxSqm` (type: `integer`):

Only include offers with at most this living area in square metres.

## `sortBy` (type: `string`):

Order of results: newest (best for monitoring), price_asc, price_desc, or relevance (the site's own order).

## `maxItems` (type: `integer`):

Stop after this many offers. Free-plan runs are capped at 5 items. The form starts at 25 for a cheap first run - that is the form's prefill, not a cap on your plan; clear it to use the default of 1000. The site serves every page of a query, so a whole town comes through when you raise it.

## `scrapeDetails` (type: `boolean`):

The search card carries the price, rooms, area, floor, energy class, condition and a trimmed description. Turn this on to read each offer's own page for the full description, the location text, year built, heating, energy source and certificate, commission, running costs, the feature list, the agency's reference number and the site's own price-per-m² comparison for the area. One extra request per offer, so a run is slower. Agency names, contact persons, phone numbers, streets and coordinates are never read.

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

Proxy settings. immowelt answers only consumer networks, so the default is an Apify residential proxy; the price covers it. Leave it as it is.

## `reportFailures` (type: `boolean`):

When a run fails, send the developer the actor name and build, an error category, the error message (truncated) and a one-way hash of your input - so a bug can be fixed without anyone asking you to reproduce it. <b>Your input itself, your results and your identity are never sent, and successful runs send nothing at all.</b> Switch this off and the actor behaves exactly the same.

## Actor input object example

```json
{
  "location": "berlin",
  "country": "de",
  "offerType": "buy",
  "propertyTypes": [
    "apartment"
  ],
  "listingIds": [],
  "sortBy": "newest",
  "maxItems": 25,
  "scrapeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "reportFailures": true
}
```

# Actor output Schema

## `offers` (type: `string`):

Scraped immowelt property offers, one JSON object per offer.

# 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": "berlin",
    "country": "de",
    "offerType": "buy",
    "propertyTypes": [
        "apartment"
    ],
    "listingIds": [],
    "sortBy": "newest",
    "maxItems": 25,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lowlanddata/immowelt-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": "berlin",
    "country": "de",
    "offerType": "buy",
    "propertyTypes": ["apartment"],
    "listingIds": [],
    "sortBy": "newest",
    "maxItems": 25,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("lowlanddata/immowelt-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": "berlin",
  "country": "de",
  "offerType": "buy",
  "propertyTypes": [
    "apartment"
  ],
  "listingIds": [],
  "sortBy": "newest",
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call lowlanddata/immowelt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lowlanddata/immowelt-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/9c2fYkr8XiBuv0Ucq/builds/dbirrH5nmYGSETz1d/openapi.json
