{"auth":{"derive":[{"from":"dom","name":"gac_key","regex":"(?:NEXT_PUBLIC_GAC_API_KEY|gacApiKey)\\W{1,10}([0-9a-f]{16,64})","selector":"script:not([src])"}]},"description":"Searches ImmoScout24 rentals like the site's own result list: cold and warm rent, rooms, living space, address (as far as the landlord shows it), publish date, private or agent listing, balcony and fitted kitchen, and the expose link. Swap-only listings (Tauschwohnung) are dropped by default. Runs only in the user's browser: AWS WAF rejects every request without the browser's own aws-waf-token cookie.","effect":"read","id":"immobilienscout24.de/search-rentals","keywords":["immobilienscout24","immoscout","wohnung mieten","mietwohnung","wohnungssuche","haus mieten","miete","zimmer","apartment","flat for rent","rental","housing","apartment search germany"],"output":{"schema":{"properties":{"city":{"description":"City actually searched","type":"string"},"listings":{"items":{"properties":{"address_text":{"type":["string","null"]},"area_m2":{"type":["number","null"]},"balcony":{"type":"boolean"},"city":{"type":["string","null"]},"cold_rent_eur":{"description":"Kaltmiete per month","type":["number","null"]},"district":{"type":["string","null"]},"fitted_kitchen":{"type":"boolean"},"house_number":{"type":["string","null"]},"id":{"type":"string"},"private_offer":{"description":"Listed by a private landlord rather than an agent","type":"boolean"},"published":{"description":"ISO timestamp","type":["string","null"]},"rooms":{"type":["number","null"]},"street":{"type":["string","null"]},"swap_only":{"description":"Tauschwohnung (title heuristic)","type":"boolean"},"title":{"type":"string"},"url":{"format":"uri","type":"string"},"warm_rent_eur":{"description":"Warmmiete (total rent) per month, when given","type":["number","null"]},"zip":{"type":["string","null"]}},"type":"object"},"type":"array"},"page":{"type":"integer"},"pages":{"type":["integer","null"]},"total":{"description":"All matching listings on ImmoScout24","type":"integer"}},"required":["city","total","page","listings"],"type":"object"},"value":"let $inc = params.include_swap in {city: steps.geo.label, total: steps.search.total, page: params.page, pages: steps.search.pages, listings: steps.search.listings[?$inc || !swap_only]}"},"params":{"additionalProperties":false,"properties":{"city":{"description":"City, e.g. 'Leipzig', 'Köln', 'Hamburg'","maxLength":80,"minLength":2,"type":"string"},"include_swap":{"default":false,"description":"Keep swap-only listings (Tauschwohnung)","type":"boolean"},"max_rent":{"default":100000,"description":"Maximum cold rent (Kaltmiete), EUR/month","minimum":1,"type":"number"},"max_rooms":{"default":99,"minimum":1,"type":"number"},"min_area_m2":{"default":0,"description":"Minimum living space in m²","minimum":0,"type":"number"},"min_rent":{"default":0,"description":"Minimum cold rent (Kaltmiete), EUR/month","minimum":0,"type":"number"},"min_rooms":{"default":0,"minimum":0,"type":"number"},"page":{"default":1,"description":"20 listings per page","maximum":50,"minimum":1,"type":"integer"},"property_type":{"default":"wohnung-mieten","description":"Flat or house for rent","enum":["wohnung-mieten","haus-mieten"],"type":"string"},"sort":{"default":0,"description":"0 = relevance, 2 = newest first, 3 = highest rent first, 4 = lowest rent first","enum":[0,2,3,4],"type":"integer"}},"required":["city"],"type":"object"},"provenance":{"method":"browser-inspect","notes":"spikes/immobilienscout24.md (verified in a real browser: Leipzig ≤800 €, ≥2 rooms → 1,865 hits). AWS WAF Bot Control in front of /Suche: without the browser's aws-waf-token cookie every request gets 401 'Ich bin kein Roboter' (curl, credentials omit). C4's automated browser was also challenged on 2026-11-07, so this recipe is verified only in a human-driven Chrome with the extension. The GAC key is a public frontend constant read from the page (homepage RSC payload NEXT_PUBLIC_GAC_API_KEY, or IS24.resultList.gacApiKey on result pages; regex matched the homepage in-browser). The JSON is a legacy XML-to-JSON mapping: a single hit is an object, not an array (to_array), keys like @id and resultlist.realEstate need quoting. Range values: spike used 800.0 style; integers and wide default bounds are assumed equivalent (unverified).","recorded_at":"2026-11-07T12:06:00+01:00","recorded_by":"C4"},"requires_login":false,"schema":"https://wield.run/schema/recipe/v1.json","site":{"country":"DE","id":"immobilienscout24.de","language":"de","login_url":"https://www.immobilienscout24.de/anmelden","name":"ImmoScout24","origin":"https://www.immobilienscout24.de","origins":["https://www.immobilienscout24.de"]},"steps":[{"description":"City name to ImmoScout24 geopath (e.g. /de/sachsen/leipzig). Needs the public frontend key from the page (X-IS24-GAC).","expect":{"assert":"length(body[?entity.type=='city' && entity.geopath.uri != null]) > `0`","content_type":"json","status":[200]},"extract":{"json":{"geopath":"[?entity.type=='city' && entity.geopath.uri != null] | [0].entity.geopath.uri","label":"[?entity.type=='city' && entity.geopath.uri != null] | [0].entity.label"}},"id":"geo","request":{"headers":{"Accept":"application/json","X-IS24-GAC":"{{vars.gac_key}}"},"method":"GET","query":{"dataset":"nextgen","i":"{{params.city}}","lang":"de","lpt":"5","t":"city"},"url":"/geoautocomplete/v4.0/DEU"}},{"description":"The result-list URL answers JSON (searchResponseModel) when sent Accept: application/json. Ranges are always sent closed (defaults) so no empty '-' values reach the site.","expect":{"assert":"body.searchResponseModel.\"resultlist.resultlist\" != null","content_type":"json","status":[200]},"extract":{"json":{"listings":"to_array(searchResponseModel.\"resultlist.resultlist\".resultlistEntries[0].resultlistEntry || `[]`)[].let $r = \"resultlist.realEstate\" in {id: to_string(\"@id\"), title: $r.title, cold_rent_eur: $r.price.value, warm_rent_eur: $r.calculatedTotalRent.totalRent.value || `null`, rooms: $r.numberOfRooms, area_m2: $r.livingSpace, street: $r.address.street || `null`, house_number: $r.address.houseNumber || `null`, zip: $r.address.postcode || `null`, city: $r.address.city || `null`, district: $r.address.quarter || `null`, address_text: $r.address.description.text || `null`, published: \"@publishDate\" || `null`, private_offer: $r.privateOffer == 'true' || $r.privateOffer == `true`, balcony: $r.balcony == 'true' || $r.balcony == `true`, fitted_kitchen: $r.builtInKitchen == 'true' || $r.builtInKitchen == `true`, swap_only: contains(lower($r.title || ''), 'tausch'), url: join('', ['https://www.immobilienscout24.de/expose/', to_string(\"@id\")])}","pages":"searchResponseModel.\"resultlist.resultlist\".paging.numberOfPages","total":"searchResponseModel.\"resultlist.resultlist\".paging.numberOfHits"}},"id":"search","request":{"headers":{"Accept":"application/json"},"method":"GET","query":{"livingspace":"{{params.min_area_m2}}-100000","numberofrooms":"{{params.min_rooms}}-{{params.max_rooms}}","pagenumber":"{{params.page}}","price":"{{params.min_rent}}-{{params.max_rent}}","pricetype":"rentpermonth","sorting":"{{params.sort}}"},"url":"/Suche{{steps.geo.geopath}}/{{params.property_type}}"}}],"task":"Search rental flats or houses in a German city with rent, rooms and size filters","tos":{"notes":"ImmoScout24's terms forbid automated querying and data collection. One user-initiated search page at a time from the user's own browser (2 requests). Never try to solve or bypass the WAF challenge: if it appears, the user loads the site normally. Listing contact data is not returned.","reviewed":false},"verify":{"checks":["length(output.listings) > `0`","output.city == 'Leipzig'","output.total > `20`","length(output.listings[?cold_rent_eur > `800`]) == `0`","starts_with(output.listings[0].url, 'https://www.immobilienscout24.de/expose/')"],"example_params":{"city":"Leipzig","max_rent":800,"min_rooms":2},"max_ms":6000},"version":1}