# 4zida.rs Scraper - Serbia Property Listings & Prices (`sian.agency/4zida-property-scraper`) Actor

Scrape 4zida.rs: sale and rental listings across Serbia with price, area, rooms, floor, year built, agency and phone. Serbian-language property data from the country's #1 portal.

- **URL**: https://apify.com/sian.agency/4zida-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.76 / 1,000 property searches

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 4zida.rs Scraper - Serbia Property Listings & Prices 🚀

[![Store SIÁN Agency](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Store Njuškalo Scraper](https://img.shields.io/badge/Store-Nju%C5%A1kalo%20Scraper-1AE392)](https://apify.com/sian.agency/njuskalo-property-scraper?fpr=sian) [![Store Sreality Scraper](https://img.shields.io/badge/Store-Sreality%20Scraper-1AE392)](https://apify.com/sian.agency/sreality-property-scraper?fpr=sian) [![Store Otodom Scraper](https://img.shields.io/badge/Store-Otodom%20Scraper-1AE392)](https://apify.com/sian.agency/otodom-property-scraper?fpr=sian)

#### 🎉 Every 4zida.rs listing, in Serbian, with the seller type already labelled

##### For analysts pricing the Serbian market, agencies sourcing stock, and anyone tired of scrolling Beograd by hand

### 🔎 What is the 4zida.rs Serbia Property Scraper — and when should you use it?

The **4zida.rs Serbia Property Scraper** turns public 4zida.rs property listings from anywhere in Serbia into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** Serbian sale and rental adverts as rows: asking price or monthly rent in euros, area, rooms, floor and building height, heating, registration, condition, publish and refresh dates, photos, the agency behind the advert and its page on the portal. Every row also names the seller type (agency, owner, company or developer), so an export splits by who is selling after the fact. Switch on full details and each row additionally carries the seller's own advert text, the complete photo set, coordinates, year built, deposit, price per square metre and the agency's phone number.

**Use something else when:** the property is not in Serbia. Use [Njuškalo Scraper](https://apify.com/sian.agency/njuskalo-property-scraper?fpr=sian) for Croatia's biggest classifieds site, with the same sale-and-rent row shape. Use [Sreality Scraper](https://apify.com/sian.agency/sreality-property-scraper?fpr=sian) for the Czech market leader, including price per square metre and agency contacts. Use [Otodom Scraper](https://apify.com/sian.agency/otodom-property-scraper?fpr=sian) for Poland, sale and rent, from the country's dominant portal. This actor covers the property surfaces 4zida.rs publishes on its main portal: apartments, houses, commercial premises, lots and garages/parking, each for sale or for rent. It reads what the portal serves to a visitor; the portal's finance calculators, blog and agency-directory pages are not part of it, and sold-price history is not published by 4zida.rs at all.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/4zida-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want property listings and asking prices from 4zida.rs using the Apify Actor `sian.agency/4zida-property-scraper`.

Use it when I need: Serbian sale and rental adverts as rows: asking price or monthly rent in euros, area, rooms, floor and building height, heating, registration, condition, publish and refresh dates, photos, the agency behind the advert and its page on the portal. Every row also names the seller type (agency, owner, company or developer), so an export splits by who is selling after the fact. Switch on full details and each row additionally carries the seller's own advert text, the complete photo set, coordinates, year built, deposit, price per square metre and the agency's phone number.

Don't use it when: the property is not in Serbia — use njuskalo-property-scraper or sreality-property-scraper or otodom-property-scraper instead.

How to call it: give `locations` a list of Serbian places (`beograd`, `novi-sad`, `nis`; the picker lists the cities and towns of 4zida's own place index) and set `dealType` to `prodaja` for sale or `izdavanje` for rent. Add `unitTypes` to pick apartments, houses, commercial premises, lots or garages/parking; leaving it empty reads apartments, the portal's default surface. Narrow with `minPrice`, `maxPrice`, `minArea` or `maxArea`; the bounds go to the portal's own filter parameters, and anything a filter excludes is never saved and never billed. `sellerType` keeps only agencies, owners, companies or developers, and every row carries the seller type it came from. `includeDetails` opens each advert for its full text, photo set, coordinates and phone, for an extra charge per listing. To expand adverts you already have, set `operation` to `detail` and pass `listingUrls`; to reach a micro-location the picker does not list (a blok, a street), paste its 4zida.rs address into `searchUrls`.

Start with this input:
{
  "operation": "search",
  "dealType": "prodaja",
  "locations": [
    "beograd"
  ],
  "unitTypes": [
    "stanovi"
  ],
  "maxResults": 200
}

Ask me which Serbian places to cover, whether they want sale or rental listings, and whether the full advert text, photo set and agency phone are worth the extra per-listing charge, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull apartments for sale in Novi Sad between €100,000 and €200,000 and rank neighbourhoods by median price per square metre.*
- *Find owner-listed rentals in Belgrade under €600 a month, with a phone number for each.*
- *Give me this week's new listings in Niš and Kragujevac with the agency name and portal page.*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/4zida-property-scraper.md](https://apify.com/sian.agency/4zida-property-scraper.md).

### 📋 Overview

**4zida.rs is where Serbia's property market actually happens.** Serbia's most-visited dedicated property portal (1.25 million visits a month, three times its nearest dedicated rival) carries around 75,000 active adverts from agencies, developers and private sellers, and publishes its own quarterly price reports for the four biggest cities. This Actor reads it the way the site publishes it and hands you the rows.

**Why professionals choose us:**

- ✅ **The record, not a teaser**: price, area, rooms, floor, total floors, heating, registration, condition, seller type, publish date and photo count on every row
- ⚡ **20-26 listings per request**: a 500-listing sweep of Novi Sad is about 20 requests and finishes in under a minute
- 🇷🇸 **Serbian that survives the trip**: place names, layouts and agency names arrive with their diacritics intact (Bačka Palanka, not Backa Palanka), because the Actor reads the structured data the portal embeds rather than scraping pixels
- 🤝 **Seller typing on every row**: agency, owner, company or developer, so an export splits by who is selling as well as by where
- 📄 **Full details as a paid add-on**: the seller's own text, every photo, coordinates, year built and the agency's phone
- 💰 **$2.00 per 1,000 listings**: matched to the field leader's price, with a row that carries what neither rival exposes

### ✨ Features

- 🔍 **Two operations in one Actor**: search 4zida.rs's listing pages, or expand specific adverts by URL
- 🇷🇸 **Every place 4zida indexes**: Serbia's cities and towns picked from a list built off the portal's own place index, not typed and hoped for
- 🏠 **All five property surfaces**: apartments, houses, commercial premises, lots and garages/parking
- 🤝 **Sale and rent in the same Actor**: one bill, one dataset, one schedule
- 🏷️ **Seller type as data**: every row states whether an agency, owner, company or developer advertises it
- 🎚️ **Filters that reach the portal**: price and area bounds ride 4zida's own filter parameters, so a narrow band costs nothing but time
- 📄 **Full details as a paid add-on**: advert text, the complete photo set, coordinates, year built, deposit, price per square metre and the agency phone
- 🔗 **Paste a URL instead**: any 4zida.rs search address works, including the micro-location pages the form cannot name (a blok in Novi Beograd, a street, a gradska lokacija)
- 🕒 **Market timestamps**: publish date, last-activated date and the portal's own last-checked date on every row, which is what a new-listing diff needs

### 🎬 Quick Start

Pick a place, pick sale or rent, press Start. The defaults return Beograd sale apartments, so a run with no configuration at all still gives you real data. Everything below is optional narrowing.

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~4zida-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"search","dealType":"prodaja","locations":["beograd"],"maxResults":100}'
```

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose your places

Pick one or more Serbian places from the list. For a micro-location the list cannot name (a blok, a street, a gradska lokacija), open its page on 4zida.rs and paste the address into Search URLs.

#### Step 2: Choose sale or rent, and the property types

Leave the property-type list empty to read apartments, or pick the surfaces you care about. Each type is searched separately, the same way a site visitor would open them one by one.

#### Step 3: Press Start, then export

Watch the run log count the pages. When it finishes, download JSON, CSV or Excel from the dataset, or open the HTML report for a summary with the advert links already collected.

**That's it! In under a minute, you'll have:**

- Every matching listing with price, area, rooms, floor, heating and seller type
- Publish and refresh timestamps for new-listing tracking
- A copy-ready list of advert links and, with full details on, contact numbers

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `operation` | string | No | `search` (default) or `detail` |
| `locations` | array | No | Serbian places, e.g. `beograd`, `novi-sad`; defaults to Beograd |
| `dealType` | string | No | `prodaja` for sale (default) or `izdavanje` for rent |
| `unitTypes` | array | No | Apartments, houses, commercial premises, lots, garages/parking; empty means apartments |
| `sellerType` | string | No | `vlasnik`, `agencija`, `firma` or `investitor`; empty means everyone |
| `maxResults` | integer | No | Whole-run listing budget, default 100 |
| `includeDetails` | boolean | No | Open each advert for the full text, all photos, coordinates and the phone |
| `minPrice` / `maxPrice` | integer | No | Price bounds in euros; 0 means no bound |
| `minArea` / `maxArea` | integer | No | Area bounds in square metres; 0 means no bound |
| `searchUrls` | array | No | 4zida.rs search addresses, including micro-location pages |
| `listingUrls` | array | No | 4zida.rs advert addresses, for the `detail` operation |

**Example:**

```json
{
  "operation": "search",
  "dealType": "prodaja",
  "locations": ["novi-sad"],
  "minPrice": 100000,
  "maxPrice": 200000,
  "maxResults": 500
}
```

**Owner-listed rentals under €600 across two cities:**

```json
{
  "operation": "search",
  "dealType": "izdavanje",
  "locations": ["beograd", "novi-sad"],
  "sellerType": "vlasnik",
  "maxPrice": 600,
  "maxResults": 300
}
```

**Expand specific adverts:**

```json
{
  "operation": "detail",
  "listingUrls": [
    { "url": "https://www.4zida.rs/prodaja-stanova/novo-naselje-gradske-lokacije-novi-sad/dvoiposoban-stan/6a96b4940e849d4f120358d2" }
  ]
}
```

### 📤 Output

Results are saved to the Apify dataset with **45+ fields**, including:

| Field | Type | Description |
|-------|------|-------------|
| `listingId` | string | 4zida's advert id |
| `url` | string | Canonical advert address |
| `titleText` | string | The card's location name, as 4zida shows it |
| `structureLabel` | string | The layout, in Serbian (Dvoiposoban stan, …) |
| `dealType` | string | `sale` or `rent` |
| `propertyType` | string | `apartment`, `house`, `newHouse`, … as the portal types it |
| `price` | number | Asking price, or monthly rent for a rental |
| `priceCurrency` | string | Reported, never assumed |
| `pricePerM2Eur` | number | The portal's own figure (with full details on) |
| `areaM2` / `rooms` | number | Size and room count |
| `floor` / `totalFloors` | number | Floor number and floors in the building |
| `registered` | string | Whether the property is registered (uknjiženo) |
| `heatingType` / `state` | string | Heating and condition, as the portal states them |
| `hasElevator` / `hasTerrace` | boolean | Present only where the portal publishes them |
| `sellerType` | string | `agencija`, `vlasnik`, `firma` or `investitor` |
| `agencyName` / `agencyUrl` | string | The agency and its page on 4zida.rs |
| `createdAt` / `lastActivatedAt` / `lastCheckedAt` | string | Publish, reactivation and portal-check dates |
| `descriptionText` | string | The seller's full advert text (`includeDetails`) |
| `latitude` / `longitude` | number | Coordinates (`includeDetails`) |
| `phone` | string | The number printed on the advert (`includeDetails`) |
| `galleryUrls` / `photoCount` | array, number | Photos and how many there are |

**Example:**

```json
{
  "listingId": "6a96b4940e849d4f120358d2",
  "url": "https://www.4zida.rs/prodaja-stanova/novo-naselje-gradske-lokacije-novi-sad/dvoiposoban-stan/6a96b4940e849d4f120358d2",
  "titleText": "Novo Naselje",
  "structureLabel": "Dvoiposoban stan",
  "dealType": "sale",
  "propertyType": "apartment",
  "price": 197200,
  "priceCurrency": "EUR",
  "areaM2": 58,
  "rooms": 2.5,
  "floor": 6,
  "totalFloors": 7,
  "registered": "yes",
  "heatingType": "district",
  "sellerType": "agencija",
  "agencyName": "Level Property",
  "agencyUrl": "https://www.4zida.rs/agencije/novi-sad/level-property-doo/288758",
  "createdAt": "2026-09-01T11:18:44.000Z",
  "photoCount": 18,
  "locationPath": "Novo Naselje › Gradske lokacije › Novi Sad"
}
```

### 💼 Use Cases & Examples

#### 1. Serbian asking-price index

**A property analyst measuring what a city really asks per square metre.**

**Input:** one or more places, apartments, a high `maxResults`
**Output:** every listing with price, area and the portal's own refreshed dates
**Use:** group by neighbourhood and build the index that 4zida's quarterly city report only samples

#### 2. Rental yield screening

**An investor comparing what a flat costs against what it rents for.**

**Input:** two runs on the same place, one `prodaja` and one `izdavanje`
**Output:** sale and rental rows sharing area, room count and location path
**Use:** match on area and location for a gross-yield picture no single 4zida page shows

#### 3. Agency stock and market-share mapping

**An agency or a proptech vendor mapping who holds the stock in a city.**

**Input:** a place, full details switched on
**Output:** every advert with its agency name and the agency's own page on the portal
**Use:** group by agency, rank by listing count, and approach the ones that dominate your patch

#### 4. Owner-listed sourcing

**An investor who wants the sellers no agency has signed yet.**

**Input:** `sellerType: "vlasnik"`, one or more places
**Output:** only adverts with no agency behind them, each with the owner's phone where the portal shows it
**Use:** the listings that never reach an agency feed, which is why Serbians scroll 4zida by hand

#### 5. New-build developer tracking

**A buyer or fund watching what developers bring to market.**

**Input:** `sellerType: "investitor"` on a daily schedule, with your saved places
**Output:** the units developers are advertising, with publish timestamps and photo counts
**Use:** keep the ids you have seen, pay only for what appeared since yesterday

#### 6. New-listing monitoring

**A relocation service or a buying agent who needs to see today's stock today.**

**Input:** saved places on a schedule, sale or rent
**Output:** only what is live, each row carrying its publish date
**Use:** the publish timestamp makes the diff a simple set operation

#### 7. Commercial and land sourcing

**A business buyer looking for premises or a plot with the right size and price.**

**Input:** `unitTypes: ["poslovni-prostora", "placeva"]` with price and area bounds
**Output:** the stock by surface type with the portal's own layout labels
**Use:** shortlist before anyone drives out to look

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/4zida-property-scraper').call({
  operation: 'search',
  dealType: 'prodaja',
  locations: ['novi-sad'],
  unitTypes: ['stanovi'],
  maxResults: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/4zida-property-scraper').call(
    run_input={
        'operation': 'search',
        'dealType': 'izdavanje',
        'locations': ['beograd'],
        'maxResults': 200,
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['titleText'], item['price'], item['sellerType'])
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~4zida-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"search","dealType":"izdavanje","locations":["nis"],"sellerType":"vlasnik"}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: a daily schedule, or a webhook from your own system
2. **HTTP Request**: call the Actor's run-sync endpoint with your saved input
3. **Process**: filter the returned rows on price, area or seller type
4. **Action**: append to a sheet, upsert into your CRM, or send the new listings to Slack

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run, with every field and every filter available
- No credit card required
- Enough to check the data before you commit to a sweep

#### PAID Tier (Production Ready)

- **Unlimited** listings per run, bounded only by the row budget you set
- Pay-per-result: charged per listing saved, never for a listing your filters excluded
- Full details available as a per-listing add-on, only when you switch it on

💰 **$2.00 per 1,000 listings**, level with the leading 4zida.rs Actor on the Store: floor, heating, registration, seller type and the publish timestamps sit on the same row.

🔗 [View current pricing](https://apify.com/sian.agency/4zida-property-scraper?fpr=sian)

### ❓ Frequently Asked Questions

**Q: How many listings can I get per run?**
A: FREE tier: 25 per run. PAID tier: as many as you budget for. Beograd apartments alone cover roughly eleven thousand listings, so for national-scale work split the run by place, by property type or by price band.

**Q: Will the Serbian text come through correctly?**
A: Yes. The Actor reads the structured data 4zida.rs embeds in its own pages, so place names, layouts and agencies arrive with their diacritics intact (Bačka Palanka, not Backa Palanka) in JSON, CSV and Excel alike.

**Q: Are rental prices per month?**
A: Yes. 4zida.rs publishes rentals in euros per month and the rows carry them as-is; sale prices are the full asking price. The currency field on each row states which.

**Q: What is the difference between a listing row and full details?**
A: A listing row carries everything on the search card: price, area, rooms, floor, heating, registration, seller type, the agency and a photo. Full details opens the advert itself and adds the seller's text, the complete photo set, coordinates, year built, deposit, price per square metre and the phone.

**Q: Can I search a single neighbourhood?**
A: Yes, through Search URLs. Open the neighbourhood page on 4zida.rs and paste the address (a blok in Novi Beograd, a street, a gradska lokacija). The form covers cities and towns; a pasted address reaches anything the portal publishes.

**Q: What happens if I type a place the portal does not know?**
A: 4zida.rs quietly answers with its whole-country search, which would mislabel every row. This Actor checks every place against the portal's own place index before the run starts and flags an unknown one as an input error instead, and you are never charged for it.

**Q: What happens to an advert that has been withdrawn?**
A: The portal answers a dead advert with a not-found page. The Actor writes a row saying the listing could not be found and does not charge you for it.

**Q: What output formats are available?**
A: JSON, CSV, Excel and XML. Export straight from the Apify dataset, or read them over the API.

**Q: Is this legal?**
A: Yes. Only publicly available adverts are read. See the legal note below.

### 🐛 Troubleshooting

**A run returns fewer listings than the place has adverts**

- The row budget is a whole-run ceiling; raise `maxResults` to read more
- Filters exclude listings whose price or area the portal does not publish, so a tight bound on a thin market can empty the result
- Each place × property-type combination is its own search with its own budget; name more of them to widen the sweep

**A filter returned nothing**

- Price bounds are in euros on both sale and rental rows
- Nothing filtered out is charged, so an empty run costs you the run-start fee and nothing else

**A listing URL comes back as not found**

- The advert has been sold, rented or withdrawn; re-run the search to pick up what is live today
- A bare advert id cannot be resolved (4zida.rs has no address for one), so paste the full advert URL, which every search row carries

**Serbian characters look wrong in Excel**

- Open the CSV with UTF-8 encoding selected, or use the XLSX export, which carries the encoding itself
- The JSON export is always UTF-8 and needs no configuration

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

4zida and 4zida.rs are trademarks of Inspira grupa d.o.o. This Actor is not affiliated with, endorsed by, or sponsored by 4zida or Inspira grupa.

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue on the [Actor's issues page](https://apify.com/sian.agency/4zida-property-scraper/issues)
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

Pick one per run. Property Search walks 4zida.rs's own listing pages for any place the portal indexes (apartments, houses, offices, lots or garages, sale or rental) and returns 20-26 listings per page with price, area, rooms, floor, heating, registration, agency and the publish date. Property Detail takes 4zida listing URLs and returns the full advert: seller's description, complete photo set, coordinates, year built, deposit and the agency's phone number.

## `locations` (type: `array`):

Where to search, one place per line. Serbia's cities and towns resolve by name in Serbian Latin (Beograd, Novi Sad, Niš, Kragujevac, Subotica) or by the exact 4zida place address in the URL (beograd, novi-sad). Leave empty to read all of Serbia. For a city micro-location the form cannot name (a blok, a street, a gradska lokacija), paste the 4zida search address into Search URLs instead.

## `dealType` (type: `string`):

For-sale listings (prodaja) or rentals (izdavanje). Rental prices come back in euros per month exactly as 4zida publishes them.

## `unitTypes` (type: `array`):

Which kinds of property to read. Leave empty to take apartments only, 4zida's default surface. The values are 4zida's own property-type paths, so the list is exactly what the site offers: apartments, houses, commercial premises, lots and garages/parking. One place combined with several types runs one search per type, the way a site visitor would open them one by one.

## `sellerType` (type: `string`):

Keep only listings advertised by one kind of seller, one of the same four categories 4zida's own seller filter offers. Empty means everyone. Every row also carries the seller type it came from, so you can split the export later instead of re-running.

## `maxResults` (type: `integer`):

Stop after this many results across the whole run, not per place. One page carries 20-26 results, so a run ends on the first page that crosses your limit.

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

Open each listing's own page as well and fold in what it adds: the seller's description, the complete photo set, coordinates, year built, deposit, price per m² and the agency's phone. One extra request and one extra charge per listing.

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

Keep only results priced at or above this, in euros. 0 means no lower bound. On rentals this is the monthly rent. Applied by 4zida's own price filter, so a narrow band costs you nothing but time.

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

Keep only results priced at or below this, in euros. 0 means no upper bound.

## `minArea` (type: `integer`):

Keep only properties of at least this many square metres. 0 means no minimum.

## `maxArea` (type: `integer`):

Keep only properties of at most this many square metres. 0 means no maximum.

## `searchUrls` (type: `array`):

Paste 4zida search addresses instead of filling the form, e.g. https://www.4zida.rs/prodaja-stanova/novi-sad or a filtered one like https://www.4zida.rs/izdavanje-stanova/beograd/vlasnik?jeftinije\_od=600eur. Build the search on 4zida.rs, copy the address bar, and the place, property type, seller type and filters in it are read straight off the URL. A page number in the address is ignored; the run starts at page one and pages forward on its own.

## `listingUrls` (type: `array`):

For Property Detail: paste the 4zida advert addresses, e.g. https://www.4zida.rs/prodaja-stanova/novo-naselje-gradske-lokacije-novi-sad/dvoiposoban-stan/6a96b4940e849d4f120358d2. Every URL a Property Search returns works here as-is.

## Actor input object example

```json
{
  "operation": "search",
  "locations": [
    "beograd"
  ],
  "dealType": "prodaja",
  "unitTypes": [],
  "sellerType": "",
  "maxResults": 100,
  "includeDetails": false,
  "minPrice": 0,
  "maxPrice": 0,
  "minArea": 0,
  "maxArea": 0,
  "searchUrls": [],
  "listingUrls": []
}
```

# Actor output Schema

## `4zidaRsResults` (type: `string`):

Every property listing this run returned.

## `scrapingSummary` (type: `string`):

HTML summary showing successful and failed results with key metrics

# 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 = {
    "operation": "search",
    "locations": [
        "beograd"
    ],
    "dealType": "prodaja",
    "unitTypes": [],
    "sellerType": "",
    "maxResults": 100,
    "includeDetails": false,
    "minPrice": 0,
    "maxPrice": 0,
    "minArea": 0,
    "maxArea": 0,
    "searchUrls": [],
    "listingUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/4zida-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 = {
    "operation": "search",
    "locations": ["beograd"],
    "dealType": "prodaja",
    "unitTypes": [],
    "sellerType": "",
    "maxResults": 100,
    "includeDetails": False,
    "minPrice": 0,
    "maxPrice": 0,
    "minArea": 0,
    "maxArea": 0,
    "searchUrls": [],
    "listingUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/4zida-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 '{
  "operation": "search",
  "locations": [
    "beograd"
  ],
  "dealType": "prodaja",
  "unitTypes": [],
  "sellerType": "",
  "maxResults": 100,
  "includeDetails": false,
  "minPrice": 0,
  "maxPrice": 0,
  "minArea": 0,
  "maxArea": 0,
  "searchUrls": [],
  "listingUrls": []
}' |
apify call sian.agency/4zida-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/4zida-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/sXEcaNtEi64JadSh4/builds/lAZc1ibnnVxeKim2x/openapi.json
