# Zonaprop Property Listings Scraper (`scrapers-hub/zonaprop-property-listings-scraper`) Actor

Zonaprop Property Listings Scraper extracts Argentinian real-estate listings - posting ID, title, price and operation type, expenses, antiquity, main and general features, publisher, property type, units and description. 🏠 For market analysis.

- **URL**: https://apify.com/scrapers-hub/zonaprop-property-listings-scraper.md
- **Developed by:** [Scrapers Hub](https://apify.com/scrapers-hub) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

### 🏘️ Zonaprop Property Listings Scraper – Extract Argentine Real Estate Listings, Prices & Agency Data

The **Zonaprop Property Listings Scraper** extracts structured real estate data from Zonaprop, Argentina's largest property portal, turning search result pages into a clean dataset of postings. Each record carries the posting identifier, title, price and operation type, expenses, property features, location, publisher agency, photos, WhatsApp contact and modification date — everything you need for property market analysis, comparative pricing research, lead generation or an internal listings feed.

Point this Zonaprop scraper at a search results URL — apartments for sale in Buenos Aires, houses for rent in Córdoba, or any filtered query you build on the site — and pagination is followed automatically until your per-URL item cap is reached. Because the output preserves Zonaprop's own structured objects for features, location and publisher rather than flattening them into strings, you keep the granularity needed for serious real estate data analysis.

***

### 📊 What Data Can You Extract with This Zonaprop Scraper?

Every posting becomes one dataset item. The table below groups the real output fields into the categories property analysts actually work with.

| Category | Fields | What it gives you |
|---|---|---|
| 🆔 Listing identity | `posting_id`, `posting_code`, `url`, `from_url`, `posting_type`, `status` | Zonaprop's own posting ID and agency reference code, the listing URL, the start URL it was found from, the posting type and its current status. |
| 💰 Pricing & costs | `price_operation_types`, `expenses` | Price entries broken down by operation type (Venta, Alquiler and so on) plus the monthly expensas object with amount, currency and formatted value. |
| 🏠 Property characteristics | `main_features`, `general_features`, `development_features`, `real_estate_type`, `antiquity`, `house_info`, `units` | Structured feature objects covering room counts, surface areas, layout, amenities, the property type classification, building age and unit breakdowns. |
| 📍 Location | `posting_location` | The full location object for the posting — the geographic context behind every price comparison. |
| 📝 Description & media | `title`, `description_normalized`, `visible_pictures` | The listing headline, the normalised long-form description text, and the visible photo set. |
| 🏢 Publisher & contact | `publisher`, `url_logo`, `whatsapp` | The listing agency or agent object with name and profile URL, their logo, and the WhatsApp contact where published. |
| ⭐ Promotion & ranking | `premier`, `highlighted_features`, `flags_features`, `slot`, `slot_color` | Whether the listing is a premium placement, plus highlight badges and slot metadata that reveal how the portal ranks and promotes it. |
| 📅 Freshness | `publication`, `modified_date` | Publication metadata and the date the posting was last modified. |

The sleeper field here is **`expenses`**. Argentine listings quote a headline price, but monthly *expensas* can materially change the true cost of occupying a property — and they are returned as a structured object with `amount`, `currency` and `formatted_amount`, so you can add them into total-cost-of-ownership models rather than parsing them out of description text.

***

### 🌟 Key Features of the Zonaprop Property Listings Scraper

| Feature | Description |
|---|---|
| 🔎 Search-URL driven | Paste any Zonaprop search results URL — filtered by city, neighbourhood, price band, property type or operation — and the scraper collects the postings it returns. |
| 📄 Automatic pagination | Pagination is followed automatically from each start URL, so you do not need to enumerate page numbers yourself. |
| 🎚️ Per-URL item cap | `maxItemsPerUrl` bounds how many postings are collected from each start URL, defaulting to 30, giving you precise control over run size. |
| 🔁 Configurable retries | `maxRetriesPerUrl` sets how many times a failed page request is retried before the scraper gives up, defaulting to 2. |
| 🧯 Failure tolerance | With `ignoreUrlFailures` enabled by default, one bad start URL does not abort the run — the remaining URLs are still processed. |
| 🧱 Structured feature objects | `main_features`, `general_features` and `development_features` are returned as objects keyed by Zonaprop's own feature IDs, preserving labels, values and units of measure. |
| 🏢 Agency attribution | The `publisher` object identifies the listing agency or agent with their ID, name and portal URL, enabling agency-level market share analysis. |
| 🌐 Automatic proxy rotation | Proxy rotation is handled for you during the run — there is nothing to configure. |
| 💳 Pay-per-event billing | The actor uses pay-per-event pricing. Check the Pricing tab on the Apify Store listing for current rates. |

***

### 🚀 Why Choose This Zonaprop Property Listings Scraper?

**Real structured features, not scraped strings.** Property portals bury the details that matter — surface area, room count, layout, orientation — inside inconsistent markup. This Zonaprop scraper returns `main_features` and its siblings as objects that keep the feature ID, human label, value and unit of measure together. That means you can compute price per square metre across thousands of listings without writing a parser for every phrasing variant.

**Total cost, not just headline price.** `price_operation_types` gives you the price broken out by operation type, and `expenses` gives you the monthly expensas as a structured amount with its currency. Together they let you model what a property actually costs, which is the number that drives real purchase and rental decisions in the Argentine market.

**Runs that survive bad inputs.** `ignoreUrlFailures` defaults to true and `maxRetriesPerUrl` defaults to 2, so a transient failure on one search URL is retried and then, if it still fails, skipped rather than taking the whole run down. For scheduled market monitoring across dozens of searches, that resilience is the difference between a dataset and an empty run.

**Agency and promotion intelligence built in.** Alongside the property data you get `publisher`, `premier`, `highlighted_features` and `flags_features`. That combination tells you not only what is on the market but who is listing it and how hard they are paying to promote it — a competitive signal most property datasets simply do not carry.

***

### 📥 Input

The Zonaprop scraper takes a list of start URLs plus three run-control settings.

```json
{
  "urls": [
    "https://www.zonaprop.com.ar/departamentos-venta.html"
  ],
  "maxItemsPerUrl": 30,
  "maxRetriesPerUrl": 2,
  "ignoreUrlFailures": true
}
```

#### 🔧 Zonaprop Scraper Input Fields

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `urls` | array of strings | ✅ Yes | prefilled with `["https://www.zonaprop.com.ar/departamentos-venta.html"]` | Zonaprop listing URLs to scrape, for example a search results page. Pagination is followed automatically. |
| `maxItemsPerUrl` | integer | ❌ No | `30` | Maximum number of postings to collect per start URL. |
| `maxRetriesPerUrl` | integer | ❌ No | `2` | How many times to retry a failed page request before giving up. |
| `ignoreUrlFailures` | boolean | ❌ No | `true` | If a start URL fails, continue with the remaining URLs instead of aborting the run. |

#### 💡 Input Examples

**Apartments for sale, default settings**

```json
{
  "urls": ["https://www.zonaprop.com.ar/departamentos-venta.html"]
}
```

**Several searches with a deeper crawl per URL**

```json
{
  "urls": [
    "https://www.zonaprop.com.ar/departamentos-venta.html",
    "https://www.zonaprop.com.ar/casas-alquiler.html",
    "https://www.zonaprop.com.ar/oficinas-venta.html"
  ],
  "maxItemsPerUrl": 200,
  "maxRetriesPerUrl": 3
}
```

**Strict mode — abort if any start URL fails**

```json
{
  "urls": ["https://www.zonaprop.com.ar/departamentos-venta.html"],
  "maxItemsPerUrl": 50,
  "ignoreUrlFailures": false
}
```

***

### 📤 Output

Each posting produces one dataset item. The record below is a real result from an actual run, trimmed to the most useful keys.

```json
{
  "posting_id": "59284192",
  "url": "/propiedades/clasificado/veclapin-departamento-en-venta.-2-ambientes.-san-telmo.-super-59284192.html",
  "posting_code": "KP518776",
  "title": "Departamento en Venta. 2 Ambientes. San Telmo. Súper Luminoso. Cocina Comedor.",
  "price_operation_types": "[{\"low_price_percentage\": null, \"operation_type\": {\"name\": \"Venta\", \"operation_type_id\": \"1\"}, \"pric…",
  "expenses": {
    "currency_id": null,
    "amount": 130000,
    "formatted_amount": "130.000",
    "currency": "$"
  },
  "main_features": "{\"1000019\": {\"feature_id\": \"1000019\", \"label\": \"Disposición\", \"measure\": null, \"value\": \"Interno\"…",
  "real_estate_type": {
    "name": "Departamentos",
    "real_estate_type_id": "2"
  },
  "publisher": "{\"publisher_id\": \"17061204\", \"name\": \"MKS Propiedades\", \"url\": \"/inmobiliarias/mks-propiedades_17061…",
  "premier": true,
  "description_normalized": "Departamento de 2 ambientes en venta, ubicado sobre la calle Bolívar al 1400, entre Av. Garay y Av.…",
  "general_features": {},
  "highlighted_features": [],
  "units": []
}
```

#### 🧾 Zonaprop Property Listing Output Fields

| Field | Type | Description |
|---|---|---|
| `posting_id` | string | null | Zonaprop's identifier for the posting. |
| `url` | string | null | Canonical URL of the scraped posting. |
| `posting_code` | string | null | Agency reference code for the posting. |
| `title` | string | null | Listing headline. |
| `price_operation_types` | array | null | Price entries by operation type, such as Venta or Alquiler. |
| `expenses` | object | null | Monthly expensas with amount, currency and formatted amount. |
| `main_features` | object | null | Core property features keyed by Zonaprop feature ID, each with label, value and measure. |
| `general_features` | object | null | General features and amenities of the property. |
| `development_features` | object | null | Features relating to the development or building. |
| `highlighted_features` | array | null | Highlighted feature badges shown on the listing. |
| `flags_features` | array | null | Flag-style feature markers attached to the posting. |
| `antiquity` | — | Antiquity, or age, of the property. |
| `publisher` | object | null | The publishing agency or agent, with ID, name and portal URL. |
| `url_logo` | — | URL of the publisher's logo. |
| `real_estate_type` | object | null | Property type classification with name and type ID. |
| `units` | array | null | Individual units associated with the posting. |
| `publication` | object | null | Publication metadata for the posting. |
| `premier` | boolean | null | Whether the posting holds a premium placement. |
| `slot` | — | Slot assignment for the posting. |
| `slot_color` | — | Slot colour used in the portal's display. |
| `house_info` | — | Additional house-level information. |
| `description_normalized` | string | null | Normalised long-form description text. |
| `posting_location` | object | null | Location object for the posting. |
| `visible_pictures` | object | null | Visible photo set for the posting. |
| `status` | string | null | Current status of the posting. |
| `posting_type` | string | null | Type of the posting. |
| `whatsapp` | string | null | WhatsApp contact published with the listing. |
| `modified_date` | string | null | Date the posting was last modified. |
| `from_url` | string | null | The start URL this posting was discovered from. |

Several fields — `antiquity`, `url_logo`, `slot`, `slot_color`, `house_info` — are frequently null because Zonaprop only populates them for certain listing types. The `url` field is returned as a site-relative path, so prefix it with `https://www.zonaprop.com.ar` to build an absolute link.

***

### 💻 How to Use the Zonaprop Property Listings Scraper (Step by Step)

#### Step 1: Build Your Zonaprop Search URLs

Go to Zonaprop and construct the search you actually care about using the site's own filters — operation type, property type, province, neighbourhood, price range, number of rooms. When the results page shows what you want, copy the URL from the address bar. This is the single most important step: the filters baked into that URL determine exactly which postings the Zonaprop scraper will collect, so a precise search saves you filtering thousands of irrelevant records later.

#### Step 2: Enter the URLs in the Input Tab

Open the actor in the Apify Console and go to the **Input** tab. Paste your search URLs into the **Start URLs** string list, one per line. The field is prefilled with a sample apartments-for-sale search you can replace. You can mix operations and property types freely in one run — each posting records its originating `from_url`, so you can always attribute results back to the search that produced them.

#### Step 3: Set Your Per-URL Item Limit

**Max items per URL** defaults to 30, which is deliberately conservative — enough to verify the output shape without committing to a large run. For genuine market analysis, raise it substantially. Remember the limit applies per start URL, so five URLs at 200 items each yields up to a thousand postings.

#### Step 4: Tune Retries and Failure Handling

**Max retries per request** defaults to 2, which handles the ordinary transient failures any large crawl encounters. **Ignore URL failures** defaults to true, meaning a start URL that fails outright is skipped and the run continues. Set it to false only when you need strict guarantees that every submitted search was covered — for scheduled monitoring, leaving it true is almost always the right call.

#### Step 5: Run the Zonaprop Scraper

Click **Start**. The log shows pagination progress per start URL as the scraper works through search result pages, followed by the postings it collects. Proxy rotation is applied automatically during the run, so there is nothing to configure on that front. Watch for the point at which each URL hits its item cap — that confirms the limit, rather than a failure, ended collection for that search.

#### Step 6: Inspect and Validate the Dataset

Open **Storage → Dataset** when the run completes. Check `posting_id` for duplicates first, since overlapping searches can surface the same property more than once. Then spot-check `expenses` and `price_operation_types` on a few rows against the live listing to confirm the numbers line up, and confirm `real_estate_type` matches the property type you filtered for.

#### Step 7: Export and Analyse the Property Data

Export as JSON, CSV, Excel, XML or HTML. JSON is strongly recommended here: `main_features`, `expenses`, `publisher`, `posting_location` and `visible_pictures` are nested objects, and flat formats will stringify them. For recurring market tracking, attach an Apify schedule and use `modified_date` together with `posting_id` to detect new listings, price changes and withdrawn properties between runs.

***

### 🔌 API Access & Integrations

Run the Zonaprop property listings scraper from the Apify API and get dataset items back in the same call.

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers-hub~zonaprop-property-listings-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://www.zonaprop.com.ar/departamentos-venta.html"],
    "maxItemsPerUrl": 50,
    "maxRetriesPerUrl": 2,
    "ignoreUrlFailures": true
  }'
```

The same run from Python with the official client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")

run_input = {
    "urls": [
        "https://www.zonaprop.com.ar/departamentos-venta.html",
        "https://www.zonaprop.com.ar/casas-alquiler.html",
    ],
    "maxItemsPerUrl": 100,
    "maxRetriesPerUrl": 3,
    "ignoreUrlFailures": True,
}

run = client.actor("scrapers-hub/zonaprop-property-listings-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    expenses = item.get("expenses") or {}
    print(item.get("posting_id"), item.get("title"))
    print("  type:", (item.get("real_estate_type") or {}).get("name"))
    print("  expensas:", expenses.get("formatted_amount"), expenses.get("currency"))
    print("  url: https://www.zonaprop.com.ar" + (item.get("url") or ""))
```

The actor also connects to Zapier, Make, Google Sheets, Slack and generic HTTP webhooks, so fresh Zonaprop listings can flow into a CRM, a pricing dashboard, a shared spreadsheet or a team alert channel without custom integration work.

***

### 💡 Best Use Cases for Zonaprop Property Data

#### 📈 Real Estate Market Price Analysis

Combine `price_operation_types` with the surface-area entries inside `main_features` to compute price per square metre across neighbourhoods, then segment by `real_estate_type` to compare apartments against houses and offices. Adding the `expenses` amount produces a total monthly cost figure that reflects what occupants actually pay — a materially different ranking from headline price alone.

#### 🏢 Agency Market Share and Competitor Tracking

The `publisher` object names the listing agency for every posting. Aggregating postings by publisher across a city reveals which agencies dominate which neighbourhoods, how their inventory mix breaks down by `real_estate_type`, and — via the `premier` flag — which competitors are paying for premium placement rather than relying on organic visibility.

#### 🎯 Property Lead Generation and Outreach

For brokers and proptech services, `publisher`, `whatsapp` and `posting_code` together form a workable contact record tied to a specific listing. Filtering by `real_estate_type` and location lets you build targeted outreach lists of agencies active in exactly the segment you serve, with the listing reference already attached to each conversation.

#### 🔍 Investment Screening and Yield Modelling

Run parallel searches for sale and rental listings in the same neighbourhood, then compare `price_operation_types` across the two datasets to estimate gross rental yields. Subtracting `expenses` from the rental side sharpens the net yield estimate, and `antiquity` plus `development_features` help you flag buildings likely to carry higher maintenance risk.

#### 📊 Inventory and Absorption Rate Monitoring

Scheduling the Zonaprop scraper against a fixed set of searches and tracking `posting_id` between runs shows you exactly which listings entered the market and which disappeared. That churn, read alongside `modified_date`, is the raw material for absorption rate and days-on-market metrics that no single snapshot can give you.

#### 💸 Price Change and Repricing Detection

Because `posting_id` is stable and `modified_date` records the last change, comparing consecutive runs surfaces listings that have been repriced. Sellers who cut prices are motivated sellers, and a dataset of recent reductions in a target neighbourhood is one of the most directly actionable outputs of ongoing property data extraction.

#### 🗺️ Neighbourhood and Location Intelligence

The `posting_location` object supplies the geographic context for every posting, letting you aggregate pricing, inventory volume and property mix by area. Joining that with `visible_pictures` counts and `description_normalized` text gives a fuller picture of listing quality by neighbourhood — useful for valuation models and for deciding where to focus acquisition effort.

***

### ⚙️ Tips for Better Zonaprop Scraping Results

- **Filter on the site, not afterwards.** Build precise search URLs using Zonaprop's own filters before scraping. Narrowing by neighbourhood, price band and property type in the URL is far more efficient than collecting everything and filtering the dataset later.
- **Raise `maxItemsPerUrl` deliberately.** The default of 30 is a verification sample. Market analysis needs hundreds of postings per search to be meaningful, and the cap applies per URL, so multiply carefully when you submit many searches.
- **Keep `ignoreUrlFailures` true for scheduled runs.** For recurring monitoring, tolerating one failed search is much better than losing an entire run's data.
- **Prefix `url` values before use.** The `url` field is a site-relative path. Prepend `https://www.zonaprop.com.ar` to produce clickable links in your exports and dashboards.
- **Export as JSON when features matter.** `main_features`, `expenses`, `publisher`, `posting_location` and `visible_pictures` are nested objects. CSV and Excel exports stringify them, so use JSON if you intend to parse those structures.
- **Deduplicate on `posting_id`.** Overlapping searches frequently return the same property. The posting ID is the stable key for merging runs and for detecting new versus recurring listings over time.
- **Split large jobs across scheduled runs.** Several moderate runs are easier to retry, cheaper to debug and less likely to time out than one very large crawl.

***

### 🛠️ Troubleshooting

**The run stopped at 30 items per URL.**
That is the `maxItemsPerUrl` default doing its job. Raise it to the number of postings you actually need per search. Remember the limit is per start URL, not per run.

**One of my start URLs returned nothing.**
Open the URL in a browser and confirm it still produces results — Zonaprop search URLs change when the site's filter parameters are updated, and an outdated URL can return an empty result set. Because `ignoreUrlFailures` defaults to true, a failing URL is skipped silently, so check the log to identify which one dropped out.

**Fields like `antiquity`, `slot` and `house_info` are always null.**
Zonaprop only populates these for certain listing categories. Null means the portal published no value for that posting, not that extraction failed. Build your analysis around the fields that are consistently present for your property type.

**`main_features` and `publisher` look like strings in my CSV export.**
Nested objects cannot be represented in flat file formats, so they are stringified during CSV and Excel export. Export as JSON to keep the structure, or parse the stringified values back into objects after import.

**The `url` values do not open in my browser.**
They are site-relative paths rather than absolute URLs. Prefix them with `https://www.zonaprop.com.ar` and they will resolve correctly.

**Some pages failed even after retries.**
Increase `maxRetriesPerUrl` above the default of 2 and reduce the number of start URLs per run. Proxy rotation is applied automatically, but very aggressive crawls of a single search still meet more resistance than moderate ones spread across scheduled runs.

***

### ❓ Frequently Asked Questions About Zonaprop Scraping

**What does the Zonaprop Property Listings Scraper extract?**
It extracts property postings from Zonaprop search result pages, returning the posting ID and code, title, price by operation type, expensas, structured property features, location, publisher agency, photos, WhatsApp contact, status and modification date.

**What input does the Zonaprop scraper need?**
One required field, `urls` — an array of Zonaprop listing or search URLs. You can also set `maxItemsPerUrl`, `maxRetriesPerUrl` and `ignoreUrlFailures`.

**Does it follow pagination automatically?**
Yes. Pagination is followed automatically from each start URL until the per-URL item cap is reached, so you do not need to enumerate page numbers.

**How many listings does it collect by default?**
`maxItemsPerUrl` defaults to 30 postings per start URL. Increase it for larger datasets.

**Can I scrape both sale and rental listings in one run?**
Yes. Submit search URLs for each operation type in the same `urls` array. Every posting records `from_url`, so you can separate the results by source search afterwards.

**Can I filter by neighbourhood, price or number of rooms?**
Filtering happens on Zonaprop itself. Build the filtered search on the site, then paste the resulting URL as a start URL — the scraper collects whatever that search returns.

**Does the Zonaprop scraper use proxies?**
Proxy rotation is handled automatically during the run. There is no proxy field to configure in the input.

**What happens if one start URL fails?**
With `ignoreUrlFailures` set to true, which is the default, the run continues with the remaining URLs. Set it to false if you would rather the run abort so nothing is silently skipped.

**Why is the `url` field not a full web address?**
Zonaprop returns site-relative paths for postings. Prefix them with `https://www.zonaprop.com.ar` to build absolute links.

**What is in the `expenses` field?**
The monthly expensas for the property, as an object containing the numeric `amount`, the `currency` symbol, a `formatted_amount` string and a currency identifier. It is separate from the sale or rental price.

**How do I read the `main_features` object?**
It is keyed by Zonaprop's feature IDs, and each entry carries a `feature_id`, a human-readable `label`, a `value` and a `measure` where a unit applies. Iterate the object's values and index by label to build a tidy feature table.

**How is this actor billed?**
It uses pay-per-event pricing. See the Pricing tab on the Apify Store listing for the current rate.

**Can I schedule Zonaprop property data extraction?**
Yes. Apify schedules let you re-run the same searches on any cadence, and webhooks can push each batch into your systems when a run finishes.

**How do I detect price changes between runs?**
Match records on `posting_id` across consecutive runs and compare `price_operation_types` and `modified_date`. Listings whose price entries changed are your repricing signal.

**What export formats are available for Zonaprop listings data?**
JSON, JSONL, CSV, Excel, XML, HTML and RSS. JSON is recommended because it preserves the nested feature, location, publisher and pictures objects.

***

### 🆘 Support & Feedback

Run into a bug, an unexpected empty result or a search URL that behaves oddly? Open a ticket on the actor's **Issues** tab, including the exact Zonaprop URL and the input you used, so the problem can be reproduced.

Need something custom — additional fields, detail-page enrichment, a specific export shape, or a private build feeding your own property platform? Email **scraperhubapi@gmail.com** with a description of your requirements.

If the Zonaprop Property Listings Scraper helps your work, please leave a review on the Apify Store. Real user feedback drives which improvements get prioritised.

***

### ⚖️ Disclaimer

The Zonaprop Property Listings Scraper collects **publicly available data** only — property postings that Zonaprop displays to any visitor without authentication. It does not access private areas of the site or bypass any access control.

You are responsible for how you use the extracted Zonaprop property data. Review Zonaprop's Terms of Service and robots.txt before running the scraper at scale, keep request volumes reasonable, and do not use the output in ways the platform prohibits.

Property listings can contain personal data. Individual agents appear in the `publisher` object, and the `whatsapp` field may carry a personal phone number. If you process such data for individuals in the EU, UK, Argentina or other jurisdictions with data protection regimes, you must comply with the GDPR and equivalent privacy legislation — establish a lawful basis, honour data subject rights, minimise what you store and delete what you no longer need. Be especially careful with contact details: using scraped phone numbers for unsolicited marketing may breach both privacy law and the platform's terms. Listing photographs and descriptions also remain the property of their rights holders.

If you believe data collected by this Zonaprop scraper relates to you and you would like it removed, contact **scraperhubapi@gmail.com** with the relevant details and we will action your request.

# Actor input Schema

## `urls` (type: `array`):

Zonaprop listing URLs to scrape (e.g. a search results page). Pagination is followed automatically.

## `maxItemsPerUrl` (type: `integer`):

Maximum number of postings to collect per start URL.

## `maxRetriesPerUrl` (type: `integer`):

How many times to retry a failed page request before giving up.

## `ignoreUrlFailures` (type: `boolean`):

If a start URL fails, continue with the remaining URLs instead of aborting the run.

## Actor input object example

```json
{
  "urls": [
    "https://www.zonaprop.com.ar/departamentos-venta.html"
  ],
  "maxItemsPerUrl": 30,
  "maxRetriesPerUrl": 2,
  "ignoreUrlFailures": true
}
```

# Actor output Schema

## `results` (type: `string`):

Records scraped by Zonaprop Property Listings Scraper, stored in the run's default dataset.

## `pageSnapshots` (type: `string`):

Raw HTML snapshots of the listing pages that were scraped.

# 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 = {
    "urls": [
        "https://www.zonaprop.com.ar/departamentos-venta.html"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers-hub/zonaprop-property-listings-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 = { "urls": ["https://www.zonaprop.com.ar/departamentos-venta.html"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapers-hub/zonaprop-property-listings-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 '{
  "urls": [
    "https://www.zonaprop.com.ar/departamentos-venta.html"
  ]
}' |
apify call scrapers-hub/zonaprop-property-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers-hub/zonaprop-property-listings-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/wEOSKUUaEKJSX3YEX/builds/V1Bkndw7F3eRrZoLm/openapi.json
