Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
VivaReal & ZAP Imóveis Scraper icon

VivaReal & ZAP Imóveis Scraper

Scrape Brazilian real estate listings from VivaReal and ZAP Imóveis: price, condo fee, IPTU, area, rooms, address, coordinates, advertiser and photos.

29 runs on Apify $0.0014 per property ($1.4 / 1,000)
Run this in the cloudRun on Apify →

Developer & Research Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust location, portal, business (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.0014 per property = $1.4 per 1,000

You are charged forWhenPrice
Property returnedOne property listing returned in the dataset. Diagnostic rows and the labelled sample row are not charged.$0.0014

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-20, and they are what you are actually charged.

Inputs

FieldWhat it doesType
locationA Brazilian city or neighbourhood, written the way it is written there: "Pinheiros, São Paulo", "Copacabana, Rio de Janeiro", "Curitiba", "Balneário Camboriú". The portal's own place lookup decides the match, and the run log tells you which one it picked.string
portalVivaReal and ZAP Imóveis run on one shared listing index, so both return the same properties. This only decides which site the listing URL points at, and the order results come back in.string
businessSale (venda) or rental (aluguel). Rental rows also carry the monthly total with condo fee and IPTU added.string
listingTypeUSED is the ordinary resale market. DEVELOPMENT is new-build launches (lançamentos), a much smaller pool — a few thousand nationally rather than millions.string
maxItemsHard cap on rows across every search in this run (1–5000). You are charged per listing returned. Sample and diagnostic rows are never charged.integer
startUrlsPaste search pages or single listing pages from either portal. A search page works best when it still carries its "?onde=" parameter — that is where the portal keeps the place id. A single listing page must end in -id-<number>/.array
unitTypesLeave empty for everything. These are the portal's own codes.array
bedroomsMinMinimum number of bedrooms (quartos).integer
bathroomsMinMinimum number of bathrooms (banheiros).integer
parkingMinMinimum number of parking spaces (vagas).integer
priceMinSale price, or monthly rent when you are searching rentals.integer
priceMaxSale price, or monthly rent when you are searching rentals.integer
areaMinMinimum área útil in square metres.integer
areaMaxMaximum área útil in square metres.integer
locationIdsFor repeat runs where you already know the exact place. These look like BR>Sao Paulo>NULL>Sao Paulo>Zona Oeste>Pinheiros and appear in the run log whenever a location is resolved. Using them skips the place lookup and guarantees the same area every time.array

What you get

A structured dataset — each result includes fields like:

imageUrltitlepricecondoFeeiptuusableAreabedroomsbathroomsparkingSpacesneighborhoodcitystateAcronymadvertiserTypeadvertiserNameupdatedAturllistingId

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

Related tools in Developer & Research Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

GitHub Scraper iconDeveloper & Research Tools

GitHub Scraper

Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.

18 use cases

Stack Overflow / Stack Exchange Scraper iconDeveloper & Research Tools

Stack Overflow / Stack Exchange Scraper

Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.

2 use cases

Package Registry Scraper (npm + PyPI) iconDeveloper & Research Tools

Package Registry Scraper (npm + PyPI)

Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.

2 use cases

arXiv Scraper iconDeveloper & Research Tools

arXiv Scraper

Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.

2 use cases

OpenAlex Scholarly Works Scraper iconDeveloper & Research Tools

OpenAlex Scholarly Works Scraper

Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.

2 use cases

Crossref Scholarly Works Scraper iconDeveloper & Research Tools

Crossref Scholarly Works Scraper

Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.

2 use cases

See all Developer & Research Tools →

VivaReal & ZAP Imóveis Scraper — Brazilian property listings

Point it at a Brazilian city or neighbourhood and it returns one row per property advert: asking price, condomínio, IPTU, área útil, bedrooms, bathrooms, parking, the full address with coordinates, the amenity list, who is advertising it, every photo and the link back to the listing. Sale and rental both work.

Start with the limit, because it decides whether this is the right tool for you: the portals stop paging any single search at 1,500 results. Ask for São Paulo and you will get 1,500 rows out of the million-plus that exist. That is the portal's own window, not a setting here, and no scraper gets past it. The way round it is to split the job by neighbourhood, by price band or by property type, then run several searches. A Pinheiros three-bedroom search between R$800k and R$1.5m comes back complete. "Every flat in Brazil" does not.

What one row looks like

Real row, trimmed to the interesting parts, pulled on 19 September 2026:

{
  "listingId": "2814207417",
  "portal": "VivaReal",
  "url": "https://www.vivareal.com.br/imovel/apartamento-2-quartos-pinheiros-zona-oeste-sao-paulo-com-garagem-85m2-venda-RS2650000-id-2814207417/",
  "title": "Apartamento com 2 Quartos à venda, 85m²",
  "businessType": "SALE",
  "listingType": "USED",
  "currency": "BRL",
  "price": 2650000,
  "condoFee": 2060,
  "iptu": 890,
  "iptuPeriod": "YEARLY",
  "usableArea": 85,
  "bedrooms": 2,
  "bathrooms": 1,
  "suites": 0,
  "parkingSpaces": 1,
  "unitFloor": 13,
  "amenities": ["POOL", "GYM", "ELEVATOR", "BARBECUE_GRILL", "GATED_COMMUNITY"],
  "street": "Rua Dona Ana Neri",
  "streetNumber": "581",
  "neighborhood": "Pinheiros",
  "zone": "Zona Oeste",
  "city": "São Paulo",
  "stateAcronym": "SP",
  "zipCode": "01522000",
  "latitude": -23.559503,
  "longitude": -46.615471,
  "advertiserType": "agency",
  "advertiserName": "Santucci Broker Negócios Imobiliários",
  "advertiserLicense": "31016-J-SP",
  "phones": ["11999782608"],
  "whatsapp": "11999782608",
  "imageCount": 30,
  "createdAt": "2024-05-29T20:07:12.572Z",
  "updatedAt": "2026-08-26T17:47:06.754Z"
}

Rentals carry two extra numbers that matter in Brazil: price is the monthly rent on its own and rentalTotalPrice is what the tenant actually pays each month once condomínio and IPTU are added. Measured on a Pinheiros rental pull: R$12,800 rent, R$14,860 total. Budget filters that ignore the condomínio are why so many Brazilian rental searches lie to you.

Input

Everything except the place is optional.

{
  "location": "Pinheiros, São Paulo",
  "portal": "vivareal",
  "business": "SALE",
  "listingType": "USED",
  "bedroomsMin": 3,
  "priceMin": 800000,
  "priceMax": 1500000,
  "maxItems": 200
}

location. Write it the way a Brazilian would: Pinheiros, São Paulo, Copacabana, Rio de Janeiro, Curitiba, Balneário Camboriú. A bare name is read as the city; add the city after a comma when you mean a neighbourhood. That matters more than it sounds, because São Paulo is also the name of a neighbourhood in Belo Horizonte. The run log names the place it picked on the first line, so a wrong match shows up there rather than in the data. Fifteen of fifteen test phrasings, accented and not, resolved to the place a person would have meant.

portal. VivaReal and ZAP Imóveis run on one shared listing index. Same properties, same ids, same prices. What changes is which site the url points at and the order results come back in. Pick whichever one your team already uses. Checked across eight identical searches on 19 September 2026: the match counts agreed to the row every time.

startUrls. Paste search pages or single listing pages from either site instead of filling in fields. A listing page has to end in -id-<number>/. A search page works best when it still has its ?onde= parameter, because that is where the portals keep the place id; copy the URL straight out of the address bar after you have run the search on the site and it will. A plain SEO path like /venda/sp/sao-paulo/zona-oeste/pinheiros/ also works, since the last part of the path gets sent through the place lookup, but that is a guess at your intent rather than a certainty.

Filters. bedroomsMin, bathroomsMin, parkingMin, priceMin, priceMax, areaMin, areaMax, unitTypes. These are applied by the portal, not filtered out afterwards, so the count in the log is the real count and you are not charged for rows that get thrown away. Verified: a three-bedroom search between R$800k and R$1.5m returned ten rows, all with exactly three bedrooms, all inside the band.

locationIds, for repeat runs. Once the log has told you that "Pinheiros, São Paulo" resolves to BR>Sao Paulo>NULL>Sao Paulo>Zona Oeste>Pinheiros, put that string here and the place lookup is skipped entirely. Same area every run, no ambiguity.

What you get charged for

One charge per listing row delivered. Nothing else bills:

  • An empty input writes a single labelled sample row and stops. Not charged.
  • A place the portal does not recognise writes a diagnostic row saying so. Not charged.
  • A URL that is not from either site writes a diagnostic row naming the URL. Not charged.
  • A search that finds nothing writes a diagnostic row. Not charged.
  • A refused request writes a diagnostic row after the retries run out. Not charged.

Diagnostic rows are marked _diagnostic: true and the sample row _sample: true, so a filter on those two fields separates paid rows from free ones. The rate itself is on the pricing tab of this page.

What this does not do

  • It cannot go past 1,500 rows in one search. Covered at the top; it is the single thing most

likely to surprise you.

  • The count in the log is the portal's index count, not the headline on the website. For

Pinheiros the index reports 45,589 matches while the site's own page says 23,566. The rows are real either way, and every one of them opens on the live site, but the two numbers are counted differently and I could not reproduce the site's arithmetic. Treat the log count as a rough sense of scale and the rows as the truth.

  • Neighbourhood searches bleed slightly into the neighbours. Over 270 Pinheiros rows, 261 were

in Pinheiros and 9 were in Cerqueira César, Butantã and Itaim Bibi. That is the portal's own behaviour, not a bug here. Every row carries neighborhood, so filter on it if you need a hard boundary.

  • No sold prices and no price history. The portals do not publish either. A row is what the

advert says today.

  • No login-only data. No saved searches, no lead forms, no messaging an advertiser, no account

of any kind is created or used.

  • About one row in four has no coordinates, and it varies a lot by city. Measured over 720 rows

across eight cities: 77% carried a point, from 49% in Belo Horizonte up to 92% in Curitiba. Some advertisers hide the exact position. latitude and longitude come back null rather than guessed, so a map build should expect to drop rows rather than plot a wrong pin.

  • advertiserType is agency, owner or null. It comes from the portal's own contract flag.

Over 240 sampled rows it read agency on 232 and owner on 8. Private sellers are genuinely rare on these two sites, which is worth knowing before you build a for-sale-by-owner pipeline on it.

  • New developments (lançamentos) are a small pool. Around 3,900 nationally against millions of

resale adverts. Set listingType to DEVELOPMENT and expect hundreds, not thousands.

  • Descriptions are the advertiser's text. HTML is stripped and line breaks kept; nothing is

summarised, translated or cleaned up beyond that.

Questions people actually ask

Is this the VivaReal API or the ZAP Imóveis API? Both, and it is the same one. The two portals are run by the same company on one shared listing index, which is why a listing id from one resolves on the other. The portal input decides which site's URLs you get back.

Can I scrape a whole city? Not in one go; see the 1,500 limit. Split it. For São Paulo, running one search per neighbourhood gets you a lot further than one search for the city, and running each of those split by price band gets you further again.

Do I need a Brazilian IP address, a proxy or an account? No. Leave the proxy field alone; the Actor handles its own routing and rotates to another address when the portal refuses one. If you have your own proxy servers and a reason to use them, put them in proxyConfiguration.proxyUrls and they will be used as-is.

How fresh is the data? Live at the moment of the run. Every row carries updatedAt from the advertiser's last edit, so you can tell a listing refreshed last week from one that has sat untouched since 2024.

Why did I get fewer rows than maxItems? Either the search genuinely has fewer matches (the log says how many the portal reports), or you hit the 1,500 window, or duplicate ids were dropped. The same property is sometimes advertised by several agencies; ids are deduplicated within a run, so you are charged once for it, not three times.

What currency are the prices in? Brazilian reais, always. currency is "BRL" on every row. price, condoFee and iptu are plain numbers with no formatting, so they go straight into a spreadsheet or a database column.

Can I get the advertiser's phone number? It is in phones and whatsapp when the advertiser published it, which is most of the time. It is the number shown on the public listing page, nothing more.

Does it work for commercial property and land? Yes. Set unitTypes to OFFICE, BUSINESS, COMMERCIAL_PROPERTY, COMMERCIAL_BUILDING, FARM or one of the land types. usageTypes on each row tells you RESIDENTIAL or COMMERCIAL.

Output fields

listingId · portal · url · title · description · businessType · listingType · propertyType · unitTypes · usageTypes · currency · price · rentalTotalPrice · rentalPeriod · condoFee · iptu · iptuPeriod · usableArea · totalArea · bedrooms · bathrooms · suites · parkingSpaces · unitFloor · amenities · street · streetNumber · neighborhood · zone · city · state · stateAcronym · zipCode · fullAddress · latitude · longitude · advertiserType · advertiserName · advertiserId · advertiserLicense · advertiserTier · phones · whatsapp · publicationType · status · imageUrl · imageCount · images · createdAt · updatedAt · searchLocation · position · scrapedAt

amenities is the portal's own code list: POOL, GYM, ELEVATOR, BARBECUE_GRILL, GATED_COMMUNITY and about 160 others. They are passed through untranslated so they stay stable across runs. advertiserLicense is the CRECI registration number where the advertiser is a licensed agency.