# QuintoAndar Property Listings Scraper (`bovi/quintoandar-scraper`) Actor

Extract public QuintoAndar sale/rental listings in Brazil. Get IDs, URLs, prices, locations, details, descriptions, amenities, images. Run with city slug and deal type; no login. Pricing: $0.0011 per saved listing + $0.00005 per Actor Start on Free.

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

## Pricing

from $1.10 / 1,000 quintoandar property listings scrapers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## QuintoAndar Property Listings Scraper

Extract public sale and rental property listings from QuintoAndar in Brazil, including listing IDs, public URLs, prices, locations, property details, descriptions, amenities, and image URLs. Each run reads one search page (up to 24 cards). No buyer account or login is required.

- Analyze Brazilian sale and rental inventory by city and optional neighborhood.
- Compare prices, area, rooms, parking spaces, and location fields.
- Build property datasets with listing IDs, detail URLs, descriptions, amenities, and images.
- Export the dataset as JSON or CSV, or read it through the Apify dataset API.

### What you get

| Field family | Fields | Type | What it contains |
|---|---|---|---|
| Record | `record_type`, `record_id` | string | Record type and listing identifier. |
| Source context | `source_url`, `source_name`, `source_domain`, `page_index` | string, integer | The search page source and page number. |
| Search seed | `source_context.seed.type`, `.value`, `.neighborhood` | string | The location search used; neighborhood only when supplied. |
| Source IDs | `source_context.external_ids.listing_id`, `entity.external_ids.listing_id` | string | Listing ID references. |
| Entity | `entity.title`, `entity.description`, `entity.url` | string | Listing title, source description, and public detail URL. |
| Listing | `listing.listing_id`, `listing.deal_type`, `listing.for_sale`, `listing.for_rent` | string, boolean | Listing identifier, selected mode, and sale or rental flags. |
| Listing descriptions | `listing.short_sale_description`, `listing.short_rent_description` | string | Short descriptions when supplied. |
| Pricing | `pricing.sale_price`, `pricing.rent_price`, `pricing.total_cost`, `pricing.condo_iptu`, `pricing.currency` | number, string | Sale and rent prices, total cost, condominium/IPTU value, and currency. |
| Location | `location.street_address`, `.neighborhood`, `.region`, `.city`, `.state`, `.country` | string | Address and geographic fields parsed from the listing. |
| Property details | `property.property_type`, `.area_sqm`, `.bedrooms`, `.bathrooms`, `.parking_spots`, `.furnished` | string, number, integer, boolean | Property type, area, rooms, parking, and furnished status. |
| Property lists | `property.amenities`, `.categories`, `.installations` | string arrays | Property and building feature lists. |
| Availability | `availability.visits_unavailable` | boolean | Whether visits are unavailable. |
| Media | `media.images`, `media.cover_image` | string array, string | Image URLs and the cover image URL. |
| Attributes | `attributes.listing_tags`, `.yield_strategy`, `.is_primary_market` | string array, string, boolean | Additional listing tags and source attributes. |

Fields that are not available on a particular listing may be absent from that record.

### Sample output

The sample is shortened: real records also carry `media` (images), `availability`, `attributes`, and the property arrays such as amenities.

```json
{
  "record_type": "property_listing",
  "record_id": "895772792",
  "source_context": {
    "source_url": "https://www.quintoandar.com.br/comprar/imovel/sao-paulo-sp-brasil",
    "source_name": "QuintoAndar",
    "source_domain": "quintoandar.com.br",
    "page_index": 1,
    "seed": {"type": "location", "value": "sao-paulo-sp-brasil"},
    "external_ids": {"listing_id": "895772792"}
  },
  "entity": {"external_ids": {"listing_id": "895772792"}, "title": "Apartamento com 2 dorms, 67m²", "description": "Venda de apartamento na Vila Ipojuca com varanda e 2 quartos.", "url": "https://www.quintoandar.com.br/imovel/895772792/comprar/apartamento-2-quartos-vila-ipojuca-sao-paulo"},
  "listing": {"listing_id": "895772792", "deal_type": "sale", "for_sale": true, "for_rent": false, "short_sale_description": "Venda de apartamento na Vila Ipojuca com varanda e 2 quartos.", "short_rent_description": ""},
  "pricing": {"sale_price": 1140000, "rent_price": 0, "total_cost": 1795, "condo_iptu": 1795, "currency": "BRL"},
  "location": {"street_address": "Rua Tonelero", "neighborhood": "Vila Ipojuca", "region": "Vila Romana", "city": "São Paulo", "state": "SP", "country": "BR"},
  "property": {"property_type": "Apartamento", "area_sqm": 67, "bedrooms": 2, "bathrooms": 2, "parking_spots": 2, "furnished": false}
}
```

### Pricing

You pay per event; the prices below are for the Apify Free plan.

- **Actor Start:** $0.00005 per event on the Free plan, charged on every run (one event per GB of memory, minimum one).
- **Saved dataset item:** $0.0011 per saved listing on the Free plan (one scraped result with all fields).

Each run saves at most 24 listings and triggers its own Actor Start event, so costs scale by runs:

- 24 listings with 1 start event: 24 x $0.0011 + 1 x $0.00005 = $0.02645 on the Free plan.
- 1,000 listings with 42 start events: 1,000 x $0.0011 + 42 x $0.00005 = $1.1021 on the Free plan.
- 10,000 listings with 417 start events: 10,000 x $0.0011 + 417 x $0.00005 = $11.02085 on the Free plan.

The $5 monthly platform usage credit of the Free plan covers about 189 full runs. Platform usage (compute, proxy, storage) is included in the event prices.

### How to use

1. **Choose** `sale` or `rent` for `dealType`.
2. **Enter** a QuintoAndar city location slug such as `sao-paulo-sp-brasil`.
3. **Add** a `neighborhood` value to narrow the city search.
4. **Set** `maxResults` to the number of records to save (at least 1).
5. **Configure** `proxyConfiguration` optionally. Leave it empty to connect directly.
6. **Start** the Actor and inspect the resulting dataset. Each run reads one location search page and saves records from that page up to `maxResults`.
7. **Repeat** the run with Apify Schedules to track listings over time.

```json
{
  "dealType": "sale",
  "city": "sao-paulo-sp-brasil",
  "neighborhood": "Vila Mariana",
  "maxResults": 24,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Input parameters

| Parameter | What it does | Default |
|---|---|---|
| `dealType` | Search route: `sale` or `rent`. | `sale` |
| `city` | Required QuintoAndar location slug used to build the search URL. | `sao-paulo-sp-brasil` |
| `neighborhood` | Optional neighborhood name, added to the search URL. | Empty |
| `maxResults` | Maximum listing records to save from the page (minimum 1). | `50` |
| `proxyConfiguration` | Optional Apify proxy settings; a proxy is used only when `useApifyProxy` is `true`. | `useApifyProxy: true`, group `RESIDENTIAL` |

### Limits and edge cases

| Condition | What the buyer sees | What to do |
|---|---|---|
| The source currently renders up to 24 cards on the location search page. | A run can save fewer than `maxResults`, even when `maxResults` is `50` or higher. | Use a different city or neighborhood search when you need a different result set. |
| The search page does not contain server-rendered listing records. | The Actor logs a warning and returns without saving records. | Check the city and optional neighborhood values, then run the search again. |
| A page entry has no listing ID. | That entry is skipped. | Use the remaining records. |
| All three page-fetch attempts fail. | The run raises a `RuntimeError` after the retries; nothing is saved. | Check the input location and optionally provide a valid `proxyConfiguration`, then rerun. |

### FAQ

#### How much does it cost to scrape QuintoAndar?

See Pricing above: you pay per saved listing plus an Actor Start event per run.

#### Why did my run return no records?

The search page had no server-rendered listing records. Check the city slug and optional neighborhood, then rerun.

#### Do I need a QuintoAndar account or login?

No. The Actor reads the public, server-rendered listing page.

#### Is it legal or allowed to use QuintoAndar public data?

The Actor reads public listing pages. Source terms and applicable law depend on your use case, so assess them before using the data.

### Related actors

- [Chaves na Mão Property Listings](https://apify.com/bovi/chaves-scraper) — another bovi Actor for property listings.
- [FincaRaíz Property Scraper](https://apify.com/bovi/fincaraiz-scraper) — another bovi property-listing scraper.
- [Metrocuadrado Scraper](https://apify.com/bovi/metrocuadrado-scraper) — another bovi Actor focused on property listings.

# Actor input Schema

## `dealType` (type: `string`):

Collect listings for sale or rent.

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

QuintoAndar location slug, for example sao-paulo-sp-brasil.

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

Optional neighborhood name within the selected city, for example Vila Mariana.

## `maxResults` (type: `integer`):

Maximum number of listing records to save from the search page.

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

Optional Apify proxy settings. Leave empty to connect directly.

## Actor input object example

```json
{
  "dealType": "sale",
  "city": "sao-paulo-sp-brasil",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset with the collected QuintoAndar listings.

# 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 = {
    "city": "sao-paulo-sp-brasil",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/quintoandar-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 = {
    "city": "sao-paulo-sp-brasil",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("bovi/quintoandar-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 '{
  "city": "sao-paulo-sp-brasil",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call bovi/quintoandar-scraper --silent --output-dataset

```

## MCP server setup

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