Europe Distressed Property Scraper - Foreclosures & Auctions
Pricing
from $1.80 / 1,000 distressed property records
Europe Distressed Property Scraper - Foreclosures & Auctions
Distressed-property leads across Europe: German ZVG foreclosure auctions, Polish KRZ restructuring proceedings, and Spanish BOE judicial auctions in one run, with detail enrichment, resume, and incremental change tracking.
Pricing
from $1.80 / 1,000 distressed property records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Europe Distressed Property Scraper
Distressed-property and insolvency leads across Europe in one run: German foreclosure auctions (ZVG), Polish restructuring proceedings (KRZ), and Spanish judicial auctions (BOE). Pick one country or combine lanes in a single run, enrich each record from its detail page, and track what changed between scheduled runs.
Why This Scraper?
- Three registers, one actor. Walk the German ZVG foreclosure auction portal, the Polish KRZ restructuring register, and the Spanish BOE judicial auction portal. Each lane keeps its own native filters, and every record comes back normalized to one schema.
- Detail enrichment built in. Every record can be opened on its source page for the full description, case numbers, parties, valuations, auction dates, and attached documents (appraisals, official announcements, photos).
- Made for recurring monitoring. Resume an interrupted run from its ID, or let incremental mode remember what you already scraped and return only NEW and UPDATED records, with EXPIRED markers when a record leaves the source.
- Search the way each register wants. German state, city and auction-date windows; Polish entity, identifier and case-signature lookups; Spanish auction status and deadline ranges. Or just paste links and let URL mode sort them out.
- Honest by design. If a register refuses every request the run fails loudly instead of returning an empty dataset that looks like "no results". A genuine empty search says so.
Use Cases
- Who: Investors and buyers hunting below-market property across EU foreclosure and judicial-auction channels.
- Who: Restructuring and insolvency professionals tracking proceedings by company name or identifier in Poland.
- Who: Lead-generation teams feeding distressed-property signals into CRM systems and alerting pipelines on a schedule.
- Who: Analysts comparing distressed inventory levels across European markets from one dataset.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
recordId | "es:boe:SUB-JA-2026-000000" |
country | "de", "pl" or "es" |
source | "zvg", "krz" or "boe" |
title | "Apartment (1 to 2 rooms): Musterstraße 1, 12345 Musterstadt" |
distressType | "foreclosure_auction", "restructuring_proceeding", "judicial_auction" |
caseNumber | "0123 O 0045/2026" |
auctionDate | "2026-11-03T09:30:00" |
deadlineAt | "2026-11-20" |
location.address / location.city / location.region | "Musterstraße 1, 12345 Musterstadt" / "Musterstadt" / "BE" (the property, not the court) |
valueAmount / valueCurrency | 250000 / "EUR" |
status | "scheduled", "zakończone", "Celebrándose" |
parties | [{ "role": "authority", "name": "Sample Court" }] |
attachments | [{ "label": "Gutachten1.pdf", "url": "..." }] |
description | full detail description (when enrichment is on) |
details | per-source detail block (valuation, lot data, register data) |
court / stateName / objectType / propertyType | German rows: the Amtsgericht (filled from the record page when fetchDetails is on, or from the court filter; otherwise null, never the state name), state name, object type as listed (with room counts) and property type (the category only, e.g. Eigentumswohnung); the auction kind is in details.artDerVersteigerung |
area / pricePerSqm | German rows: area and price per square metre (when the listing states an area) |
daysUntilAuction / isNewSinceLastRun | days until the auction; new-since-last-run flag (incremental runs) |
changeType / changedFields / firstSeenAt / lastSeenAt | incremental-mode metadata |
url | source record URL |
How to Use
- Pick a Mode:
search(default) walks the country lanes with your filters;urlreads only the links you paste. Pasted links are ignored in search mode, and the run log says so. - In search mode, pick your country lanes (Germany, Poland, Spain) and set each lane's filters (German state/city/dates, Polish entity name or identifier, Spanish auction status and date windows). In url mode, paste register links.
- Set Max items and whether to fetch detail pages, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
German foreclosure auctions:
{"mode": "search","country": ["de"],"deLand": "be","deCity": "Berlin","deSort": "2","fetchDetails": true,"maxItems": 50}
Polish restructuring proceedings by entity:
{"mode": "search","country": ["pl"],"plEntityName": "Sample Company Name","plIdentifier": "0000000000","maxItems": 20}
Spanish judicial auctions by deadline window:
{"mode": "search","country": ["es"],"esAuctionStatus": "EJ","esDeadlineFrom": "2026-10-01","esDeadlineTo": "2026-12-31","maxItems": 100}
Paste links from any supported register (url mode):
{"mode": "url","urls": ["https://www.zvg-portal.de/index.php?button=showZvg&zvg_id=14429&land_abk=be","https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2026-263220&ver=1"],"fetchDetails": true}
Prefer to paste links? URL mode reads German foreclosure record pages and Spanish auction pages; each auction gives one record. Behaviour change: in url mode, leaving the URLs field untouched now scrapes the two example links below instead of nothing. Pasting several tabs of the same Spanish auction returns that auction once.
| Link shape | Example | Result |
|---|---|---|
| German record page (showZvg) | https://www.zvg-portal.de/index.php?button=showZvg&zvg_id=14429&land_abk=be | one record (a session is opened for you first) |
| Spanish auction, general data (ver=1) | https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2026-263220&ver=1 | one record |
| Spanish auction, other tab (ver=2) or lots tab (ver=3) | ...detalleSubasta.php?idSub=SUB-JA-2026-263220&ver=3 | same record as ver=1, returned once |
| Spanish auction without ver | https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2026-263220 | one record |
| Spanish auction under the /reg/ path | https://subastas.boe.es/reg/detalleSubasta.php?idSub=SUB-JA-2026-263220 | one record |
| German search form page | https://www.zvg-portal.de/index.php?button=Termine%20suchen | skipped with a warning; use search mode |
| Spanish search form page | https://subastas.boe.es/subastas_ava.php | skipped with a warning; use search mode |
| Polish register home | https://krz.ms.gov.pl/ | skipped with a warning; it has no per-record link, use search mode |
When a German court or place filter matches no listing, the run log says so and names the state(s) searched. A court name that matches no court of the state is reported instead of silently returning the whole state. City names with umlauts match in any spelling (Köln, Koeln).
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("abotapi/distressed-eu-scraper").call(run_input={"country": ["de"],"deLand": "be","deCity": "Berlin","fetchDetails": True,"maxItems": 50,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["recordId"], item["title"], item.get("valueAmount"))
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('abotapi/distressed-eu-scraper').call({country: ['es'],esAuctionStatus: 'EJ',fetchDetails: true,maxItems: 50,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const item of items) console.log(item.recordId, item.title);
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run ID and the actor skips everything already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same scope. Each record is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on) orEXPIRED(only after a run that scanned the whole scope, and only withemitExpired). UsestateKeyto share one baseline across slightly different filter variants, andignoreFieldsForChangesto exclude noisy fields from the comparison. The two features are mutually exclusive; pick one per run.
Send results into your apps (MCP connectors)
Optionally send a summary of each returned record into an app connected through Apify MCP integrations. Select one or more MCP connectors and, for Notion, provide the parent page URL or ID. The actor creates a Notion page per record; other connectors receive a best-effort write or digest. Exports are capped by Max items to export per connector (50 by default), and connector failures do not change dataset output.
| Field | What it does |
|---|---|
mcpConnectors | Selected MCP connectors (empty = no export). |
notionParentPageUrl | Notion parent page URL or ID; required for Notion exports. |
maxNotifyListings | Maximum records sent to each selected connector (default 50, maximum 1000). |
Input Parameters
All parameters are optional unless noted. Each country lane uses only its own filters.
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search walks the country lanes with your filters; url reads only the pasted links. |
country | array | ["de"] | Country lanes to walk, in order: de, pl, es. Search mode only. |
deLand | string | be | German state code (required for the ZVG search): bw, by, be, bb, hb, hh, he, mv, ni, nw, rp, sl, sn, st, sh, th. |
deLands | array | (none) | Several German states in one run (codes, or all for all 16). Replaces deLand when set; deLand keeps working. |
deCourt | string | (none) | One Amtsgericht of the selected state, by the town the portal lists (for example Charlottenburg, München). |
deObjectType | string | (none) | German object-type filter. |
deStreet | string | (none) | German street filter. |
dePostalCode | string | (none) | German postal code filter. |
deCity | string | (none) | German city filter; matches the town in the address (not the street); umlaut spellings (Köln, Koeln) both match. |
deAuctionType | string | (none) | German auction-type selector. |
deAuctionDateFrom | string | (none) | Only auctions on/after this date (YYYY-MM-DD). |
deAuctionDateTo | string | (none) | Only auctions on/before this date (YYYY-MM-DD). |
deSort | string | 2 | Sort: 2 auction date, 1 last update, 3 case number. |
plEntityName | string | (none) | Polish entity name to search in the restructuring register. |
plIdentifier | string | (none) | KRS/NIP/PESEL identifier to combine with the name. |
plCaseSignature | string | (none) | Exact case signature (sygnatura). |
plSoleTraderName | string | (none) | Sole-trader business name (JDG). |
plFirstName | string | (none) | Natural-person first name (with plLastName). |
plLastName | string | (none) | Natural-person last name (with plFirstName). |
esAuctionStatus | string | EJ | Spanish auction lifecycle: EJ, PU, SU, CA, FS, or empty for all. |
esDeadlineFrom | string | (none) | Spanish conclusion date on/after (YYYY-MM-DD). |
esDeadlineTo | string | (none) | Spanish conclusion date on/before (YYYY-MM-DD). |
esStartFrom | string | (none) | Spanish start date on/after (YYYY-MM-DD). |
esStartTo | string | (none) | Spanish start date on/before (YYYY-MM-DD). |
urls | array | one German record and one Spanish auction example | Pasted record links: a German foreclosure record page or a Spanish auction page. Read in url mode only. |
fetchDetails | boolean | true | Open each record's detail page for the full field set. |
maxItems | integer | 50 | Total result cap across all lanes (0 = no limit; the German register alone holds thousands of auctions, so set a number you are happy to pay for). |
maxPages | integer | 0 | Page cap per search walk; 0 = until natural end. |
proxy | object | standard pool | Connection settings. Poland uses its own premium connection automatically. |
resumeFromRunId | string | (none) | Continue a previous run; only unpushed records are saved. |
incrementalMode | boolean | false | Track changes across scheduled runs; only NEW/UPDATED returned. Mutually exclusive with resumeFromRunId. |
stateKey | string | (none) | Named incremental baseline; derived from the scope when empty. |
emitUnchanged | boolean | false | Also return UNCHANGED records in incremental mode. |
emitExpired | boolean | false | Also return EXPIRED records in incremental mode. |
ignoreFieldsForChanges | array | (none) | Extra fields that never count as a change. |
mcpConnectors | array | (none) | Optional MCP connectors to receive returned record summaries after the run. |
notionParentPageUrl | string | (none) | Parent page URL or ID required for Notion page creation. |
maxNotifyListings | integer | 50 | Maximum records sent to each connector (1-1000). |
Output Example
The Output tab offers three tables: Overview (one row per record, including court, state, object type, area and days until the auction), Detail-enriched (runs with detail fetching on) and Changes (change type, changed fields, first and last seen, for incremental runs). A run summary record is also stored in the key-value store.
Sample shape: values are illustrative placeholders, not from a live record.
Example record (Spain, detail-enriched):
{"recordId": "es:boe:SUB-JA-2026-000000","country": "es","source": "boe","title": "Sample commercial unit, ground floor, Sampletown","distressType": "judicial_auction","caseNumber": "0000 0000 00 0000 00","proceedingId": "SUB-JA-2026-000000","publishedAt": "2026-09-01","deadlineAt": "2026-10-11","location": { "address": "Calle Muestra 1", "city": "Sampletown", "region": "Sample", "country": "es" },"valueAmount": 125887.5,"valueCurrency": "EUR","status": "Celebrándose","parties": [{ "role": "authority", "name": "Sample Court" }],"description": "Sample auction description.","attachments": [{ "label": "Documento 1", "url": "https://subastas.boe.es/verDocumento.php?..."}],"url": "https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2026-000000","raw": {}}
Plan Requirement
Germany (ZVG) and Spain (BOE) start on the standard connection and do not require residential access. No connection tier has been measured as required for them, and the actor does not claim it works without any action on every plan: it escalates to the platform's residential connection only when the standard one is refused, and it also needs proxy access on your account. Poland (KRZ) sits behind a protection layer that blocks plain requests, so it is read through a browser session on the platform's residential connection (Polish exit); this lane is the least predictable of the three.
What you will see in the run log when a connection is not available:
- Warning: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable."
- Info: "Served over the backup connection (the default connection was unavailable)."
- Failure, proxy refused: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required."
- Failure, residential unavailable: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested ... pages."
- Failure, no page loaded: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."
If you enter your own proxy URLs, they are used as given.
FAQ
How much does it cost?
You pay per record returned (the apify-default-dataset-item event), and records whose detail page was fetched also bill the detail-enrichment event, once per record. Records not returned (for example unchanged ones in incremental mode) are not billed. There are no monthly fees; check the Pricing tab for the current per-event prices.
Is it legal to scrape these registers?
These are public registers: German foreclosure auctions are published under the ZVG statute, the Polish restructuring register is a public government service, and Spanish judicial auctions are published by the official state gazette. The actor reads the same pages a browser would, at a polite pace, and links every record back to its official source.
Can I get only new or changed records on a schedule?
Yes. Use incremental mode: the actor remembers its baseline per scope and returns only what changed (NEW, UPDATED), with optional EXPIRED markers for records that left the source. Use stateKey to share one baseline across slightly different filter variants.
Why does a run return fewer records than I expected?
Max items (50 by default) stops the run once the cap is reached, walking the selected country lanes in order; raise it or set it to 0 to collect everything. Narrow filter combinations (a single German city, an exact Polish case signature) can also simply match few records; clear a filter to widen the search.
What does each country return?
Germany: every foreclosure auction the register lists for the chosen state, with the property address, appraised value, auction date and attached documents (appraisal, announcement). German rows also carry court, state name, object type, auction type, area, price per square metre (when the listing states an area) and days until the auction; incremental mode adds an is-new flag (the equivalent of a new-auctions-only switch). Hamburg and Mecklenburg-Vorpommern currently list no auctions (an empty state is reported as an empty result, not as a connection problem). Spain: judicial and tax-office auctions with value, deadline, authority and lot details; the "all statuses" choice is too wide for the portal, so pick one status. Poland: insolvency and restructuring proceedings of companies and sole traders found by name or identifier. These are signals about the owner, not a property list, and only entities whose name contains your search words are returned.
How current are the German and Spanish lists?
Both registers are read live on every run, so you see what is published that day. Dates are the portal's own: the auction date for Germany and the closing date of bidding for Spain.
Why did my run fail instead of returning an empty dataset?
One of the registers refused every request in that run, or no proxy access was available (see Plan Requirement for the exact messages). The run is failed loudly rather than returning an empty dataset that would look like "no results". Wait and rerun.
Can I use it with AI agents or MCP?
Yes, the run output is a clean JSON dataset that works with MCP connectors and any AI workflow. Use the mcpConnectors input to send results straight into your apps after each run.
🔗 Want more Distressed data?
Pair this actor with these related scrapers from the same team:
| 🧩 Distressed Property Scraper Find mortgagee-sale and distressed-property listings in Australia and New Zealand. NZ... | 🏠 Canada Distressed Property Scraper Canadian tax-sale properties from taxsales.ca: tender and auction listings across 9... |
| 🧩 Spain Property & Judicial Auctions Scraper Scrape Spain's official BOE auction portal: judicial and public auction listings with... | 📇 GoWork Scraper Extract company profiles from GoWork France and Germany, including contact details... |
| 🏠 Auction.com Scraper Extract foreclosure, REO, short-sale, and auction listings from Auction.com in minutes... | 🧩 Propwire Scraper Scrape Propwire.com: 157M+ US MLS & off-market properties with owner names, mailing... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.