# Zonaprop | Extracción de Propiedades y Datos de Anunciantes (`hiagencia/zonaprop`) Actor

Extracción de avisos de Zonaprop con la ficha completa de cada propiedad: precio, superficies, ubicación, características y fotos. Como opciones, el teléfono y el mail validado del anunciante. Por filtros, avisos específicos o datos de anunciantes.

- **URL**: https://apify.com/hiagencia/zonaprop.md
- **Developed by:** [Hi Agencia](https://apify.com/hiagencia) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 avisos

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

## Zonaprop | Extracción de Propiedades y Datos de Anunciantes

Avisos de Zonaprop, el portal inmobiliario de Argentina, con su ficha completa: precio y expensas, superficies en m²,
ambientes, dormitorios y baños, dirección con barrio, ciudad, provincia y coordenadas, descripción, comodidades, fotos y
fecha de publicación. Como opciones, el teléfono, el celular y el WhatsApp de cada anunciante en formato internacional, y
su mail validado. Una fila por aviso, con las mismas 43 columnas en todos los modos.

> Desarrollado por **[Hi Agencia](https://hiagencia.com/?utm_source=apify\&utm_medium=actor\&utm_campaign=zonaprop)** — extracción de datos, automatización y software a medida para empresas que venden. Publicado en Apify como **Hi Agencia**.

***

### Qué entrega

- **La ficha completa de cada aviso**, en una forma lista para usar: los montos como número con su moneda en código de
  tres letras (USD, ARS), las superficies en m² —la que el portal publica en hectáreas sale convertida—, las fechas en
  ISO 8601 y la ubicación separada en barrio, ciudad, provincia, región y país.
- **El tipo de anunciante**: dueño directo o inmobiliaria, según el filtro del propio portal.
- **Los datos de contacto del anunciante**, a elección: teléfono, celular y WhatsApp en formato internacional —con el 9 de
  los celulares argentinos, la forma que abre el chat—, y el mail, sólo validado.
- **De cuándo es cada dato**: la columna `fechaActualizacion` dice cuándo se leyó la fila, y ningún aviso se entrega con
  datos de más de una semana; con «Antigüedad máxima de los datos» se pide un plazo más corto, en horas, y con 0 cada
  aviso se lee en el momento.

### Cuándo usarlo

- Armar bases de contacto de dueños directos, de inmobiliarias, o de ambos, por zona, tipo de propiedad y operación.
- Analizar el mercado: precios y precio por m², oferta por barrio, por antigüedad o por superficie.
- Seguir lo que se publica: con la fecha de publicación limitada a las últimas 24 horas, cada corrida trae lo nuevo
  del día.
- Completar avisos o anunciantes que ya se tienen, por sus links o sus números.

### Cuándo no

- Para otros portales: entrega sólo avisos de Zonaprop.
- Para el historial de un aviso: entrega su estado actual, no sus precios anteriores; un aviso que ya no está publicado
  sale marcado como «Dado de baja».
- Para buscar personas o validar casillas sueltas: el contacto es el del anunciante de cada aviso, y el mail se entrega
  sólo validado.

### Qué lo hace distinto

- **La búsqueda completa.** Una búsqueda se entrega entera, también la que tiene más páginas de las que el portal
  muestra; el resumen de la corrida dice si se leyó completa.
- **La ficha en cada fila**, no sólo lo que muestra el listado.
- **El contacto con su estado.** Cada fila dice si el mail está entregado, pendiente o no disponible, y de dónde sale.
- **Se cobra lo entregado.** Un aviso dado de baja no se cobra como aviso, y los datos del anunciante se cobran una vez
  por anunciante y por corrida, sólo si se entregan.

### Cómo se usa

#### Modos de uso

| Modo | Qué se completa | Qué entrega |
|---|---|---|
| Búsqueda por filtros | quién publica (dueños directos, inmobiliarias o ambos) y los filtros del formulario | todos los avisos que coinciden, completa |
| Avisos específicos | URLs o números de aviso | esos avisos |
| Datos de anunciantes | links de la página del anunciante en el portal, o sus números | los datos de contacto de cada anunciante |

Los filtros son los del portal: quién publica, tipo de propiedad, operación, ubicación (las 29 de primer nivel; con
varias, se suman), ambientes desde y hasta, precio desde y hasta en dólares o en pesos, superficie total o cubierta desde
y hasta, antigüedad y fecha de publicación. Con una ubicación elegida, los avisos de otro lugar que el portal suma a la
búsqueda no se entregan. Un valor que no está en el formulario o un rango invertido se rechazan antes de empezar, con su
motivo.

#### Cuántos

«Máximo de avisos» viene precargado en 100, para que una primera corrida sea una muestra. Vacío, se entrega la búsqueda
completa; por API, una corrida que no lo manda no tiene límite. El tope de gasto de la corrida también limita: se
entregan las filas que el tope alcanza a pagar.

#### Qué tan recientes

«Antigüedad máxima de los datos» dice, en horas, cuán viejos pueden ser los datos de un aviso: el que se leyó del portal
hace más se vuelve a leer en el momento, y el más reciente se entrega con lo ya leído. Vacío, una semana (168); con 0,
todos se leen en el momento. Sirve, por ejemplo, para confirmar con «Avisos específicos» que una lista de avisos sigue
publicada hoy: el que ya no está sale «Dado de baja», y `fechaActualizacion` dice cuándo se leyó cada fila.

#### Datos del anunciante

- **Teléfonos y WhatsApp del anunciante**: el teléfono, el celular y el WhatsApp de cada anunciante. Se cobran una vez por
  anunciante y por corrida, sólo si se entrega al menos un número.
- **Mail del anunciante**: sólo validado. Se cobra una vez por anunciante y por corrida, sólo si se entrega. Cuando
  todavía no está disponible, la fila lo dice («Pendiente») y puede volver a pedirse más tarde con el link del aviso, en
  el modo Avisos específicos.

El modo Datos de anunciantes entrega los datos de contacto: lleva la opción de teléfonos, la del mail o las dos.

### Las columnas

| Columna | Qué es |
|---|---|
| `idAviso` | Número del aviso en el portal. |
| `url` | Link del aviso. |
| `estadoAviso` | Publicado · Dado de baja · Sin datos (ver «Cómo leer un dato vacío»). |
| `operacion` | Venta · Alquiler · Alquiler temporal. |
| `tipoPropiedad` | Departamento, Casa, PH, Terreno y los demás tipos del portal. |
| `titulo` | Título del aviso. |
| `precio` | Precio publicado. |
| `moneda` | Moneda del precio, en código de tres letras. |
| `expensas` | Expensas publicadas. |
| `expensasMoneda` | Moneda de las expensas. |
| `ambientes` | Cantidad de ambientes. |
| `dormitorios` | Cantidad de dormitorios. |
| `banos` | Cantidad de baños. |
| `cocheras` | Cantidad de cocheras. |
| `superficieTotalM2` | Superficie total, en m². |
| `superficieCubiertaM2` | Superficie cubierta, en m². |
| `direccion` | Dirección publicada. |
| `barrio` | Barrio en la Ciudad Autónoma de Buenos Aires; localidad en el resto. |
| `ciudad` | Ciudad o partido. |
| `provincia` | Provincia; fuera de Argentina, el nivel equivalente del país. |
| `region` | La región del portal dentro de la provincia de Buenos Aires: GBA Norte · GBA Sur · GBA Oeste · Buenos Aires Costa Atlántica · Buenos Aires (fuera de GBA). |
| `pais` | País del aviso. |
| `latitud` · `longitud` | Coordenadas de la ubicación publicada. |
| `anunciante` | Nombre de quien publica. |
| `idAnunciante` | Número del anunciante en el portal: con él se piden sus datos en el modo Datos de anunciantes. |
| `tipoAnunciante` | Dueño directo · Inmobiliaria. |
| `estadoAnunciante` | Encontrado · Sin datos. |
| `telefonoAnunciante` | Teléfono del anunciante, en formato internacional (`+54…`). |
| `celularAnunciante` | Celular del anunciante, con el 9 de los celulares argentinos (`+549…`). |
| `whatsappAnunciante` | WhatsApp del anunciante, en la forma que abre el chat (`+549…`). |
| `mailAnunciante` | Mail del anunciante, sólo validado. |
| `estadoMail` | Entregado · Pendiente · No disponible · No entregado: tope de gasto. |
| `origenMail` | Declarado por el anunciante · Reconstruido y validado (la casilla personal armada desde la dirección que el portal muestra, con uso comprobado). |
| `descripcion` | Descripción completa del aviso. |
| `comodidades` | Comodidades y servicios publicados. |
| `antiguedadAnios` | Antigüedad de la propiedad, en años. |
| `disposicion` | Disposición: frente, contrafrente… |
| `aptoCredito` | Si el aviso dice que es apto crédito. |
| `fechaPublicacion` | Fecha de publicación (ISO 8601). |
| `fotos` | Links de las fotos. |
| `video` | Si el aviso tiene video. |
| `fechaActualizacion` | Cuándo se leyeron los datos de la fila (ISO 8601). |

Un teléfono que no se puede ubicar —un número local sin código de área— sale con los dígitos que publicó el anunciante.

### Cómo leer un dato vacío

- **El aviso no lo publica.** Con `estadoAviso` «Publicado», una columna vacía es un dato que el aviso no trae: un
  departamento sin expensas, una casa sin cochera, un aviso sin coordenadas.
- **El aviso ya no está.** «Dado de baja»: el aviso no está publicado o no existe, y la fila lleva lo que se pudo saber.
  «Sin datos»: el portal no devolvió los datos del aviso. Ninguno de los dos se cobra como aviso.
- **No se pidió.** Las columnas de teléfonos van vacías sin la opción de teléfonos, y las del mail sin la opción del mail.
- **No hay un número completo.** Con la opción de teléfonos, una columna vacía es un número que el anunciante no publica
  completo.
- **El mail tiene su estado** (`estadoMail`): «Entregado» trae el mail; «Pendiente: se puede volver a pedir más tarde»
  todavía no está disponible; «No disponible» no hay un mail validado de ese anunciante; «No entregado: tope de gasto» el
  tope de la corrida no alcanzó a pagarlo.
- **El tope de gasto.** Si el tope no alcanza para los datos del anunciante de una fila, la fila sale con esas columnas
  vacías y no se cobran.
- **Según el lugar.** `region` va vacía fuera de la provincia de Buenos Aires.
- **En el modo Datos de anunciantes** las columnas del aviso van vacías, y «Sin datos: se obtienen pidiendo uno de sus avisos» dice
  que los datos de ese anunciante se obtienen corriendo uno de sus avisos.

### El resumen de la corrida

El registro `RESUMEN` del almacén de la corrida dice cuántos avisos se encontraron y cuántos se entregaron, si la
búsqueda se leyó completa, cuántos estaban dados de baja, cuántos anunciantes recibieron teléfonos y mail, cuántos
mails quedaron pendientes, y si cortó el máximo de avisos o el tope de gasto.

### Cobro

| Evento | Cuándo se cobra | Cuándo no |
|---|---|---|
| Inicio de la corrida | al arrancar, según la memoria asignada | — |
| Aviso | por cada fila entregada con el aviso publicado | un aviso dado de baja o sin datos |
| Teléfonos | una vez por anunciante y por corrida, si se entrega al menos un número | sin la opción, sin un número completo, o fuera del tope |
| Mail | una vez por anunciante y por corrida, si se entrega el mail validado | sin la opción, pendiente, no disponible, o fuera del tope |

### Acerca de

Desarrollado y mantenido por **Hi Agencia**, publicado en Apify como **Hi Agencia**.

Hi Agencia construye la capa de datos y automatización sobre la que funcionan las operaciones comerciales: extrae y
enriquece datos donde estén, los conecta con CRMs y herramientas internas, y construye lo que la operación necesite
alrededor. Este Actor es una pieza de ese stack, empaquetada para usarse por sí sola.

**[hiagencia.com](https://hiagencia.com/?utm_source=apify\&utm_medium=actor\&utm_campaign=zonaprop)**

¿Hace falta algo que este Actor no cubre, o el circuito completo en lugar de una pieza? El contacto, por el sitio.

# Actor input Schema

## `modo` (type: `string`):

Búsqueda por filtros: recorre el portal con los filtros de abajo y entrega todos los avisos que coinciden, completa. Avisos específicos: entrega únicamente los avisos indicados. Datos de anunciantes: entrega los datos de contacto de cada anunciante indicado.

## `tipoAnunciante` (type: `array`):

Si se deja vacío, se incluyen los avisos de dueños directos y de inmobiliarias. Se usa con el modo Búsqueda por filtros.

## `tipos` (type: `array`):

Si se deja vacío, se incluyen todos los tipos.

## `operaciones` (type: `array`):

Si se deja vacío, se incluyen todas las operaciones.

## `ubicaciones` (type: `array`):

Si se deja vacío, se incluyen todas las ubicaciones. Con varias seleccionadas, se suman.

## `ambientesDesde` (type: `string`):

Cantidad mínima de ambientes. Si se deja vacío, no hay mínimo.

## `ambientesHasta` (type: `string`):

Cantidad máxima de ambientes. Con un máximo, también se incluyen los avisos sin ambientes declarados, como en el portal.

## `moneda` (type: `string`):

Moneda en la que se expresan los límites de precio. Los avisos publicados en la otra moneda se incluyen convertidos, como en el portal.

## `precioDesde` (type: `integer`):

Precio mínimo, en la moneda elegida. Si se deja vacío, no hay mínimo.

## `precioHasta` (type: `integer`):

Precio máximo, en la moneda elegida. Con un máximo, también se incluyen los avisos sin precio publicado, como en el portal.

## `superficieTipo` (type: `string`):

Qué superficie se compara con el mínimo y el máximo: la total o la cubierta.

## `superficieDesde` (type: `integer`):

Superficie mínima, en m². Si se deja vacío, no hay mínimo.

## `superficieHasta` (type: `integer`):

Superficie máxima, en m². Con un máximo, también se incluyen los avisos con superficie 0, como en el portal.

## `antiguedad` (type: `string`):

La antigüedad de la propiedad, según las opciones del portal.

## `fecha` (type: `string`):

Incluye sólo lo publicado dentro de la ventana elegida. Se usa con el modo Búsqueda por filtros.

## `avisos` (type: `array`):

Links de avisos del portal o sus números, por ejemplo 60312816 o el link completo del aviso. Se entrega únicamente esos avisos. Se usa con el modo «Avisos específicos».

## `anunciantes` (type: `array`):

Links de la página del anunciante en el portal o sus números, por ejemplo https://www.zonaprop.com.ar/inmobiliarias/x_17052679-inmuebles.html. Se entregan los datos de contacto de cada anunciante. Se usa con el modo «Datos de anunciantes».

## `maximoAvisos` (type: `integer`):

Cantidad máxima de avisos a entregar. Si se deja vacío, no hay límite: se entrega la búsqueda completa.

## `antiguedadMaximaHoras` (type: `integer`):

Un aviso cuyos datos se leyeron del portal hace más de estas horas se vuelve a leer en el momento; uno más reciente se entrega con lo ya leído. La columna fechaActualizacion dice cuándo se leyó cada fila. Con 0, todos se leen en el momento. Si se deja vacío, 168 (una semana).

## `telefonos` (type: `boolean`):

Teléfono, celular y WhatsApp de cada anunciante. Se cobra una vez por anunciante y por corrida, solo si se entrega al menos un número.

## `mail` (type: `boolean`):

El mail de cada anunciante, solo si está validado. Se cobra una vez por anunciante y por corrida, solo si se entrega. Cuando todavía no está disponible, la fila lo indica y puede volver a pedirse más tarde con el link del aviso.

## Actor input object example

```json
{
  "modo": "filtros",
  "tipoAnunciante": [],
  "tipos": [],
  "operaciones": [],
  "ubicaciones": [],
  "ambientesDesde": "",
  "ambientesHasta": "",
  "moneda": "dolares",
  "superficieTipo": "total",
  "antiguedad": "",
  "fecha": "",
  "avisos": [],
  "anunciantes": [],
  "maximoAvisos": 100,
  "telefonos": false,
  "mail": false
}
```

# Actor output Schema

## `avisos` (type: `string`):

Una fila por aviso: la ficha completa y, con sus opciones, los datos de contacto del anunciante.

## `contacto` (type: `string`):

Las mismas filas, con las columnas del anunciante: teléfonos, WhatsApp y mail con su estado y su origen.

## `resumen` (type: `string`):

Cuántos avisos se encontraron y se entregaron, si la búsqueda se leyó completa, y si cortó el máximo de avisos o el tope de gasto.

# 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 = {
    "maximoAvisos": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("hiagencia/zonaprop").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 = { "maximoAvisos": 100 }

# Run the Actor and wait for it to finish
run = client.actor("hiagencia/zonaprop").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 '{
  "maximoAvisos": 100
}' |
apify call hiagencia/zonaprop --silent --output-dataset

```

## MCP server setup

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

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/mCtmGGOe3n5jFTGFK/builds/S4RKzLPKyTAh5havc/openapi.json
