# OLX Brazil Scraper | Listings, Prices & Photos (`datascraperes/olx-brazil-listings-scraper`) Actor

Scrape OLX Brazil listings by search URL or keyword. Get BRL prices, locations, attributes and photos, with optional listing details and seller profile enrichment. Export JSON, CSV or Excel. Pay per saved listing; profile enrichment is an optional extra charge.

- **URL**: https://apify.com/datascraperes/olx-brazil-listings-scraper.md
- **Developed by:** [DataScraperES](https://apify.com/datascraperes) (community)
- **Categories:** E-commerce, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 listing saveds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Turn public **OLX Brazil listings into structured data** for property research and marketplace price comparisons. Paste an `olx.com.br` search URL or enter a keyword to collect titles, BRL prices, locations, attributes and photos, then export your results as JSON, CSV or Excel. Optional listing details add descriptions and photos. Seller profile enrichment is a separate opt-in charge.

### What this Actor does

OLX Brazil Scraper collects classified ads from OLX Brasil (`olx.com.br`) using search URLs, keywords, or a combination of both. A copied search URL keeps the category, location and filters you selected on OLX. General category URLs are also accepted: the Actor requests their listing results automatically, so you do not need to choose a subcategory first. The Actor follows available next-page links within your limits and saves one Dataset row per unique listing ID.

Prices include the displayed value and a numeric BRL amount when available. Each row keeps its source search URL and page number so you can trace the result. Start with search results only, or enable listing details for public descriptions and additional images. Enable `enrichProfiles` separately for available seller profile data. Request pacing and bounded retries are handled automatically.

### Use cases

- **Property research:** collect apartments and houses from an OLX property search and compare asking prices, neighborhoods, areas and room attributes when present.
- **Price comparisons:** export BRL prices and listing URLs from focused marketplace searches for analysis in a spreadsheet.
- **Inventory snapshots:** combine several search URLs or keywords into one Dataset, with duplicate listing IDs removed within the run.
- **Listing enrichment:** add available descriptions, images, basic seller information and postal codes; optionally enrich seller profiles separately.

### How to use

1. Open the Actor in Apify Console.
2. Add one or more OLX Brazil search URLs, text queries, or both, then choose a result and page limit.
3. Click **Start**, open the Dataset when the run finishes, and use **Export** to download JSON, CSV or Excel.

Use an OLX search URL when you need a category, location, filter, or sort already configured on OLX. Use `searchQueries` for a simple Brazil-wide text search. Start with a small `maxResults` value before scaling up, especially when `includeDetails` is enabled.

The initial form contains the property-search example below: up to three
listings, one page and details disabled. Replace the URL with your own search.
For a keyword-only search, remove the example URL before entering your query;
when both fields contain sources, the Actor collects from both.

### Input

| Field | Type | Required | Description |
|---|---|---:|---|
| `searchUrls` | array | No | OLX Brazil search-result URLs. Up to 1,000; fragments are removed and only OLX domains are accepted. |
| `searchQueries` | array | No | Text searches such as `iphone` or `apartamento`. Up to 1,000; each query becomes an OLX Brazil search URL. |
| `maxResults` | integer | No | Maximum unique listings saved across the run, from 1 to 10,000; default 100. |
| `maxPagesPerSearch` | integer | No | Maximum pages followed for each source, from 1 to 20; default 1. |
| `maxPagesTotal` | integer | No | Maximum pages requested across all sources, from 1 to 1,000; default 1,000. |
| `includeDetails` | boolean | No | Fetch listing-page descriptions, photos and available basic seller data; default `false`. |
| `enrichProfiles` | boolean | No | Enrich seller profiles for an extra charge per unique identifiable profile saved per run, according to your plan; default `false`. Independent of `includeDetails`. |

Request pacing and bounded retries are managed automatically by the Actor.

The small values initially shown in the form are an editable example.
The defaults in the table apply when those options are omitted from an input.

The run log shows search progress and distinguishes reviewed listings from
confirmed saved results. The final run message reports the number saved and
explains when access restrictions or your limits prevented further collection.

If both source arrays are empty, the Actor uses a small OLX property-search example. Duplicate URLs are removed before crawling. A challenge response is recorded as blocked and is never emitted as a listing.

Example input:

```json
{
  "searchUrls": [
    "https://www.olx.com.br/imoveis/venda/estado-sp"
  ],
  "maxResults": 3,
  "maxPagesPerSearch": 1,
  "maxPagesTotal": 1,
  "includeDetails": false,
  "enrichProfiles": false
}
```

### Output

Results are saved to the run's default Dataset, with one row per unique listing ID. JSON preserves nested objects such as location, attributes and seller data; CSV and Excel are available for spreadsheet workflows.

| Data | Fields and availability |
|---|---|
| Listing identity | `listingId`, `title`, `url` |
| Asking price | `price`, `priceDisplay`, `currency`; numeric values when parseable |
| Location and attributes | `location` and `attributes`; values depend on the listing |
| Images | `thumbnailUrl` and `photos`; additional images may be available with details enabled |
| Optional enrichment | `description`, `seller`, `sellerDetails`; only data returned by the public source |
| Coverage and provenance | `detailsStatus`, `sellerDetailsStatus`, `searchUrl`, `searchQuery`, `pageNumber`, `scrapedAt` |

With `includeDetails=true`, the Actor requests listing-page descriptions, images and basic seller data. With `enrichProfiles=true`, it independently requests available seller profile data and preserves complete source payloads in `sellerDetails`. Phone or email fields may be absent; contact information is not guaranteed or inferred. Unavailable enrichment keeps the base row and sets `detailsStatus` or `sellerDetailsStatus` to `blocked`, `partial`, or `error`. Profile data is not requested by default.

The normalized `seller.facebookId` is a string or `null`: integer identifiers are converted to text, and unsupported shapes become `null`. Original values remain unchanged in `sellerDetails`. Other seller fields retain their source-provided structure. In particular, `seller.score` is not normalized to a numeric rating; consumers should check its type before using it in calculations.

The following is a complete Dataset item from a successful run using the example input above:

```json
{
  "listingId": "1532746016",
  "title": "Apartamento à venda com 123m², 3 quartos e 2 vagas",
  "url": "https://sp.olx.com.br/sao-paulo-e-regiao/imoveis/apartamento-a-venda-com-123m-3-quartos-e-2-vagas-1532746016",
  "price": 1440000,
  "priceDisplay": "R$ 1.440.000",
  "currency": "BRL",
  "location": {
    "display": "São Paulo, Carandiru",
    "city": "São Paulo",
    "state": "SP",
    "neighborhood": "Carandiru",
    "postalCode": null
  },
  "attributes": [
    {
      "label": "area",
      "value": "123m²"
    },
    {
      "label": "bedrooms",
      "value": "4"
    },
    {
      "label": "bathrooms",
      "value": "3"
    },
    {
      "label": "parking",
      "value": "2"
    }
  ],
  "photos": [
    "https://img.olx.com.br/thumbs700x500/79/793603806921287.webp"
  ],
  "thumbnailUrl": "https://img.olx.com.br/thumbs700x500/79/793603806921287.webp",
  "description": null,
  "seller": null,
  "postedAtText": "Hoje, 08:43",
  "searchUrl": "https://www.olx.com.br/imoveis/venda/estado-sp",
  "searchQuery": null,
  "pageNumber": 1,
  "detailsCollected": false,
  "detailsStatus": "not_requested",
  "sellerDetails": null,
  "sellerDetailsStatus": "not_requested",
  "scrapedAt": "2026-09-05T11:54:23.170870+00:00"
}
```

Rows that fail output validation are omitted and counted in `SUMMARY.listingsRejected`; valid rows in the same batch can still be saved. Progress distinguishes processed rows from confirmed saved rows and pending rows. The result limit includes rejected rows.

The `SUMMARY` Key-Value Store record reports saved listings, duplicates, rejected rows, page limits and enrichment outcomes. Check it when a run returns fewer results than expected or a source is blocked.

### Pricing

You are charged once for each unique listing successfully saved to the Dataset.
The listing price includes optional listing-page details. A listing with partial
or unavailable details is still billable if its base row is saved. Seller profile
enrichment is a separate optional event.
Empty searches, blocked requests, duplicates, rejected rows and summaries do not
trigger a listing charge. There is no separate Actor-start fee.

| Apify tier | Price per listing (USD) | Equivalent per 1,000 listings (USD) |
|---|---:|---:|
| Free | $0.00100 | $1.00 |
| Bronze | $0.00090 | $0.90 |
| Silver | $0.00080 | $0.80 |
| Gold | $0.00075 | $0.75 |
| Platinum | $0.00075 | $0.75 |
| Diamond | $0.00075 | $0.75 |

When `enrichProfiles=true`, the **Seller profile enriched** event has the following additional price by plan:

| Apify tier | Price per enriched profile (USD) | Equivalent per 1,000 profiles (USD) |
|---|---:|---:|
| Free | $0.00100 | $1.00 |
| Bronze | $0.00090 | $0.90 |
| Silver | $0.00080 | $0.80 |
| Gold | $0.00075 | $0.75 |
| Platinum | $0.00075 | $0.75 |
| Diamond | $0.00075 | $0.75 |

A profile charge requires useful profile data with an unambiguous OLX `publicAccountId` to be saved in the Dataset. A partial profile is billable when it meets these conditions. The same seller is charged once per run even if present in several listings. Empty, blocked, unidentified or conflicting-identity profiles do not create this charge. Basic seller data from the listing page does not trigger the profile event. With `enrichProfiles=false`, no profile events are charged.

The actual charges are per saved listing and per unique enriched profile; the 1,000-unit columns are comparisons only. Apify applies your account tier automatically. Standard Actor execution
costs are included in the event price. Your maximum run charge can stop collection
before `maxResults` is reached; inspect `SUMMARY.budgetLimitReached`. The Actor conservatively reserves budget for both events before profile work, so a run may stop with some budget remaining. `SUMMARY.billingCharged` counts listing events and `SUMMARY.profilesCharged` counts profile events.

### Related Actors

| Actor | Best for |
|---|---|
| [Realtor.com US Property Listings Scraper](https://apify.com/datascraperes/realtor-property-search) | Searching comparable property inventory across US cities, states, and ZIP codes. |
| [Fotocasa Spain Property Listings Scraper](https://apify.com/datascraperes/fotocasa-property-search-scraper) | Searching sale, rental, and shared-accommodation listings across Spain. |

### Limits and data quality

The Actor accepts up to 1,000 URLs and 1,000 queries, follows at most 20 pages per source and 1,000 pages per run, and saves at most 10,000 unique listings. Counts and fields depend on OLX's current public inventory and markup. Some listings may not publish a price, neighborhood, date, image, seller name, description, or postal code; missing values remain `null` or empty arrays.

HTTP 401, 403, 429, recognized Cloudflare challenge pages, and similar access failures are reported in `SUMMARY` and do not become Dataset rows. Search results are saved in batches of up to 50. Confirmed saved results remain available if a later page is blocked. A storage-write failure stops the run without automatically replaying an uncertain write. If a listing was saved but its charge response was lost, a resumed run retries that charge without writing the listing again. A write whose delivery cannot be confirmed requires investigation before resuming. When summary storage is available, `SUMMARY.status=failed` records the failure and `listingsPending` counts rows whose storage was not confirmed; consult the Dataset for actual rows. Run-level deduplication uses the listing ID from the public URL. Re-run the Actor when freshness matters, and use focused search URLs and small limits before broadening the collection.

A successful HTTP response does not guarantee successful enrichment. A detail
page without recognized listing content is recorded as a detail error while
the original search-result row is preserved.

Detail coverage can vary by category and page format. A successful result for
one search does not guarantee that every category exposes the same fields.

### Frequently asked questions

#### How do I scrape OLX Brazil property listings?

Open your property search on OLX, select the location and filters there, and copy the search-result URL into `searchUrls`. The example above uses properties for sale in São Paulo. Start with a small result limit and inspect the available attributes before collecting a larger sample.

#### Can I use a copied OLX search URL?

Yes. Add it to `searchUrls`; category, location, query, filter, and sort parameters already present in the URL are preserved. Only OLX Brazil hostnames are accepted.

#### Can I export OLX listings to CSV, Excel or JSON?

Yes. Open the run's Dataset and choose **Export**. Use JSON to retain nested location, attribute and seller objects, or select CSV or Excel for a spreadsheet.

#### Do I need to configure request delays or retries?

No. The Actor manages these settings internally. You control the search sources, result and page limits, and whether to include details.

#### What does `includeDetails` add?

It adds available descriptions, full image URLs, basic seller display data and structured location from the public listing page. It does not activate paid profile enrichment.

#### How do I enable seller profile enrichment?

Select `enrichProfiles`. It works with listing details on or off and adds a charge per unique identifiable seller profile saved in the run at your plan's price (see Pricing). Available phone, email and other fields are preserved without guarantees. Partial profile data can be billable; repeated sellers, empty results, blocked requests and profiles without an unambiguous public seller ID do not create additional profile charges.

#### Does this Actor track price drops or return historical prices?

Each run collects the prices currently displayed in its search results. To study changes, retain separate exports and compare listings by `listingId`. The Actor does not produce a price-history dataset or calculate price-drop alerts.

#### Why did a run save fewer listings than expected?

The public search may contain fewer matching listings, the result or global page limit may have been reached, duplicate listing IDs may have been skipped, or OLX may have returned a challenge. Inspect `SUMMARY` to distinguish these cases; a global page cap is reported with `pagesLimitReached` and a partial run status.

#### Can I submit a large batch of sources?

Yes. Submit up to 1,000 search URLs and 1,000 text queries. For predictable runtime and request volume, set `maxPagesTotal` together with `maxResults`; Dataset rows are deduplicated and saved incrementally during the run.

### Responsible use

Use public marketplace data responsibly. You are responsible for complying with applicable laws, privacy and data-protection requirements, and OLX's terms and applicable restrictions. Do not use the Actor to collect or republish personal data in ways that violate those requirements.

### Support

Open an issue in the Actor's **Issues** tab and include a reproducible input and run ID. Mention the affected OLX search URL, expected result, and observed result so the issue can be investigated.

[GitHub: Python examples and CSV exports](https://github.com/datacrawler-edu/olx-brazil-listings-python)

# Actor input Schema

## `searchUrls` (type: `array`):

Paste search-result URLs copied from OLX Brazil to keep your category, location and filters. Replace the example URL with your own, or remove it when searching only by keyword.

## `searchQueries` (type: `array`):

Optional keywords searched across Brazil, for example iphone or apartamento. When URLs are also entered, both sets of searches run. Clear the example URL for a keyword-only search.

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

Hard limit for unique listings saved across the whole run.

## `maxPagesPerSearch` (type: `integer`):

Follow OLX's next-page link up to this many pages for each search URL or generated query URL.

## `maxPagesTotal` (type: `integer`):

Global safety limit for pages requested across all search URLs and generated query URLs. Use this to control runtime and request volume for large batches.

## `includeDetails` (type: `boolean`):

Add available listing descriptions, additional photos, basic seller information and postal location from the listing page. Profile endpoint enrichment is a separate optional setting.

## `enrichProfiles` (type: `boolean`):

Optional extra charge per unique seller profile per run: Free $0.001, Bronze $0.0009, Silver $0.0008, Gold/Platinum/Diamond $0.00075 when useful profile data with a public seller ID is saved. Partial profiles are billable; empty, blocked and unidentified profiles are not. Works independently of listing details. Disabled by default.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.olx.com.br/imoveis/venda/estado-sp"
  ],
  "maxResults": 3,
  "maxPagesPerSearch": 1,
  "maxPagesTotal": 1,
  "includeDetails": false,
  "enrichProfiles": false
}
```

# Actor output Schema

## `listings` (type: `string`):

Normalized public listing records saved by this run.

## `summary` (type: `string`):

Counts for saved, duplicate, blocked, detail, and HTTP requests.

# 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 = {
    "searchUrls": [
        "https://www.olx.com.br/imoveis/venda/estado-sp"
    ],
    "maxResults": 3,
    "maxPagesPerSearch": 1,
    "maxPagesTotal": 1,
    "includeDetails": false,
    "enrichProfiles": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascraperes/olx-brazil-listings-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 = {
    "searchUrls": ["https://www.olx.com.br/imoveis/venda/estado-sp"],
    "maxResults": 3,
    "maxPagesPerSearch": 1,
    "maxPagesTotal": 1,
    "includeDetails": False,
    "enrichProfiles": False,
}

# Run the Actor and wait for it to finish
run = client.actor("datascraperes/olx-brazil-listings-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 '{
  "searchUrls": [
    "https://www.olx.com.br/imoveis/venda/estado-sp"
  ],
  "maxResults": 3,
  "maxPagesPerSearch": 1,
  "maxPagesTotal": 1,
  "includeDetails": false,
  "enrichProfiles": false
}' |
apify call datascraperes/olx-brazil-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascraperes/olx-brazil-listings-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/LYuWJXnicLf4dRDZC/builds/EV5A9SAcOdO6VmXtX/openapi.json
