VivaReal & ZAP Imóveis Scraper - Brazil Property Data avatar

VivaReal & ZAP Imóveis Scraper - Brazil Property Data

Pricing

from $1.40 / 1,000 property returneds

Go to Apify Store
VivaReal & ZAP Imóveis Scraper - Brazil Property Data

VivaReal & ZAP Imóveis Scraper - Brazil Property Data

Brazilian property listings from VivaReal and ZAP Imóveis in one run: asking price, condo fee, IPTU, usable area, bedrooms, bathrooms, parking, full address, coordinates, amenities, advertiser and photos. Sale or rental, by city or neighbourhood. Pay only for listings returned.

Pricing

from $1.40 / 1,000 property returneds

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 hours ago

Last modified

Share

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.