VivaReal & ZAP Imóveis Scraper - Brazil Property Data
Pricing
from $1.40 / 1,000 property returneds
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 hours ago
Last modified
Categories
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 JaneiroCuritiba, 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.
latitudeandlongitudecome back null rather than guessed, so a map build should expect to drop rows rather than plot a wrong pin. advertiserTypeisagency,owneror 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
listingTypeto 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.