# VivaReal Scraper | Brazil Real Estate BRL Pricing (`haketa/vivareal-scraper`) Actor

VivaReal scraper & API for Brazilian real estate: search property for sale and rent and export address, price, condo fee, beds, baths, parking, area, type, amenities, photos and coordinates. Brazil property market data and real-estate lead generation — fast, no login.

- **URL**: https://apify.com/haketa/vivareal-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Real estate, Developer tools, Automation
- **Features:** Limited permissions
- **Stats:** 23 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 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

## VivaReal Scraper — Brazil Real Estate Listings, BRL Pricing, Condomínio, IPTU & Imobiliária Leads

> **Scrape property listings and real estate agency profiles from [VivaReal.com.br](https://www.vivareal.com.br) — Brazil's premier real estate marketplace.** Extract apartments (`apartamentos`), houses (`casas`), penthouses (`coberturas`), commercial spaces, and new developer projects (`lançamentos`) with **asking prices in BRL, monthly condomínio fees, annual IPTU tax, R$/m², usable & total area, bedrooms/suites/parking, bairro-level address, GPS coordinates, FGTS/MCMV financing flags, CRECI broker licenses, and high-resolution photo galleries**. Includes a dedicated **Agency Directory mode** for B2B real estate lead generation.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-00C853?style=flat-square\&logo=apify)](https://apify.com/haketa/vivareal-scraper)
[![Region](https://img.shields.io/badge/Market-Brazil%20%F0%9F%87%A7%F0%9F%87%B7-green?style=flat-square)]()
[![Deep Pagination](https://img.shields.io/badge/Scale-1%2C000%2B%20Listings%20Pagination-orange?style=flat-square)]()
[![B2B Leads](https://img.shields.io/badge/Mode-Listings%20%2B%20Imobili%C3%A1ria%20Directory-blue?style=flat-square)]()
[![Data Formats](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel%20%7C%20API-purple?style=flat-square)]()

***

### ⚡ At a glance

| Capability | Details |
| --- | --- |
| **Target Portals** | [VivaReal](https://www.vivareal.com.br) (`VIVA_REAL`) and sister portal **ZAP Imóveis** (`ZAP`) |
| **Operating Modes** | **Property Listings** (Sale & Rent, Used & Lançamentos) · **Agency Directory** (`imobiliárias` B2B leads) |
| **Geographic Scope** | All 27 Brazilian states (`UF`), 50+ pre-mapped cities, custom city slugs, and `bairro` (neighborhood) targeting |
| **Financial & Property Data** | `priceBRL`, `condominioMonthlyBRL`, `iptuYearlyBRL`, `totalMonthlyCostBRL`, `pricePerSqmBRL`, `usableArea`, `bedrooms`, `suites`, `parkingSpaces` |
| **Brazilian Market Signals** | `isFGTSEligible`, `isMCMVEligible`, `isFinancing`, `isFiadorFree` (`Sem Fiador`), `acceptsExchange` (`Permuta`) |
| **Pagination & Scale** | Offset-based deep pagination (`maxPages: 0` = unlimited, governed by `maxListings` up to **1,000–50,000+ listings**) |
| **Deduplication** | Automatic cross-page and cross-search deduplication on `listingId` (0% duplicate records) |
| **Export Formats** | JSON, JSONL, CSV, Excel (XLSX), XML, HTML Table, REST API, Webhooks |

***

### 🔎 Why scrape VivaReal?

[VivaReal](https://www.vivareal.com.br/) (part of Grupo OLX / Grupo ZAP alongside ZAP Imóveis) is where millions of Brazilian homebuyers, renters, investors, and brokers search to **comprar** (buy) and **alugar** (rent) residential and commercial real estate across every state (`UF`), municipality (`cidade`), and neighborhood (`bairro`).

Collecting Brazilian real estate intelligence manually or with generic scrapers fails because:

- **Brazilian housing economics require 3 numbers, not 1:** In Brazil, evaluating a rental or purchase without **monthly condomínio (HOA)** and **annual IPTU (municipal property tax)** produces completely distorted yield and affordability calculations.
- **Complex local financing & rental rules:** Buyers filter heavily on **FGTS** eligibility, **Minha Casa Minha Vida (MCMV)** qualification, and **permuta** (property exchange), while renters look for **Sem Fiador** (no guarantor required).
- **Rich developer & broker metadata:** New builds (`lançamentos`) carry constructor names, CNPJ tax IDs, construction phase (`Pré-lançamento`, `Em obras`, `Pronto para morar`), and delivery dates, while agencies carry mandatory **CRECI** license numbers.

This **VivaReal scraper** extracts and normalizes all 80+ fields into a flat, analysis-ready schema — calculating `pricePerSqmBRL` and `totalMonthlyCostBRL` (`rent + condomínio + IPTU/12`) automatically, filtering out broker `R$ 1` placeholder spam, and resolving image templates into direct high-resolution photo URLs.

***

### ✨ What this VivaReal data extractor does

- 🏠 **Dual Extraction Modes:**
  - **Property Listings Mode (`listings`):** Search residential and commercial properties for sale (`SALE`) or rent (`RENTAL`), covering resale inventory (`USED`) and brand-new developer projects (`DEVELOPMENT` / `lançamentos`).
  - **Agency Directory Mode (`agencies`):** Extract real estate agency (`imobiliária`) profiles with `agencyName`, `agencyCRECI`, `agencyCNPJ`, `agencyPhone`, `agencyEmail`, `agencyWebsite`, `agencyAddress`, and portfolio counts for B2B lead generation.
- 🔄 **Dual Portal Switch (`VIVA_REAL` & `ZAP`):** Switch between VivaReal and ZAP Imóveis with a single dropdown while keeping the exact same input and output schema.
- 🔓 **Unlocked 1,000+ Deep Pagination:** With `maxPages: 0` by default, pagination continues automatically until `maxListings` is reached or the search inventory is exhausted — scaling effortlessly to **1,000+ listings** per run.
- 💰 **Complete Brazilian Cost Breakdown:** Extracts `priceBRL`, `condominioMonthlyBRL`, `iptuYearlyBRL`, derived `pricePerSqmBRL` (R$/m²), and `totalMonthlyCostBRL` for rentals.
- 🏗️ **Lançamento & Developer Intelligence:** Captures `isLancamento`, `launchName`, `launchPhase`, `constructorName`, `constructorCNPJ`, `deliveryDate`, and `totalUnits`.
- 🏦 **FGTS, MCMV & Sem Fiador Detection:** Automatically flags `isFGTSEligible`, `isMCMVEligible`, `isFinancing`, `isFiadorFree`, and `acceptsExchange` from structured amenities and listing descriptions.
- 🖼️ **Clean Media Separation:** Expands VivaReal's dynamic image sizing templates into ready-to-open `800x600` photo URLs (`imageUrls`, `thumbnailUrl`) and separates YouTube/Vimeo walkthroughs into `videoUrls`.

***

### 🎯 High-value use cases

#### 1. Real Estate Investment & FII (Fundos Imobiliários) Analytics

Benchmark asking prices and **R$/m²** (`pricePerSqmBRL`) across São Paulo, Rio de Janeiro, Belo Horizonte, Curitiba, Florianópolis, and Brasília. Compute net rental yields after subtracting `condominioMonthlyBRL` and `iptuYearlyBRL`.

#### 2. PropTech Valuation Models (AVM & CMA)

Feed thousands of geo-coded comparables (`latitude`, `longitude`, `zipCode` CEP, `usableArea`, `bedrooms`, `suites`, `parkingSpaces`, `amenities`) into automated valuation models and comparative market analysis tools.

#### 3. B2B Imobiliária & Broker Lead Generation

Use **Agency Directory mode** (or aggregate `agencyId`, `agencyName`, `agencyCRECI`, and `agencyPhone` from listings) to build verified B2B prospect lists for CRM software, mortgage origination, property insurance, and marketing agencies.

#### 4. Developer & Lançamento Competitive Tracking

Filter `listingType: ["DEVELOPMENT"]` to monitor competing developers (Cyrela, MRV, EZTec, Tegra, Direcional), tracking unit sizes, launch phases (`Em obras` vs. `Pré-lançamento`), delivery dates, and pricing per square meter.

#### 5. Mortgage, FGTS & Subsidized Housing Sizing

Identify neighborhoods and price tiers with the highest concentration of `isFGTSEligible`, `isMCMVEligible`, and `isFinancing` inventory for credit and mortgage product targeting.

***

### 📥 Input parameters

All fields are optional. Leaving location filters empty runs a nationwide sample across Brazil.

| Parameter | Type | Default / Prefill | Description |
| --- | --- | --- | --- |
| `mode` | `string` | `"listings"` | `"listings"` for property search, or `"agencies"` for B2B real estate agency directory profiles. |
| `portal` | `string` | `"VIVA_REAL"` | Target portal: `"VIVA_REAL"` (VivaReal) or `"ZAP"` (ZAP Imóveis). |
| `business` | `array<string>` | `["SALE"]` | Deal type: `"SALE"` (Venda), `"RENTAL"` (Aluguel), or both. |
| `listingType` | `array<string>` | `["USED"]` | `"USED"` (resale/standard rental) or `"DEVELOPMENT"` (new `lançamentos`). |
| `usageTypes` | `array<string>` | `["RESIDENTIAL"]` | `"RESIDENTIAL"`, `"COMMERCIAL"`, or both. |
| `unitTypes` | `array<string>` | `[]` (All types) | Filter by specific property types: `APARTMENT`, `HOME`, `CONDOMINIUM`, `PENTHOUSE`, `FLAT`, `KITNET`, `FARM`, `LAND_LOT`, `OFFICE`, `COMMERCIAL_BUILDING`, `WAREHOUSE_SHED`, `HOTEL`, etc. |
| `states` | `array<string>` | Prefill: `["SP"]` | Brazilian state UF codes (`SP`, `RJ`, `MG`, `RS`, `PR`, `SC`, `BA`, `DF`, `GO`, `PE`, `CE`, `ES`, etc.). |
| `cities` | `array<string>` | Prefill: `["sao-paulo"]` | Major Brazilian cities from the dropdown (`sao-paulo`, `rio-de-janeiro`, `belo-horizonte`, `brasilia`, `curitiba`, `porto-alegre`, `florianopolis`, `salvador`, `recife`, `fortaleza`, etc.). |
| `citiesCustom` | `array<string>` | `[]` | Additional cities by URL slug (lowercase, hyphenated, no accents, e.g., `"sao-bernardo-do-campo"`, `"balneario-camboriu"`). |
| `neighborhoods` | `array<string>` | `[]` | Specific `bairros` by slug (e.g., `"pinheiros"`, `"itaim-bibi"`, `"vila-mariana"`, `"copacabana"`, `"leblon"`). |
| `minPrice` / `maxPrice` | `integer` | `0` | Minimum and maximum price in BRL (`0` = no limit). |
| `minArea` / `maxArea` | `integer` | `0` | Minimum and maximum usable area in `m²` (`0` = no limit). |
| `minBedrooms` | `integer` | `0` | Minimum number of bedrooms (`quartos`). |
| `minParkingSpaces` | `integer` | `0` | Minimum number of parking spaces (`vagas`). |
| `semFiador` | `boolean` | `false` | Filter rentals that do not require a guarantor (`Sem Fiador`). |
| `sortBy` | `string` | `"relevance"` | Sort order: `"relevance"`, `"newest"`, `"lowest_price"`, `"highest_price"`, `"lowest_area"`, `"highest_area"`. |
| `maxListings` | `integer` | `100` | Maximum total records to collect (`0` = unlimited). Set to `1000+` for deep market pulls. |
| `maxPages` | `integer` | `0` | Maximum pages per search combination (`0` = unlimited, governed by `maxListings`). |
| `pageSize` | `integer` | `24` | Listings fetched per page request (`1` to `100`). |
| `agencyIds` | `array<string>` | `[]` | **Agency Directory mode:** Specific `imobiliária` IDs to extract. |
| `agencyIdRangeStart` / `End` | `integer` | `0` | **Agency Directory mode:** Sequential agency ID range for bulk discovery. |
| `fetchAgencyListings` | `boolean` | `false` | **Agency Directory mode:** Also extract each agency's active property listings. |
| `proxyConfiguration` | `object` | Residential `BR` | Apify Proxy configuration. **Brazilian Residential proxy (`BR`) is preconfigured and strongly recommended.** |

***

### 🛠️ Input recipes & examples

#### Recipe 1: Deep 1,000+ apartment sale sweep in São Paulo bairros

Collect 1,500 apartments for sale across Pinheiros, Itaim Bibi, and Moema in São Paulo:

```json
{
  "mode": "listings",
  "portal": "VIVA_REAL",
  "business": ["SALE"],
  "listingType": ["USED"],
  "usageTypes": ["RESIDENTIAL"],
  "unitTypes": ["APARTMENT", "PENTHOUSE"],
  "states": ["SP"],
  "cities": ["sao-paulo"],
  "neighborhoods": ["pinheiros", "itaim-bibi", "moema"],
  "minBedrooms": 2,
  "sortBy": "newest",
  "maxListings": 1500,
  "maxPages": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "BR"
  }
}
```

#### Recipe 2: Rental yield & Sem Fiador analysis in Rio de Janeiro

Pull 500 rental listings in Copacabana and Ipanema with full monthly cost breakdown (`totalMonthlyCostBRL`):

```json
{
  "mode": "listings",
  "business": ["RENTAL"],
  "usageTypes": ["RESIDENTIAL"],
  "states": ["RJ"],
  "cities": ["rio-de-janeiro"],
  "neighborhoods": ["copacabana", "ipanema"],
  "maxPrice": 12000,
  "sortBy": "lowest_price",
  "maxListings": 500
}
```

#### Recipe 3: New developer launches (`Lançamentos`) tracker

Track brand-new residential developments (`DEVELOPMENT`) across São Paulo and Curitiba:

```json
{
  "mode": "listings",
  "business": ["SALE"],
  "listingType": ["DEVELOPMENT"],
  "usageTypes": ["RESIDENTIAL"],
  "states": ["SP", "PR"],
  "cities": ["sao-paulo", "curitiba"],
  "maxListings": 1000
}
```

***

### 📤 Output schema & field reference

Each record is a flat JSON object (`recordType: "listing"` or `"agency"`).

#### 🏷️ Core Identity & Classification Fields

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `recordType` | `string` | 🟢 High (100%) | `"listing"` or `"agency"`. |
| `listingId` | `string` | 🟢 High (100%) | Unique VivaReal / ZAP listing or agency ID. |
| `portal` | `string` | 🟢 High (100%) | Source portal (`"VIVA_REAL"` or `"ZAP"`). |
| `url` | `string` | 🟢 High (100%) | Canonical URL on `vivareal.com.br` or `zapimoveis.com.br`. |
| `business` | `string` | 🟢 High (100%) | `"SALE"` or `"RENTAL"`. |
| `listingType` | `string` | 🟢 High (100%) | `"USED"` or `"DEVELOPMENT"`. |
| `usageType` | `string` | 🟢 High (100%) | `"RESIDENTIAL"` or `"COMMERCIAL"`. |
| `unitType` / `unitSubType` | `string` | 🟢 High (100%) | Raw property type (`"APARTMENT"`, `"HOME"`, `"PENTHOUSE"`, `"OFFICE"`, etc.). |
| `category` / `subCategory` | `string` | 🟢 High (100%) | Normalized category (`"residential"`, `"comercial"`, `"land"`, `"rural"`) and Portuguese slug (`"apartamento"`, `"casa"`, `"cobertura"`). |
| `title` / `description` | `string` | 🟡 Conditional | Headline and description text when exposed by the publisher on the feed. |

#### 💰 Pricing & Brazilian Tax/HOA Fields (BRL)

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `priceBRL` | `number` | 🟢 High (~99%) | Asking sale price or monthly rent in Brazilian Reais (`BRL`). Sentinel `R$ 1` placeholders are filtered out. |
| `pricePerSqmBRL` | `number` | 🟢 High (~98%) | Automatically calculated `priceBRL / usableArea` (R$/m²). |
| `condominioMonthlyBRL` | `number` | 🟡 Conditional (~55%) | Monthly HOA (`condomínio`) fee in BRL when applicable. |
| `iptuYearlyBRL` | `number` | 🟡 Conditional (~55%) | Annual municipal property tax (`IPTU`) in BRL. |
| `totalMonthlyCostBRL` | `number` | 🟡 Conditional (Rentals) | Derived total monthly outlay for rentals: `priceBRL + condominioMonthlyBRL + (iptuYearlyBRL / 12)`. |
| `rentPeriod` | `string` | 🟡 Conditional (Rentals) | Rental billing period (e.g., `"MONTHLY"`). |

#### 📐 Dimensions, Rooms & Amenities

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `usableArea` / `totalArea` | `number` | 🟢 High (96–100%) | Usable (`área útil`) and total area in square meters (`m²`). |
| `bedrooms` | `number` | 🟢 High (~98%) | Number of bedrooms (`quartos`). |
| `bathrooms` | `number` | 🟢 High (~99%) | Number of bathrooms (`banheiros`). |
| `suites` | `number` | 🟢 High (~82%) | Number of en-suite bedrooms (`suítes`). |
| `parkingSpaces` | `number` | 🟢 High (~95%) | Number of parking spaces (`vagas de garagem`). |
| `amenities` | `array<string>` | 🟢 High (~87%) | Normalized amenity tags (`POOL`, `GYM`, `GATED_COMMUNITY`, `ELEVATOR`, `PETS_ALLOWED`, `BALCONY`, etc.). |

#### 📍 Location & Geo-Coordinates

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `uf` | `string` | 🟢 High (100%) | 2-letter Brazilian state code (`SP`, `RJ`, `MG`, `PR`, `SC`, etc.). |
| `city` | `string` | 🟢 High (100%) | Municipality name with proper Portuguese diacritics (`São Paulo`, `Florianópolis`). |
| `neighborhood` | `string` | 🟢 High (100%) | Neighborhood (`bairro`) name (`Pinheiros`, `Jardim Paulista`, `Copacabana`). |
| `zone` | `string` | 🟢 High (~95%) | Urban zone (`Zona Sul`, `Zona Oeste`, `Centro`, etc.). |
| `street` / `streetNumber` | `string` | 🟢 High (75–90%) | Street name (`logradouro`) and street number when disclosed by the seller. |
| `zipCode` | `string` | 🟢 High (~99%) | 8-digit Brazilian postal code (`CEP`). |
| `latitude` / `longitude` | `number` | 🟢 High (~80%) | WGS-84 GPS coordinates for mapping and spatial analysis. |

#### 🏦 Brazilian Financing, Lançamento & Agency Fields

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `isFGTSEligible` / `isMCMVEligible` | `boolean` | 🟢 High (100%) | Flags indicating FGTS or Minha Casa Minha Vida eligibility signals. |
| `isFinancing` / `acceptsExchange` | `boolean` | 🟢 High (100%) | Flags for bank financing (`aceita financiamento`) and property trade-in (`permuta`). |
| `isFiadorFree` | `boolean` | 🟢 High (100%) | `true` when the rental does not require a traditional guarantor (`sem fiador`). |
| `isLancamento` / `launchPhase` | `boolean/string` | 🟡 Conditional | New development flag and construction status (`Pré-lançamento`, `Em obras`, `Pronto para morar`). |
| `constructorName` / `constructorCNPJ` | `string` | 🟡 Conditional | Developer company name and corporate tax ID (`CNPJ`) on `DEVELOPMENT` listings. |
| `deliveryDate` / `totalUnits` | `string/number` | 🟡 Conditional | Expected completion date and total unit count for new developments. |
| `agencyId` / `agencyName` | `string` | 🟢 High (~98%) | Publishing real estate agency (`imobiliária`) ID and display name. |
| `agencyCRECI` | `string` | 🟢 High (~88%) | Official Brazilian broker license registration (`CRECI`, e.g., `"19917-J-SP"`). |
| `agencyPhone` / `agencyEmail` / `agencyCNPJ` | `string` | 🟡 Conditional | Populated in **Agency Directory mode** (`mode: "agencies"`) or when disclosed on the account record. |
| `agencyTier` / `agencyVerified` | `string/boolean` | 🟢 High (~95%) | Advertiser tier (`diamond`, `gold`, `silver`) and verification badge. |
| `imageCount` / `thumbnailUrl` / `imageUrls` | `number/array` | 🟢 High (100%) | Total photo count and array of direct, ready-to-open `800x600` image URLs. |
| `videoUrls` / `hasVideo` / `hasVirtualTour` | `array/boolean` | 🟢 High (100%) | Video tour links and virtual tour / floorplan availability flags. |
| `listingQualityScore` | `number` | 🟢 High (100%) | 0–100 listing completeness score. |
| `publishedAt` / `scrapedAt` | `string` | 🟢 High (100%) | Original listing creation timestamp and ISO-8601 extraction timestamp. |

***

### 📋 Sample JSON output

```json
{
  "recordType": "listing",
  "listingId": "2737644317",
  "portal": "VIVA_REAL",
  "url": "https://www.vivareal.com.br/imovel/imovel-id-2737644317/",
  "business": "SALE",
  "listingType": "USED",
  "usageType": "RESIDENTIAL",
  "unitType": "APARTMENT",
  "category": "residential",
  "subCategory": "apartamento",
  "priceBRL": 1200000,
  "condominioMonthlyBRL": 1100,
  "iptuYearlyBRL": 180,
  "pricePerSqmBRL": 11009,
  "usableArea": 109,
  "totalArea": 109,
  "bedrooms": 3,
  "bathrooms": 3,
  "suites": 1,
  "parkingSpaces": 2,
  "uf": "SP",
  "city": "São Paulo",
  "neighborhood": "Jardim Arpoador",
  "zone": "Zona Oeste",
  "street": "Rodovia Raposo Tavares",
  "streetNumber": "7389",
  "zipCode": "05577200",
  "latitude": -23.58413,
  "longitude": -46.775581,
  "amenities": ["POOL", "GYM", "GATED_COMMUNITY", "SAUNA", "PLAYGROUND", "CONCIERGE_24H", "ELEVATOR", "PETS_ALLOWED"],
  "isLancamento": false,
  "isFiadorFree": false,
  "acceptsExchange": false,
  "isFinancing": false,
  "isFGTSEligible": false,
  "isMCMVEligible": false,
  "agencyId": "06e526ae-f09a-bfd2-2a5b-89ef166eb990",
  "agencyName": "Alonso Imoveis",
  "agencyCRECI": "19917-J-SP",
  "agencyTier": "diamond",
  "agencyVerified": false,
  "publisherType": "agency",
  "publishedAt": "2024-08-26T18:41:27.228+00:00",
  "imageCount": 34,
  "thumbnailUrl": "https://resizedimgs.vivareal.com/img/vr-listing/a1187ff80760ede0377542e99241af2a/imovel.jpg?action=fit-in&dimension=800x600",
  "imageUrls": [
    "https://resizedimgs.vivareal.com/img/vr-listing/a1187ff80760ede0377542e99241af2a/imovel.jpg?action=fit-in&dimension=800x600"
  ],
  "hasVideo": false,
  "hasFloorplan": false,
  "hasVirtualTour": false,
  "listingQualityScore": 45,
  "searchBusiness": "SALE",
  "searchState": "SP",
  "searchCity": "sao-paulo",
  "scrapedAt": "2026-11-10T02:30:00.000Z"
}
```

***

### 🔁 Pagination & 1,000+ scaling

- **Unlimited Page Traversal by Default (`maxPages: 0`):** The actor steps through result pages in increments of `pageSize` (default `24`, configurable up to `100`) and continues until `totalSaved` reaches your `maxListings` target or the portal reports no further listings.
- **Multi-Combination Matrix:** Selecting multiple `states`, `cities`, `neighborhoods`, or `business` types automatically builds a task queue for every combination and deduplicates records globally on `listingId`.
- **High-Speed Execution:** Because the actor communicates directly with the structured JSON backend without launching a headless browser, pulling 100 listings takes **~10–15 seconds**, and **1,000+ listings** finish in just a couple of minutes.

***

### 💻 API & integration examples

#### Python (`apify-client`)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/vivareal-scraper").call(run_input={
    "mode": "listings",
    "portal": "VIVA_REAL",
    "business": ["SALE"],
    "states": ["SP"],
    "cities": ["sao-paulo"],
    "neighborhoods": ["pinheiros", "vila-madalena"],
    "maxListings": 1000,
    "maxPages": 0,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["listingId"], item["neighborhood"], item["priceBRL"], item["pricePerSqmBRL"])
```

#### Node.js (`apify-client`)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/vivareal-scraper').call({
    mode: 'listings',
    portal: 'VIVA_REAL',
    business: ['RENTAL'],
    states: ['RJ'],
    cities: ['rio-de-janeiro'],
    maxListings: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Extracted ${items.length} Rio de Janeiro rentals`);
```

***

### 💡 Pro tips for best results

- **Keep the Brazilian Residential Proxy enabled:** VivaReal geo-fences and rate-limits non-Brazilian datacenter traffic. The default `proxyConfiguration` (`RESIDENTIAL`, country `BR`) ensures near-100% request reliability.
- **Segment large metro pulls by `neighborhoods`:** When pulling 5,000+ listings in megacities like São Paulo or Rio de Janeiro, passing a list of target `bairros` (`pinheiros`, `moema`, `itaim-bibi`, `perdizes`, `brooklin`) gives deeper coverage per submarket.
- **Use `totalMonthlyCostBRL` for rental comparisons:** In Brazil, a lower base rent often hides a high `condomínio`. Always compare rentals using `totalMonthlyCostBRL`.
- **Switch `portal: "ZAP"` for cross-portal coverage:** Run the same search against both `VIVA_REAL` and `ZAP` and merge on `listingId` to capture exclusive listings across the OLX Brasil / Grupo ZAP network.

***

### ⚠️ Known limitations

- **Residential proxy requirement:** Running without a Brazilian residential proxy (`apifyProxyCountry: "BR"`) will frequently trigger HTTP 403/503 blocks from the portal's edge firewall.
- **Feed vs. Agency Directory contact fields:** In `listings` mode, the search feed provides `agencyId`, `agencyName`, and `agencyCRECI` (~88%), while full agency contact details (`agencyCNPJ`, `agencyEmail`, `agencyWebsite`) are populated in `agencies` (Agency Directory) mode.

***

### ❓ Frequently Asked Questions

#### How many listings can I scrape in one run?

Set `maxListings: 1000` (or `0` for unlimited). With `maxPages: 0` by default, the scraper automatically paginates through all available result pages until your `maxListings` target is met.

#### What is the difference between `bedrooms` (`quartos`) and `suites` (`suítes`)?

`bedrooms` is the total number of bedrooms in the property, while `suites` is the subset of bedrooms that have a private en-suite bathroom (e.g., 3 quartos / 1 suíte = 3 bedrooms total, 1 of which is en-suite).

#### Do the extracted image URLs work directly?

Yes. VivaReal stores image URLs with unexpanded template variables (`{action}/{width}x{height}`); this actor automatically resolves every URL into a direct, ready-to-load `800x600` JPEG link and separates video links into `videoUrls`.

#### Can I scrape commercial offices, warehouses, and land lots?

Yes. Set `usageTypes: ["COMMERCIAL"]` or select specific `unitTypes` such as `OFFICE` (`Sala Comercial`), `COMMERCIAL_BUILDING` (`Prédio`), `WAREHOUSE_SHED` (`Galpão`), `LAND_LOT` (`Terreno`), or `FARM` (`Fazenda`).

***

### 🔗 Related scrapers

- [ZAP Imóveis Scraper (Brazil)](https://apify.com/haketa/zapimoveis-scraper) — Dedicated scraper for ZAP Imóveis Brazil.
- [OLX Brasil Scraper](https://apify.com/haketa/olx-brasil-scraper) — Brazil's largest classifieds and property marketplace.
- [QuintoAndar Scraper](https://apify.com/haketa/quintoandar-scraper) — Brazil's leading proptech rental and sale platform.
- [Realtor.ca Scraper (Canada)](https://apify.com/haketa/realtor-ca-scraper) — Canadian MLS real estate listings.
- [Domain.com.au Scraper (Australia)](https://apify.com/haketa/domain-com-au-scraper) — Australian property listings and agency data.

***

### 📋 Changelog

| Version | Date | Highlights |
| --- | --- | --- |
| **v1.2** | `2026-11` | **Unlocked 1,000+ deep pagination:** Changed `maxPages` default from `20` to `0` (unlimited, governed by `maxListings`), raised `pageSize` maximum to `100`, added `maxItems` / `maxRecords` input alias support, and added explicit run completion status messages. |
| **v1.1** | `2026-11` | Separated video walkthrough URLs (`videoUrls`) from photo galleries (`imageUrls`), expanded `propertyDevelopers` extraction for `lançamentos`, and normalized `listingQualityScore` to 0–100. |
| **v1.0** | `2026-06` | Initial release supporting VivaReal and ZAP Imóveis listings and Agency Directory mode. |

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/vivareal-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Property Listings = search homes, apartments, commercial units and new developments. Agency Directory = pull imobiliária (real estate agency) profiles with license, tax ID and contact details for B2B lead generation.

## `portal` (type: `string`):

Which portal to pull from. Both share the same listings backend.

## `business` (type: `array`):

Choose Sale, Rental, or leave empty to get both.

## `listingType` (type: `array`):

Used = standard resale/rental inventory. Development = lançamentos, brand-new developer projects (Cyrela, EZTec, Tegra, etc). Leave empty for both.

## `usageTypes` (type: `array`):

Residential (apartments, houses, penthouses) or Commercial (offices, retail, warehouses). Leave empty for both.

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

Pick one or more property types. Leave empty to include all types.

## `states` (type: `array`):

Choose one or more Brazilian states. Leave empty to search nationwide.

## `cities` (type: `array`):

Choose one or more major cities. Leave empty to search the whole state (or nationwide). For a city not listed here, add it in 'More cities (advanced)' below.

## `citiesCustom` (type: `array`):

Optional. Add any other city by its URL slug: lowercase, hyphenated, no accents (e.g. 'sao-bernardo-do-campo', 'foz-do-iguacu'). These are searched in addition to the cities picked above.

## `neighborhoods` (type: `array`):

Optional. Narrow to specific bairros by slug: lowercase, hyphenated, no accents (e.g. 'pinheiros', 'itaim-bibi', 'copacabana'). Works best with a single city selected.

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

Minimum price in Brazilian Reais. 0 = no minimum.

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

Maximum price in Brazilian Reais. 0 = no maximum.

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

Minimum usable area in square meters. 0 = no minimum.

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

Maximum usable area in square meters. 0 = no maximum.

## `minBedrooms` (type: `integer`):

Minimum number of bedrooms (quartos). 0 = any.

## `minParkingSpaces` (type: `integer`):

Minimum number of parking spaces (vagas). 0 = any.

## `semFiador` (type: `boolean`):

Only show rentals that don't require a fiador (guarantor).

## `sortBy` (type: `string`):

How to order the results.

## `agencyIds` (type: `array`):

Optional. Only used in Agency Directory mode. Provide specific imobiliária IDs to pull. Leave empty to use an ID range instead.

## `agencyIdRangeStart` (type: `integer`):

Optional. Agency Directory mode only. Start of a sequential agency ID range to discover agencies. 0 = disabled.

## `agencyIdRangeEnd` (type: `integer`):

Optional. Agency Directory mode only. End of the sequential agency ID range. Must be greater than the start. 0 = disabled.

## `fetchAgencyListings` (type: `boolean`):

Agency Directory mode only. When on, also pulls each agency's active property portfolio (slower). When off, saves profile details only.

## `maxListings` (type: `integer`):

Maximum number of records to collect in total. Set 0 for unlimited.

## `maxPages` (type: `integer`):

Maximum pages per search combination (~24 listings per page). Set 0 for unlimited (governed by Max results).

## `pageSize` (type: `integer`):

How many listings to fetch per request. Default 24.

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

A Brazilian residential proxy is strongly recommended for reliable results. The default uses Apify Proxy with the Residential group and Brazil country.

## `requestDelay` (type: `integer`):

Pause between requests in milliseconds. Increase if you hit rate limits.

## `maxConcurrency` (type: `integer`):

Number of searches to run in parallel. Keep low (1-2) for best reliability.

## `maxRetries` (type: `integer`):

Retry attempts per failed request.

## Actor input object example

```json
{
  "mode": "listings",
  "portal": "VIVA_REAL",
  "business": [
    "SALE"
  ],
  "listingType": [
    "USED"
  ],
  "usageTypes": [
    "RESIDENTIAL"
  ],
  "unitTypes": [],
  "states": [
    "SP"
  ],
  "cities": [
    "sao-paulo"
  ],
  "citiesCustom": [],
  "neighborhoods": [],
  "minPrice": 0,
  "maxPrice": 0,
  "minArea": 0,
  "maxArea": 0,
  "minBedrooms": 0,
  "minParkingSpaces": 0,
  "semFiador": false,
  "sortBy": "relevance",
  "agencyIds": [],
  "agencyIdRangeStart": 0,
  "agencyIdRangeEnd": 0,
  "fetchAgencyListings": false,
  "maxListings": 100,
  "maxPages": 0,
  "pageSize": 24,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BR"
  },
  "requestDelay": 800,
  "maxConcurrency": 1,
  "maxRetries": 3
}
```

# Actor output Schema

## `recordType` (type: `string`):

listing / agency

## `listingId` (type: `string`):

Internal listing or agency ID

## `portal` (type: `string`):

VIVA_REAL or ZAP

## `url` (type: `string`):

Full listing/agency URL

## `title` (type: `string`):

Listing or agency display title

## `description` (type: `string`):

Listing description text

## `business` (type: `string`):

SALE / RENTAL

## `listingType` (type: `string`):

USED / DEVELOPMENT (lançamento)

## `usageType` (type: `string`):

RESIDENTIAL / COMMERCIAL

## `unitType` (type: `string`):

APARTMENT / HOME / OFFICE / WAREHOUSE_SHED etc.

## `unitSubType` (type: `string`):

Sub-type (cobertura, kitnet, sala comercial...)

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

Normalized category (residential/comercial/...)

## `subCategory` (type: `string`):

Specific sub-category (sala-comercial, galpao...)

## `priceBRL` (type: `string`):

Listing price in Brazilian Reais

## `rentPeriod` (type: `string`):

MONTHLY / WEEKLY / DAILY (rentals only)

## `condominioMonthlyBRL` (type: `string`):

Monthly building maintenance fee

## `iptuYearlyBRL` (type: `string`):

Annual municipal property tax

## `totalMonthlyCostBRL` (type: `string`):

Derived: rent + condomínio + (IPTU/12)

## `pricePerSqmBRL` (type: `string`):

Derived: price / usable area

## `usableArea` (type: `string`):

Área útil

## `totalArea` (type: `string`):

Área total

## `bedrooms` (type: `string`):

Number of quartos

## `bathrooms` (type: `string`):

Number of banheiros

## `suites` (type: `string`):

Number of suítes

## `parkingSpaces` (type: `string`):

Vagas de garagem

## `uf` (type: `string`):

Brazilian state code

## `city` (type: `string`):

Cidade

## `neighborhood` (type: `string`):

Bairro

## `zone` (type: `string`):

Zona Sul/Norte/Leste/Oeste

## `street` (type: `string`):

Rua/Avenida

## `streetNumber` (type: `string`):

Number on street

## `zipCode` (type: `string`):

Postal code

## `latitude` (type: `string`):

Latitude coordinate

## `longitude` (type: `string`):

Longitude coordinate

## `amenities` (type: `string`):

Property amenities (comma separated)

## `buildingClass` (type: `string`):

A+/A/B+/B/C (CRE classification)

## `buildingName` (type: `string`):

Edifício/condomínio name

## `ceilingHeight` (type: `string`):

Pé direito in meters

## `isCommercialCondo` (type: `string`):

Part of commercial business park

## `zoning` (type: `string`):

Zoning code (comercial/industrial/misto)

## `isLancamento` (type: `string`):

New development listing

## `launchName` (type: `string`):

Developer project name

## `launchPhase` (type: `string`):

Pré-lançamento/Lançamento/Em obras/Pronto

## `constructorName` (type: `string`):

Constructora (Cyrela, EZTec, Tegra...)

## `constructorCNPJ` (type: `string`):

Constructor Brazilian tax ID

## `deliveryDate` (type: `string`):

Estimated delivery

## `totalUnits` (type: `string`):

Project total unit count

## `isFiadorFree` (type: `string`):

Rental without guarantor requirement

## `acceptsExchange` (type: `string`):

Accepts property exchange

## `isFinancing` (type: `string`):

Bank financing accepted

## `isFGTSEligible` (type: `string`):

Eligible for FGTS withdrawal usage

## `isMCMVEligible` (type: `string`):

Minha Casa Minha Vida program eligible

## `agencyId` (type: `string`):

Imobiliária ID

## `agencyName` (type: `string`):

Imobiliária name

## `agencyCRECI` (type: `string`):

CRECI registration (J = jurídica)

## `agencyCNPJ` (type: `string`):

Brazilian corporate tax ID

## `agencyPhone` (type: `string`):

Contact phone

## `agencyEmail` (type: `string`):

Contact email

## `agencyWebsite` (type: `string`):

Corporate website

## `agencyAddress` (type: `string`):

Agency physical address

## `agencyLogoUrl` (type: `string`):

Logo image URL

## `agencyTier` (type: `string`):

Free / Premium / Premium+

## `agencyVerified` (type: `string`):

Verification badge

## `agencyEstablishedYear` (type: `string`):

Year founded

## `agencyTotalListings` (type: `string`):

Active listing count

## `agencyServiceAreas` (type: `string`):

Cities/bairros served (comma separated)

## `agencySpecializations` (type: `string`):

Residencial/Comercial/Luxo/Litoral

## `agencyBranchCount` (type: `string`):

Number of branches

## `publisherType` (type: `string`):

Owner / Agency

## `publishedAt` (type: `string`):

First published timestamp

## `updatedAt` (type: `string`):

Last updated timestamp

## `imageCount` (type: `string`):

Total images

## `thumbnailUrl` (type: `string`):

First image URL

## `imageUrls` (type: `string`):

All images (comma separated)

## `videoUrls` (type: `string`):

Video tour URLs

## `hasVideo` (type: `string`):

Has video tour

## `hasFloorplan` (type: `string`):

Has floorplan image

## `hasVirtualTour` (type: `string`):

Has 3D virtual tour

## `listingQualityScore` (type: `string`):

Derived quality score 0-100

## `searchBusiness` (type: `string`):

Business filter used in search

## `searchState` (type: `string`):

UF used in search

## `searchCity` (type: `string`):

City slug used in search

## `searchNeighborhood` (type: `string`):

Bairro slug used in search

## `scrapedAt` (type: `string`):

ISO timestamp when 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 = {
    "business": [
        "SALE"
    ],
    "listingType": [
        "USED"
    ],
    "usageTypes": [
        "RESIDENTIAL"
    ],
    "unitTypes": [],
    "states": [
        "SP"
    ],
    "cities": [
        "sao-paulo"
    ],
    "citiesCustom": [],
    "neighborhoods": [],
    "agencyIds": [],
    "maxListings": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "BR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/vivareal-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 = {
    "business": ["SALE"],
    "listingType": ["USED"],
    "usageTypes": ["RESIDENTIAL"],
    "unitTypes": [],
    "states": ["SP"],
    "cities": ["sao-paulo"],
    "citiesCustom": [],
    "neighborhoods": [],
    "agencyIds": [],
    "maxListings": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "BR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/vivareal-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 '{
  "business": [
    "SALE"
  ],
  "listingType": [
    "USED"
  ],
  "usageTypes": [
    "RESIDENTIAL"
  ],
  "unitTypes": [],
  "states": [
    "SP"
  ],
  "cities": [
    "sao-paulo"
  ],
  "citiesCustom": [],
  "neighborhoods": [],
  "agencyIds": [],
  "maxListings": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BR"
  }
}' |
apify call haketa/vivareal-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/vivareal-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/gW8mUpx0klw2b4gnB/builds/qGv2NfUJ0zDYieea3/openapi.json
