I built this actor; it's a paid tool on Apify with a free trial credit.
Portál dražeb (portaldrazeb.cz) is where Czech court executors publish their auctions: flats, family houses, land, cars and more, usually with a minimum bid of two-thirds of the appraised value. It's the largest source of execution auctions in the country, but the site has no export, no RSS and no public data API. If you want to know "which flats in Prague go under the hammer this month and at what discount", you click through a Vue app page by page.
I'm an 18-year-old engineering student, and I built Portál dražeb Scraper to turn the portal into clean JSON. This post shows how to call it, what the data looks like, and one small project: a daily alert for auctions priced well below their appraisal.
How it works, briefly
The listing pages load their data from the site's own JSON endpoint, with a CSRF token issued with the page. The actor loads each list once for a token and cookie, pages through the JSON in blocks of 200, and normalises every auction: prices, the RÚIAN address, region, coordinates, photos and document links. No browser, no login. The full upcoming list (786 auctions when I tested) takes about a minute.
Python example
pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rel8ble/portal-drazeb-scraper").call(run_input={
"listings": ["upcoming"],
"categories": ["flat"],
"locations": ["Praha"],
})
for a in client.dataset(run["defaultDatasetId"]).iterate_items():
print(a["startAt"][:10], a["minimumBid"], a["estimatedPrice"], a["title"], a["url"])
Node example
npm install apify-client
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });
const run = await client.actor("rel8ble/portal-drazeb-scraper").call({
listings: ["upcoming"],
categories: ["vehicles"],
maxPrice: 100000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const a of items) console.log(`${a.title}: from ${a.minimumBid} CZK on ${a.startAt.slice(0, 10)} (${a.city})`);
What comes back
One item per auction. This is a real record from a test run, trimmed:
{
"listing": "upcoming",
"auctionId": "poJ7z",
"auctionNumber": "098EX01347/21-292",
"url": "https://www.portaldrazeb.cz/drazba/098ex01347-21-292-poj7z",
"title": "Byt v Praze - Krč o výměře 76,6 m2",
"categoryEn": "Flat / apartment",
"electronic": true,
"startAt": "2026-10-06T08:00:00.000+00:00",
"currency": "CZK",
"estimatedPrice": 9150000,
"minimumBid": 6100000,
"minimumBidPctOfEstimate": 66.7,
"bidIncrement": 15000,
"cautionDeposit": 1300000,
"region": "Hlavní město Praha",
"city": "Praha",
"address": "Za dvorem 1862/3, Krč, Praha",
"latitude": 50.0183617,
"longitude": 14.4627307,
"images": ["https://www.portaldrazeb.cz/upload/auction-image/32vlN"],
"documents": [
{ "type": "auction_decree", "typeLabel": "Auction decree (dražební vyhláška)", "url": "https://www.portaldrazeb.cz/upload/auction-document/NxZnn" }
]
}
In a run over all 818 upcoming and finished auctions, the region, district and city were filled for 97-98%, GPS for 96% and photos for 81%. The street address was filled for only 34%, because many executors publish only the municipality. For finished auctions, currentPrice is the final price. One flat in Prague's Kamýk district had an appraisal of 8,625,000 CZK, a minimum bid of 5,750,000 and sold for 7,050,000.
A privacy note: the portal's JSON also carries a "responsible person" block, and uploaded document file names sometimes contain the debtor's name. The actor drops both and keeps only the executor office's official contact details.
Use case: a daily alert for deep-discount auctions
The goal: every morning, list flats and houses whose minimum bid is below 70% of the appraisal and that start within the next 30 days, and skip the ones already seen.
import json, pathlib
from datetime import date, timedelta
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
seen_file = pathlib.Path("seen.json")
seen = set(json.loads(seen_file.read_text())) if seen_file.exists() else set()
run = client.actor("rel8ble/portal-drazeb-scraper").call(run_input={
"listings": ["upcoming"],
"categories": ["flat", "house"],
"startFrom": date.today().isoformat(),
"startTo": (date.today() + timedelta(days=30)).isoformat(),
})
new = []
for a in client.dataset(run["defaultDatasetId"]).iterate_items():
pct = a.get("minimumBidPctOfEstimate")
if pct is not None and pct < 70 and a["auctionId"] not in seen:
new.append(a)
seen.add(a["auctionId"])
for a in sorted(new, key=lambda a: a["minimumBidPctOfEstimate"]):
print(f'{a["minimumBidPctOfEstimate"]}% | {a["minimumBid"]:,} CZK | {a["city"]} | {a["title"]} | {a["url"]}')
seen_file.write_text(json.dumps(sorted(seen)))
Most real-estate auctions start at exactly two-thirds of the appraisal: 345 of the 541 I looked at sat at 66.7%, and another 105 were below that. So the 70 threshold catches nearly every first-round auction. Change it to 60 to see only the deeper discounts. Run it with cron or Task Scheduler, or skip the script: set up a Schedule in Apify Console and send the dataset to Slack or Google Sheets through an integration.
What it costs
Pricing is $3.00 per 1,000 results, and one result is one auction saved.
- Every upcoming auction in Czechia (~800) = about $2.40
- The daily alert above (a few dozen matching flats and houses) = a few cents per run
- Filters are applied before saving, so you only pay for matches
Limits
These come straight from my testing:
- Only portaldrazeb.cz. Voluntary and insolvency auctions published on other portals aren't included.
- Descriptions stay in Czech. Categories are translated to English.
- Street address for about a third of auctions; region, city and GPS for nearly all.
- The "finished" list is short. The portal only shows recently ended auctions (32 when I tested), so schedule runs if you want a price history.
- It's slow-ish on the portal side: fetching all ~800 upcoming auctions took about a minute, almost all of it waiting on the site.
If something breaks or a field is wrong, the Issues tab on the actor page reaches me directly.
Portál dražeb Scraper on Apify
This article was drafted with AI and published by me.
Top comments (0)