Skip to content
ListingrailGet an API key

How to get ImmoScout24 listings in Python

By the end of this guide you have a CSV of Berlin flats to rent, with rent, rooms and size, from one script you can run again tomorrow. Everything below was run on 15 October 2026; the output table is what it returned.

Why scraping ImmoScout24 yourself breaks

  • ImmoScout24 has an official REST API, but searching all listings needs a separate "Content Partner" permission. A normal key only reads the listings of the customer who authorised it.
  • API access is for business accounts only and is paid: the published 2022 price list starts at EUR 59 a month for 20,000 calls.
  • The website uses AWS WAF bot protection, so browser automation works on a laptop and gets blocked in production.
  • Contact details on listings are personal data under the GDPR, so storing them needs your own legal basis.

None of that is impossible, but each point is code you then maintain. The rest of this guide uses Listingrail, which does the reading and hands back clean JSON. The ImmoScout24 API page has the official options with sources.

1. Get a key

One request with your email returns a key with 100 free listings. It is shown once, so keep it in an environment variable.

curl -X POST https://listingrail.com/v1/signup \
  -H "content-type: application/json" \
  -d '{"email": "you@example.com"}'

export LISTINGRAIL_KEY=re_...

2. Search and save to CSV

Install requests (pip install requests), then run:

import csv
import os

import requests

r = requests.post(
    "https://listingrail.com/v1/listings/search",
    headers={"Authorization": f"Bearer {os.environ['LISTINGRAIL_KEY']}"},
    json={"source":"immobilienscout24","location":"Berlin","type":"rent","limit":50},
    timeout=300,
)
r.raise_for_status()
listings = r.json()["listings"]

fields = ["price", "currency", "rooms", "area", "address", "url"]
with open("immobilienscout24-berlin.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(fields)
    for home in listings:
        writer.writerow([home[k] for k in fields])

print(len(listings), "listings saved to immobilienscout24-berlin.csv")

The request body, on its own:

{
  "source": "immobilienscout24",
  "location": "Berlin",
  "type": "rent",
  "limit": 50
}

Each listing returned costs one credit. A search that finds nothing, or fails at ImmoScout24, costs nothing. A request can take up to a minute or two, because ImmoScout24 is read at that moment.

3. What comes back

The first three rows of the run on 15 October 2026:

AddressPriceSizeAgent
Hellersdorfer Straße 91, 12619 Berlin, Kaulsdorf (Hellersdorf)362 EUR / month2 rooms · 52 m²–
Hellersdorfer Straße 87, 12619 Berlin, Kaulsdorf (Hellersdorf)760 EUR / month2 rooms · 52 m²–
Hellersdorfer Straße 87, 12619 Berlin, Kaulsdorf (Hellersdorf)363 EUR / month2 rooms · 52 m²–

Every listing has the same keys on all 17 portals, so the code for ImmoScout24 reads the others too. Fields ImmoScout24 does not show come back as null, and the portal's own record sits in raw. With pandas:

import pandas as pd

df = pd.DataFrame(listings)
df["agent"] = df["agent"].str.get("company")
print(df[["price", "rooms", "area", "address", "agent"]].head())

4. Get new listings and price cuts every day

Running the script on a schedule works, but then you compare the files yourself. A monitor stores the search, checks it once a day, and sends only what changed: new listings and price cuts. The free key holds one monitor.

requests.post(
    "https://listingrail.com/v1/monitors",
    headers={"Authorization": f"Bearer {os.environ['LISTINGRAIL_KEY']}"},
    json={
        "source": "immobilienscout24",
        "location": "Berlin",
        "filters": {"type":"rent"},
        "webhook_url": "https://example.com/new-listings",
    },
    timeout=30,
)

Changes can also be read with GET /v1/monitors/{id}/changes or downloaded as CSV. Plans and limits are on the monitors page.

ImmoScout24 quirks worth knowing

  • Pass a German city or district ("Berlin", "München"). City searches return apartments.
  • rooms is the German room count (Zimmer), which includes the living room. beds stays empty.
  • For rentals, price is the rent shown on the result card; on ImmoScout24 that is usually the cold rent (Kaltmiete), without heating and service charges.
  • area is living space in square metres. Search rows carry no agent contact.

Questions

Is the ImmoScout24 API free?

A sandbox is free; production use is paid and needs a business account. Searching the whole portal needs the extra Content Partner permission.

Is price the cold or warm rent?

It is the rent on the result card, which on ImmoScout24 is usually the cold rent (Kaltmiete). Open the listing link for the warm rent.

Can I monitor new ImmoScout24 listings?

Yes. A monitor checks your saved search every day and reports new listings and price cuts by webhook or CSV.

Get 100 free listingsAPI docsOther guides