How to use it: 3 steps
- Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
- Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example:
Berlinin Location. Each start is one run. - Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.
This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.
What it does
Export property listings from ImmobilienScout24, also called ImmoScout24, for German market research: give a city, region, postcode or search link, and get price, area, rooms, address and realtor company for each listing. No login or API key is needed, and a run with 10 rows costs about $0.011.
Good for
- You invest in German property and want to compare asking prices and rent per square metre.
- You track new listings in a city and want only the new ones each day.
- You need listing data in a spreadsheet, a database or your own tools.
Who uses it
Property investors
Compare asking prices and rent per square metre.
Market analysts
Track new listings in a city each day.
Data teams
Send listing rows to a spreadsheet or database.
Price
Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.
| What you pay for | Price | When |
|---|---|---|
| Start fee | $0.001 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
| Listing with full details | $0.00099 (from $0.00069 on paid Apify plans) | Charged for each saved listing row with full details. |
| Listing | $0.0005 (from $0.00035 on paid Apify plans) | Charged for each saved listing row with search fields only. |
| Check without a paid row | $0.00005 | Charged for each read that gives no paid row: an empty search, a listing that is gone, or a search page with nothing new. The first read in a run is free. |
Examples
- One result: about $0.002.
- 1,000 results: about $0.99.
- Every day 100 results, for 30 days: about $3.00 a month.
Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 5,000 results.
Prices checked on 8 November 2026. See the current price on Apify.
Questions
Do I need an ImmobilienScout24 account or a key?
No. The Actor reads public listings and does not log in.
Does the data include phone numbers or emails?
No. You get the realtor company name. Private sellers are marked and their names are not collected.
Why is price lower than the rent I see elsewhere?
For rent, price is the cold rent. totalRent includes costs when the listing gives them.
Do I need a proxy?
No. Normal runs do not use one, and the proxy field is there only if you want it.
Do I get all listings in Germany?
You get up to 10,000 rows per run, and only those that the source shows. Split big areas by region, or use skipItems.
How fresh is the data?
Each row is read during the run, and fetchedAt gives the time. Sort newest shows the latest listings first.
Does a run with no results cost money?
It costs the start fee. See Pricing.
How does onlyNew remember listings?
It keeps a history in a named store in your Apify account. Without stateName, each search has its own history. The first run counts all rows as new, and you pay for them.
Details
Step by step on Apify
- Open the Input tab.
locationis set to Berlin andoperationis set to rent (box 1). - Keep
maxItemsat 10 (box 2). - Click Start.
- Open Output and check
price,roomsandlivingSpace(box 4). - Check
addressandrealtor(box 5).
Use cases
| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Compare rent levels between German cities | location with operation rent | One row per listing | price, totalRent, pricePerSqm, livingSpace, postcode | Spreadsheet or BI tool |
| Find investment property for sale | location with operation buy, propertyType apartment, house or investment | One row per listing | price, pricePerSqm, yearBuilt, energyEfficiencyClass, url | Your deal list or CRM |
| Watch a search for new listings and price cuts | location or searchUrls, onlyNew, detectPriceChanges | New and changed rows | changeType, previousPrice, price, firstSeenAt | Slack, Notion or a webhook |
| Map which realtor companies work in an area | location with a high maxItems | One row per listing | realtor, city, district, operation | Market report |
| Refresh a list of known listings | searchUrls with listing links | One row per link | exposeId, price, status, fetchedAt | Your database |
Tips for better results
- Keep maxItems at 10 for a first run.
- Use filter fields with a place and radius. With links, put the filters in the link.
- Turn on onlyNew to get just the new listings on each run.
Limits and good to know
- Germany only. The source's other country sites are not covered
- Up to 10,000 rows per run. We tested this limit. A bigger area can have more listings, for example about 89,000 rental apartments in Germany. Split it by region or use
skipItems - Up to 100 links in
searchUrlsper run - The default run timeout of 300 seconds is enough for about 2,000 rows with details. A run of 10,000 rows took about 14 minutes, so set a timeout of 1,200 seconds for it. When time runs out, the run keeps its rows and ends with
reasonDEADLINE - Filter fields work with
locationand radius, not with links. Put filters in the link itself - Search links with map-drawn areas are not supported. Use a place or a radius
- Offices, retail, gastronomy and industry cannot be filtered by rent or buy, because the source mixes them
realtorneeds full details. WithfetchDetailsoff it is null
For developers
Sample result
One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.
{
"exposeId": "172422033",
"url": "https://www.immobilienscout24.de/expose/172422033",
"title": "4-Zimmer-Wohnung in Mitte",
"price": 852,
"priceUnit": "month",
"currency": "EUR",
"pricePerSqm": 9.88,
"totalRent": 1137.67,
"livingSpace": 86.2,
"rooms": 4,
"address": "Rosenthaler Straße 11, 10119 Berlin, Mitte",
"realtor": "WBM Wohnungsbaugesellschaft Berlin-Mitte mbH",
"isPrivate": false,
"operation": "rent",
"propertyType": "apartment",
"energyEfficiencyClass": "B",
"status": "complete",
"source": "immobilienscout24.de",
"fetchedAt": "2026-11-06T10:12:00.000Z"
}Use it from code
Actor ID: cliqtomedia/immobilienscout24-scraper. You need your Apify API token from Apify Console → Settings → API & Integrations.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/immobilienscout24-scraper").call(run_input={
"location": "Berlin",
"operation": "rent"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~immobilienscout24-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"location": "Berlin", "operation": "rent"}'# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("cliqtomedia/immobilienscout24-scraper")
result = tool.invoke({"run_input": {"location": "Berlin", "operation": "rent"}})
print(result)The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.
Data fields (40)
| Field | Type | Meaning |
|---|---|---|
exposeId | string | Listing ID on ImmobilienScout24. |
url | string | Link to the public listing page. |
title | string | Listing title as written by the advertiser. |
price | number | Main price in EUR, in the unit given by priceUnit. Null when the source shows none. |
priceText | string | Price as the source shows it, for example "1.750 €". |
priceUnit | string | What price stands for: total (sale price or auction value), month, day, year, or sqm (monthly rent per square metre, common for offices and retail). Null when the source shows no price. |
currency | string | Currency of the price. |
pricePerSqm | number | Price per square metre of living or usable area, or of land for plots. Null for day and year prices and when the area is unknown. |
livingSpace | number | Living area in m². |
rooms | number | Number of rooms. |
address | string | Address as public on the listing. Often only postcode and district. |
latitude | number | Latitude when the source shows it. |
longitude | number | Longitude when the source shows it. |
realtor | string | Realtor company. Needs full details. Null for private advertisers. |
realtorLogoUrl | string | Logo of the realtor company. |
isPrivate | boolean | True when a private person placed the listing. Their name is never collected. |
operation | string | rent or buy. For offices, retail, gastronomy and industry it is read from each listing, because the source mixes both there. Null when the listing does not say. |
propertyType | string | Property type, for example apartment. |
realEstateType | string | Source type code, for example apartmentrent. |
isNewBuildProject | boolean | True for a new-build developer project. |
isNewObject | boolean | True when the source marks the listing as new. |
energyEfficiencyClass | string | Energy efficiency class, A+ to H. |
fairPrice | string | Price rating from the source. |
publishedText | string | Age of the listing as the source words it, for example "vor 2 Minuten". |
tags | array | Short tags from the source. |
imageUrl | string | Main picture. |
images | array | Picture links. |
description | string | Listing text. Phone numbers and email addresses are removed. Needs full details. |
postcode | string | Postcode. |
city | string | City or town. In Berlin, Hamburg and other big cities this is the city itself, and the part of town is in district. |
district | string | Part of town or county district, as the source names it. Null when the source gives none. |
state | string | German federal state. |
street | string | Street, when the advertiser made it public. |
baseRent | number | Cold rent in EUR. |
serviceCharge | number | Service charge in EUR. |
heatingCosts | number | Heating costs in EUR. |
totalRent | number | Total rent in EUR. |
deposit | string | Deposit as the source words it. |
yearBuilt | number | Construction year. |
floor | number | Floor. |
Input settings (25)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| Location | location | string | "Berlin" |
| Rent or buy | operation | string | "rent" |
| Property type | propertyType | string | "apartment" |
| Search or listing links | searchUrls | array | |
| Maximum listings | maxItems | integer | 10 |
| Full listing details | fetchDetails | boolean | true |
| Only new listings | onlyNew | boolean | false |
| Also report price changes | detectPriceChanges | boolean | false |
| Also report removed listings | detectRemovedListings | boolean | false |
| History name | stateName | string | |
| Price from (EUR) | minPrice | number | |
| Price to (EUR) | maxPrice | number | |
| Rooms from | minRooms | number | |
| Rooms to | maxRooms | number | |
| Area from (m²) | minLivingSpace | number | |
| Area to (m²) | maxLivingSpace | number | |
| Built from (year) | minYearBuilt | integer | |
| Built to (year) | maxYearBuilt | integer | |
| Floor from | minFloor | integer | |
| Floor to | maxFloor | integer | |
| Equipment | equipment | array | |
| Apartment types | apartmentTypes | array | |
| Energy classes | energyEfficiencyClasses | array | |
| Exclude new-build projects | excludeNewBuildProjects | boolean | false |
| Radius (km) | radiusKm | number |







