# Sreality Listings Scraper (`axiomworks/sreality-property-scraper`) Actor

Scrape public Sreality search results for apartments, houses, land, commercial properties or other listings, for sale or rent. Records include titles, layouts, areas, prices, location fields, coordinates and image URLs.

- **URL**: https://apify.com/axiomworks/sreality-property-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Real estate
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.79 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Sreality Property Scraper

**Returns:** one row per Sreality listing with id, title, offerType, layout, areaM2, priceCzk, city and sourceUrl.
**Input:** `{"offerType": "rent", "category": "apartments", "region": "praha", "maxItems": 25, "includeDetails": false}`
**Best for:** rent and price monitoring, property market research, lead lists of agencies and listings.

```json
{
  "id": "1724305484",
  "title": "Pronájem bytu 2+kk 54 m²",
  "offerType": "rent",
  "layout": "2+kk",
  "areaM2": 54,
  "priceCzk": 41800,
  "city": "Praha",
  "sourceUrl": "https://www.sreality.cz/detail/pronajem/byt/2+kk/praha-vinohrady-namesti-jiriho-z-podebrad/1724305484"
}
```

### What does Sreality Property Scraper do?

Sreality Property Scraper collects property listings from Sreality, the Czech property portal. You choose whether you want listings for sale or for rent, pick a category (apartments, houses, land, commercial or other), and optionally narrow the search to a region or city. The Actor then reads the public search result pages and returns one clean record per listing, ready for a spreadsheet, a database or a data pipeline.

Each record contains the listing title, offer type, category, layout or subtype, floor area, plot area, asking price in Czech crowns, price per square metre, the full location breakdown (city, city part, district, region, street), GPS coordinates, the agency that published the ad and the photo URLs. If you switch on detail pages, the Actor also opens every listing and adds the full Czech description, the agency name and a set of building parameters such as condition, construction type and ownership.

The Actor needs no login and no account. It reads only the public pages that anybody can open in a browser. Seller contact details such as phone numbers and personal names are deliberately not collected.

Typical uses include market research on asking prices and rents, scheduled runs to build a price history, feeding a property dashboard or valuation model, and mapping supply from the coordinates of each listing.

This Actor is an independent tool. It is not affiliated with or endorsed by Sreality or its operator.

### What data can you get?

Every record has an `id` and a `sourceUrl`. The table lists all fields. Fields marked "details" are filled only when `includeDetails` is on. The `propertyType` field is filled only when AI enrichment is on and succeeded.

| Field | Type | Description |
|---|---|---|
| `id` | string | Sreality listing identifier, unique within a run |
| `sourceUrl` | string | Detail page URL of the listing |
| `title` | string | Listing title as shown on the site, in Czech |
| `offerType` | string | `sale` or `rent` |
| `category` | string | `apartments`, `houses`, `land`, `commercial` or `other` |
| `layout` | string | Layout such as `2+kk`, or the subtype such as `Rodinný` or `Pole` |
| `areaM2` | number | Area in square metres, taken from the listing title |
| `plotAreaM2` | number | Plot area in square metres for houses and land |
| `priceCzk` | number | Asking price in CZK; monthly rent for rentals; empty when the price is on request |
| `priceUnit` | string | What the price covers, for example `za měsíc` or `za nemovitost` |
| `pricePerM2Czk` | number | Price per square metre in CZK as given by the site |
| `city` | string | City or municipality |
| `cityPart` | string | City part or neighbourhood |
| `district` | string | District |
| `region` | string | Region (kraj) |
| `street` | string | Street name when the listing shows one |
| `latitude` | number | Latitude of the listing |
| `longitude` | number | Longitude of the listing |
| `agencyId` | number | Agency identifier |
| `agencySlug` | string | Agency URL slug |
| `agencyName` | string | Agency name (details) |
| `imageUrls` | array | Photo URLs of the listing |
| `hasVideo` | boolean | Whether the listing has a video |
| `description` | string | Full listing description in Czech (details) |
| `previousPriceCzk` | number | Earlier price when the listing shows a price drop (details) |
| `matterportUrl` | string | 3D tour link when present (details) |
| `listedSince` | string | Date the listing was first published (details) |
| `lastEdited` | string | Date the listing was last edited (details) |
| `agencyRating` | number | Agency review score on Sreality (details) |
| `agencyWebsite` | string | Agency website (details) |
| `buildingParams` | object | Selected building parameters such as condition, construction type, ownership, floor and elevator (details) |
| `propertyType` | string | AI estimate: `investment`, `family`, `starter`, `luxury` or `other` |

Some fields are empty for some listings because the listing itself does not provide them. Street names, for example, are often hidden for houses in villages, and some agencies do not publish a price. A price shown as "price on request" is returned as empty rather than as a placeholder number.

### How to use

1. Open the Actor in Apify Console and go to the Input tab.
2. Pick the offer type (sale or rent) and the category.
3. Optionally type a region or city slug. The slug is the last part of a Sreality search address, for example `praha` or `jihomoravsky-kraj`.
4. Set `maxItems` to the number of listings you need.
5. Press Start. Results appear in the Output tab as soon as the first page has been read, and you can download them as JSON, CSV, Excel or XML.

If you already have a Sreality search address that includes the filters you want, paste it into Start URLs instead. The Actor then follows that search and ignores the offer type, category and region fields. You can also supply `/detail/` listing addresses. These targets always include available detail fields. Filters apply to search targets, not individual listings.

Large result sets are best split by region. Sreality limits how deep a single search can page, so running one search per region gives you more complete coverage than one national search.

The Actor is polite to the site: it keeps to about one request per second with low concurrency, and it retries temporary failures with a growing delay. A run of 50 listings without detail pages takes a few seconds. With detail pages every listing needs one extra request, so the run is slower.

#### New in this version

- Price filters `minPrice` and `maxPrice` narrow generated searches and `/hledani/` start URLs. A start URL that already contains its own `cena-od` or `cena-do` keeps those values.

Start URLs may also be single `/detail/` listing URLs. Each is fetched with full details and saved as one record. Detail records fill `previousPriceCzk`, `matterportUrl`, `listedSince`, `lastEdited`, `agencyRating` and `agencyWebsite` when the listing shows them; otherwise these stay empty.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | none | Optional search URLs (`/hledani/`), listing URLs (`/detail/`) as URL objects. Overrides offer type, category and region |
| `offerType` | string | `sale` | `sale` or `rent` |
| `category` | string | `apartments` | `apartments`, `houses`, `land`, `commercial` or `other` |
| `region` | string | empty | Region or city slug, for example `praha` |
| `minPrice` | integer | 0 | Minimum price in CZK (monthly rent or sale price); 0 means no minimum |
| `maxPrice` | integer | 0 | Maximum price in CZK; 0 means no maximum |
| `maxItems` | integer | 50 | Shared maximum unique listings across all targets, 1 to 10000 |
| `includeDetails` | boolean | false | Open each detail page for description, agency name and building parameters |
| `enableAiEnrichment` | boolean | true | Add the `propertyType` estimate |
| `proxyConfiguration` | object | no proxy | Apify Proxy settings |

Example input:

```json
{
  "offerType": "rent",
  "category": "apartments",
  "region": "praha",
  "maxItems": 25,
  "includeDetails": false
}
```

Example input with a search address:

```json
{
  "startUrls": [{ "url": "https://www.sreality.cz/hledani/prodej/domy/jihomoravsky-kraj" }],
  "maxItems": 25
}
```

If a search returns no records, check the region URL slug, widen the price range, or try a known public search URL. For an unavailable listing, replace its detail URL. If requests remain blocked, select an available Apify Proxy group or try later. Empty and blocked targets do not produce placeholder records and end successfully with an explanation.

The `maxItems` limit is shared across all targets and exact: a run with `maxItems` set to 7 returns exactly 7 listings when at least 7 exist, and only those 7 are billed.

### Output

Each run writes one dataset item per listing. Here is a shortened real item from a run with the first example input:

```json
{
  "id": "1724305484",
  "sourceUrl": "https://www.sreality.cz/detail/pronajem/byt/2+kk/praha-vinohrady-namesti-jiriho-z-podebrad/1724305484",
  "title": "Pronájem bytu 2+kk 54 m²",
  "offerType": "rent",
  "category": "apartments",
  "layout": "2+kk",
  "areaM2": 54,
  "plotAreaM2": null,
  "priceCzk": 41800,
  "priceUnit": "za měsíc",
  "pricePerM2Czk": 774,
  "city": "Praha",
  "cityPart": "Vinohrady",
  "district": "Praha 3",
  "region": "Hlavní město Praha",
  "street": "náměstí Jiřího z Poděbrad",
  "latitude": 50.078582,
  "longitude": 14.449973,
  "agencyId": 20262,
  "agencySlug": "prime-property",
  "agencyName": null,
  "imageUrls": ["https://d18-a.sdn.cz/d_18/c_img_qE_A/nO573v8MsNBK7ALGmsHbP2a4/3c99.jpeg"],
  "hasVideo": false,
  "description": null,
  "buildingParams": null,
  "previousPriceCzk": null,
  "matterportUrl": null,
  "listedSince": null,
  "lastEdited": null,
  "agencyRating": null,
  "agencyWebsite": null,
  "propertyType": null
}
```

With `includeDetails` on, `agencyName`, `description` and `buildingParams` are filled, for example `{"buildingCondition": "Velmi dobrý", "buildingType": "Cihlová", "floors": 1, "furnished": "Ano"}`. Explicit boolean values are preserved: `"balcony": false` means the source reports no balcony; an absent key means the source did not supply a usable value. A numeric `floorNumber` of zero is preserved, while zero-valued area placeholders and unselected enum options are omitted. The data is returned in Czech, exactly as published, so titles, descriptions and condition names are not translated.

### How much does it cost?

The Actor is charged per result: each listing saved to the dataset counts as one result. When AI enrichment is on and succeeds for a listing, that listing also counts as an enriched result. If enrichment fails or is switched off, no enrichment charge applies. See the Pricing tab of the Actor for the current rates, which can change over time. Setting a low `maxItems` is the simplest way to control the cost of a run, and a run stops as soon as that many listings have been saved.

### Use with AI agents (MCP)

You can call this Actor from any MCP-compatible AI assistant through the Apify MCP server. Add it to your client configuration like this:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=axiomworks/sreality-property-scraper"
    }
  }
}
```

Example prompts:

1. "Find 30 apartments for rent in Prague on Sreality and list the cheapest ones per square metre."
2. "Get houses for sale in the South Moravian region and group them by district."
3. "Collect 20 commercial listings for rent in Praha with descriptions and agency names."

The input field descriptions are written so that an agent can choose the right values without extra help.

### Integrations and API

You can run the Actor from code and read the results through the Apify API.

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("axiomworks/sreality-property-scraper").call(
    run_input={"offerType": "sale", "category": "apartments", "region": "praha", "maxItems": 50}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["priceCzk"])
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('axiomworks/sreality-property-scraper').call({
    offerType: 'rent',
    category: 'houses',
    region: 'jihomoravsky-kraj',
    maxItems: 30,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
process.stdout.write(`${items.length} items\n`);
```

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~sreality-property-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"offerType":"sale","category":"land","maxItems":20}'
```

You can also schedule runs, send results to Google Sheets, Slack or a webhook, or connect the Actor to automation tools using the integrations built into the platform.

### FAQ

**How many listings can I get in one run?**
Up to 10000 per run, limited by what the search returns. Sreality caps how deep one search can page, so for complete coverage run one search per region.

**Why are some prices empty?**
Some listings are published as "price on request". The Actor returns an empty price for them instead of a placeholder.

**Why is the area missing for some listings?**
The area is read from the listing title. If the title does not state an area, the field is empty.

**Do I need a proxy?**
Usually not. Requests go direct by default. If the site blocks a request or answers it with an error, the Actor retries on a fresh Apify Proxy session, first datacenter and then residential, and uses the successful route for later pages in the same run. You can also pick a proxy group in the input to always use one.

**Is the text translated?**
No. Titles, descriptions and parameter names are in Czech, as published.

**Does the Actor collect seller phone numbers or names?**
No. Seller contact details are personal data and are not collected. The record contains only the agency identifier, slug and, with detail pages, the agency name.

**What does the AI enrichment do?**
It adds a `propertyType` estimate based on layout, area, price and description. Enrichment uses a third-party AI processor. You can switch it off with `enableAiEnrichment`.

**What happens with a wrong region or a dead URL?**
The run finishes quickly with zero results and a warning in the log. No placeholder items are written.

### Is it legal to scrape Sreality?

The Actor reads publicly available listing pages without logging in and without bypassing any protection. Property listing data is generally public information, but you are responsible for how you use it. Check the site's terms of use and the rules that apply to you, including database rights and data protection law such as the GDPR. Do not use the data to contact private individuals in ways the law does not allow. This Actor does not collect seller contact details. If you are unsure about your use case, ask a lawyer.

### Feedback

If a field is missing, a region does not work or the site layout changes, open an issue on the Actor page in Apify Console and describe the input you used. Reports with an example run link are the quickest to fix.

# Actor input Schema

## `startUrls` (type: `array`):

Sreality URL objects, e.g. \[{"url":"https://www.sreality.cz/hledani/pronajem/byty/praha"}]. Accepts /hledani/ searches and /detail/ listings. Overrides offerType, category and region. Empty or omitted uses filters. Listing URLs always fetch details. maxItems is shared across targets.

## `offerType` (type: `string`):

Offer type for generated searches: "sale" or "rent", e.g. "rent" for monthly rentals. Default "sale". Ignored when startUrls contains targets.

## `category` (type: `string`):

Category for generated searches: apartments, houses, land, commercial or other, e.g. "houses". Default "apartments". Ignored when startUrls contains targets.

## `region` (type: `string`):

Region or city slug from a Sreality search URL, e.g. "praha" or "jihomoravsky-kraj". Empty or omitted searches the Czech Republic. Use a URL slug rather than a display name. Ignored when startUrls contains targets.

## `minPrice` (type: `integer`):

Minimum asking price in CZK, e.g. 15000 for monthly rent. Nonnegative integer; default 0 means no minimum. Applies to search URLs, not individual listings. An existing cena-od URL parameter takes precedence.

## `maxPrice` (type: `integer`):

Maximum asking price in CZK, e.g. 25000 for monthly rent. Nonnegative integer; default 0 means no maximum. Applies to search URLs, not individual listings. An existing cena-do URL parameter takes precedence.

## `maxItems` (type: `integer`):

Total unique listings to save across all targets, e.g. 25. 1-10000, default 50. Returns fewer when targets have fewer listings or cannot be fetched; empty or blocked targets return no records. Stops once the shared limit is reached.

## `includeDetails` (type: `boolean`):

Whether to fetch detail pages for search results, e.g. true for description, agencyName and buildingParams. Default false; adds one request per listing when enabled. Individual listing URLs always fetch details even when false. Missing detail fields remain null.

## `enableAiEnrichment` (type: `boolean`):

Whether to classify propertyType using a third-party AI processor, e.g. false for source data only. Default true. Labels: investment, family, starter, luxury or other. propertyType stays null if enrichment is disabled, unavailable or fails.

## `proxyConfiguration` (type: `object`):

Apify Proxy options, e.g. {"useApifyProxy":true}. Default {"useApifyProxy":false} starts direct. Blocked requests retry through datacenter then residential routes when available on Apify, with fresh sessions. For persistent blocks, choose an available proxy group or try later.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.sreality.cz/hledani/pronajem/byty/praha"
    }
  ],
  "offerType": "rent",
  "category": "apartments",
  "region": "praha",
  "minPrice": 0,
  "maxPrice": 0,
  "maxItems": 25,
  "includeDetails": false,
  "enableAiEnrichment": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

One record per property listing.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.sreality.cz/hledani/pronajem/byty/praha"
        }
    ],
    "offerType": "rent",
    "category": "apartments",
    "region": "praha",
    "maxItems": 25,
    "includeDetails": false,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/sreality-property-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.sreality.cz/hledani/pronajem/byty/praha" }],
    "offerType": "rent",
    "category": "apartments",
    "region": "praha",
    "maxItems": 25,
    "includeDetails": False,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/sreality-property-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.sreality.cz/hledani/pronajem/byty/praha"
    }
  ],
  "offerType": "rent",
  "category": "apartments",
  "region": "praha",
  "maxItems": 25,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/sreality-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/sreality-property-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/NtH2AlZdkvPOXInhd/builds/haCKlOkmZEFqYPTah/openapi.json
