immoscout24-kleinanzeigen-apply-bot
Pricing
from $150.00 / 1,000 application sents
immoscout24-kleinanzeigen-apply-bot
Monitors ImmoScout24 and Kleinanzeigen for new rental listings, filters them by area, price per m² and keywords, then sends a personalized application or message from your own account. Includes deduplication, listing snapshots and email alerts.
Pricing
from $150.00 / 1,000 application sents
Rating
0.0
(0)
Developer
Vincent
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
ImmoScout24 & Kleinanzeigen Apply Bot - Automated Rental Applications
Finding a flat in Germany is a race you lose by being asleep. This Actor watches ImmoScout24 and Kleinanzeigen for new rental listings, filters out the ones you would never take anyway, and sends a personalized application from your own account within minutes of a listing going online - while you are at work, commuting, or in bed.
Built for the German rental market: Berlin, Munich, Hamburg, Cologne and beyond. Every application is written per listing, mentioning the actual room count, size, district and move-in date, so it does not read like a template.
What it does
- Monitors your saved searches on ImmoScout24 or Kleinanzeigen and picks up only listings that are genuinely new
- Filters by rent per m2, keywords (furnished, sublet, swap, WBS) and, for Berlin, by postal code and radius
- Writes a personalized application per listing from your template, filling in rooms, size, district, period features and move-in date
- Sends it from your own account through the official apply and message Actors
- Never applies twice to the same listing, across runs and across schedules
- Archives every listing you applied to as an HTML snapshot with photos, so you still have it after the ad disappears
- Emails you a summary with the text that was sent, and keeps a filterable dashboard of every run
Before you start: required Actors
This Actor is the brain, not the hands. It orchestrates existing scraper and apply Actors, which you need access to as well. Please check these costs before you start, they are not included in this Actor's price:
| What | Actor | Cost (August 2026) |
|---|---|---|
| ImmoScout24 listings | clearpath/immoscout24-api-pro | pay per result |
| ImmoScout24 applications | clearpath/immoscout24-apply-bot | ~$79 / month |
| Kleinanzeigen listings | clearpath/kleinanzeigen-immobilien-api-pro | ~$45 / month |
| Kleinanzeigen messages | clearpath/kleinanzeigen-message-api | ~$0.49 per message |
| Email notifications | apify/send-mail | free |
You only need the Actors for the portal you actually use. Running Kleinanzeigen only is the cheaper entry point.
The two monthly fees are going away
Apify retires the rental pricing model on 1 October 2026. The two Actors above that currently cost a flat monthly fee have to move to a usage-based model, so from October there is no monthly fee to pay before your first application.
Whether your total drops depends on how you use them. Flat fees are replaced by per-use pricing, which is a clear win if you run a search a few times a day, and less so if you monitor many cities around the clock. clearpath/immoscout24-api-pro already switched to pay-per-result, which is a good hint at where the others are heading.
Prices in the table are from August 2026 and are set by their authors, not by this Actor. Check the linked pages for what they cost today before you budget.
If you already use different scrapers, you can point this Actor at them with the override fields under Underlying Actors.
Quick start
Kleinanzeigen
- Run
clearpath/kleinanzeigen-message-apionce withoperation: loginand your account details. If Kleinanzeigen asks for a code, run it again withoperation: verify2fa. This is a one-time step. - Configure this Actor:
{"platform": "kleinanzeigen","startUrls": ["https://www.kleinanzeigen.de/s-wohnung-mieten/berlin/anzeige:angebote/c203l3331+wohnung_mieten.qm_d:70.00%2C+wohnung_mieten.zimmer_d:3.0%2C"],"kaEmail": "you@example.com","emailTo": "you@example.com","monitorMode": true,"runApply": false,"maxAppliesPerRun": 3,"maxColdPricePerSqm": 25,"allowedZipCodes": ["10119", "10179", "10249", "10405", "10997"],"locationRadiusKm": 1.5,"excludedListingKeywords": ["möbliert", "befristet", "Untermiete", "WBS"],"applicationTemplate": "{{anrede}}\n\nIhre {{roomsStr}}-Zimmer{{altbauSuffix}} Wohnung{{locationSuffix}} hat mich sofort angesprochen.{{highlightsSuffix}} {{vacantPhrase}}\n\nZu mir: berufstätig, Nichtraucher, keine Haustiere. Bewerbungsmappe sende ich gerne sofort zu.\n\nViele Grüße"}
- Start with
runApply: false. Nothing is sent, but you see exactly which listings would qualify. - Happy with the result? Set
runApply: trueand schedule the task every 15 to 30 minutes.
ImmoScout24
Same, but set platform: "immoscout", use ImmoScout24 search URLs and provide username plus password for your account.
Output
One dataset record per listing, with the decision and why:
{"status": "applied","platform": "kleinanzeigen","exposeId": "3452915683","listingUrl": "https://www.kleinanzeigen.de/s-anzeige/...","title": "Helle 3-Zimmer-Altbauwohnung mit Balkon","cityDistrict": "Friedrichshain","zipCode": "10245","rooms": 3,"size": 105,"rentCold": 1450,"rentTotal": 1785,"pricePerSqmCold": 13.81,"filterReasons": [],"locationStage": "geo","locationDistanceKm": 0.64,"applicationMessage": "Hallo,\n\nIhre 3-Zimmer Altbau Wohnung in Friedrichshain ...","conversationId": "2dk9x:3cc4mpn:2pm0lqzj3","snapshotHtmlUrl": "https://api.apify.com/v2/key-value-stores/.../records/...","processedAt": "2026-08-06T10:43:22.119Z"}
Rejected listings arrive with status: "filtered" and a populated filterReasons, so you can see whether your filters are too tight.
Pricing
You pay per sent application. Collecting and filtering listings is billed per dataset record, which is a fraction of a cent.
A realistic scheduled run in monitor mode looks at a handful of new listings and sends one or two applications, so a normal day costs the price of a coffee - plus the underlying Actors listed above, which are the larger part of the bill today and get cheaper for light users once their monthly fees end in October 2026.
Use Max applications per run to cap your spend, and the run-level spending limit in Apify Console for a hard ceiling. The Actor stops sending once that limit is reached.
Features in detail
Personalized applications
Placeholders are filled from the listing data, so every message is specific:
| Placeholder | Becomes |
|---|---|
{{anrede}} | Salutation |
{{roomsStr}} | 3 |
{{sizeStr}} | 105 |
{{altbauSuffix}} | Altbau for pre-1950 buildings |
{{locationSuffix}} | in Friedrichshain (Boxhagener Str.) |
{{highlightsSuffix}} | Condition and balcony sentence |
{{vacantPhrase}} | Move-in date sentence |
{{abloeseSentence}} | Added when the ad mentions a handover fee |
{{aiParagraph}} | Optional AI sentence, needs an OpenAI key |
(pictures)...(/pictures) | Included only when the listing has photos. Aliases: (photos), (fotos), (bilder) |
Example: Die Lage gefällt mir.(pictures) Die Fotos der Wohnung haben mich sofort überzeugt.(/pictures) {{vacantPhrase}}
District names are normalized for Berlin, Munich, Hamburg, Cologne, Stuttgart and Düsseldorf, so your text says "in Prenzlauer Berg" rather than a raw data field.
Area filter (Berlin)
Instead of one search URL per postal code, use one broad city search and list the postal codes you care about. Neighbouring postal codes, coordinates and district names are derived automatically:
Location filter: 8 core ZIP(s) -> 31 ZIP(s) within 1.5 kmLocation filter results: geo=34 zip=0 district=0 unresolved=0 skipped=161
Each listing is matched on the first location signal it actually has - coordinates, then postal code, then district. Listings with none of those are kept, never silently dropped, and counted as unresolved so you can see how often it happens.
This matters for cost: each search URL is a separate proxied scrape. One city-wide search instead of eight postal code searches cuts that part of the bill by roughly eight.
No duplicate applications
Every listing you applied to is remembered permanently by its listing ID. Re-running, rescheduling or widening your search never produces a second application to the same landlord. Use a separate Queue namespace per search so parallel schedules do not consume each other's queue.
Run dashboard
Each run writes a filterable HTML dashboard: how many listings were found, queued, filtered and applied to, with the reason for every rejection. Useful when you wonder why a listing you saw on the portal never got an application.
Limitations
- The postal code area filter currently supports Berlin only. Everywhere else, use the portal's own location filter in your search URL; the rest of the Actor works normally.
- The Kleinanzeigen scraper processes one search URL per call, so this Actor runs it once per URL. Prefer one broad search plus the area filter.
- Kleinanzeigen requires a one-time login through the message Actor before anything can be sent.
- In monitor mode the first run only records a baseline and returns nothing. That is expected.
FAQ
Do I need my own account? Yes. Applications are sent from your own ImmoScout24 or Kleinanzeigen account, not from a shared one. Credentials are stored encrypted by Apify.
Why do I need those other Actors? This Actor does the deciding: monitoring, filtering, deduplication, personalization and reporting. The scraping and the actual sending are done by specialized Actors that maintain their own logins and anti-bot handling. You can substitute your own via the override fields.
Can I use it outside Berlin? Yes. Only the postal code area filter is Berlin-specific. Set your area in the portal search URL instead.
Will landlords notice it is automated? The text is generated from your own template and references concrete details of each listing. Write it as you would write it yourself, keep the pacing delay enabled, and keep the volume reasonable.
How do I stop it applying to the wrong listings? Run with Send applications off first. You get the full list of what would have been sent, with reasons, and can tune your filters before anything goes out.
Legal
This Actor acts through your own account on portals you already have a contract with. You are responsible for complying with the terms of service of ImmoScout24 and Kleinanzeigen, and with applicable data protection law including GDPR. Listing texts and landlord names are personal data - handle them accordingly. The author provides no warranty and accepts no liability for how the Actor is used.
Operating notes
The sections below are reference material for day-to-day operation.
Queue namespaces
The queue is scoped by kvNamespace. Use a distinct value per search, for example is_berlin and ka_berlin. Changing it starts with an empty queue, which is the simplest way to discard a backlog of stale listings.
If left empty, a scope is derived from the search profile ID or a hash of the search URLs.
Cost control
Proxy traffic and the underlying Actors dominate the bill.
- Replace per-postal-code search URLs with one broad city search plus the area filter
- Keep monitor mode on so only new listings are fetched in detail
- Lower the schedule frequency; the queue still drains at your per-run application limit
- Keep photo quality on hybrid, or web resolution if you do not need full-size images
- Leave the dashboard retention at its defaults; the log is rewritten in full on every flush
Run dashboard settings
opsLogEnabled (default on), opsLogMaxEvents (1000), opsLogMaxRuns (500), opsLogMaxFilteredListings (2000), opsLogMaxApplications (2000).
The dashboard link is printed at the start of every run. Higher retention means larger key-value writes on every flush, so raise these only if you need the depth.
Troubleshooting
| Symptom | Cause |
|---|---|
| First run returns nothing | Monitor mode is recording its baseline. Expected. |
| Everything filtered by location | Raise locationRadiusKm or add postal codes. Check the Location filter results line. |
High unresolved count | Listings carry no location data. Leave skipListingsWithUnknownLocation off so they are kept. |
| Kleinanzeigen send fails | The account is not logged in. Run the message Actor with operation: login. |
| Duplicate applications | Two schedules share a queue namespace. Give each its own. |
| Search URLs rejected | The URLs do not match the selected platform. |
Development
npm installnpm testnpm run build:zipdata # regenerate the Berlin postal code table (~4 min, uses Nominatim)
src/lib/berlin-zip-data.js holds 190 Berlin postal codes with centroid, district and borough, generated from OpenStreetMap data (ODbL) and committed so runs need no network access.