# OLX Brazil Scraper - Classified Ads, Prices & Sellers (`dami_studio/olx-brazil-scraper`) Actor

OLX Brazil scraper for classified ads on olx.com.br by Portuguese search term, state or category, or a pasted results page. Each row has the title, price in reais, category, city and state, publish date, photos, private or business seller, the ad's specs and link. $0.85 per 1,000 listings.

- **URL**: https://apify.com/dami_studio/olx-brazil-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** E-commerce, Real estate, Lead generation
- **Stats:** 3 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.82 / 1,000 listings

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?

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

**OLX Brazil scraper for olx.com.br searches by term, state or category, or a results page, one row per ad**:
id, title, price in reais, category, city and state, publish date, photos, whether the seller is
private or a business, and the link.

The awkward part first. There are no seller phone numbers. OLX keeps them off the results pages this
reads, and the run does not go hunting for them elsewhere. The seller's public display name and
whether they are private or a business is what you get.

| | |
|---|---|
| **Input** | Portuguese search terms, or OLX search and category URLs |
| **Output** | One row per listing: title, price in reais, category, city and state, publish date, photos, seller type, the ad's spec block and link |
| **Ceiling** | 5,000 listings per run. About 5,000 per search is OLX's own limit. A run stops a little before its time limit and keeps the listings it has delivered |
| **Account needed** | None |
| **Price** | $0.85 per 1,000 listings on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 5,800 |

### 🔍 What OLX Brazil Scraper does

Fill in the form, paste links, or do both in one run. The form is a search term plus any mix of
state, region, category, price band and sort order. A pasted URL keeps every filter already on it,
so a search you set up in OLX's own interface carries over exactly as you left it.

Results pages only. A search page, a category page, a state page. A single ad URL is not one of
those and comes back as an uncharged diagnostic row saying so.

`region` narrows inside a state, using the slug OLX prints in its own URLs, like
`sao-paulo-e-regiao`. Two things about it. It needs a state to work against, and OLX ignores a slug
it does not recognise without saying so, handing back the whole state with no error. The run checks
the rows it got against the region you asked for, and if they do not match it adds one uncharged row
naming slugs that would have worked.

Listings are de-duplicated on `listingId` across the whole run, so the same ad found under two
searches is delivered and billed once.

### 📋 What data you get from each OLX ad

| What you get | Field |
|---|---|
| Ad id, title and link | `listingId`, `title`, `url` |
| Price as a number and as shown, any earlier price, and the currency | `price`, `priceLabel`, `oldPrice`, `oldPriceLabel`, `currency` |
| Category | `category`, `categoryId`, `parentCategoryId` |
| Where it is | `city`, `state`, `stateName`, `neighbourhood`, `areaCode`, `locationLabel` |
| When it was published | `publishedAt`, `publishedTimestamp` |
| The seller | `sellerType`, `sellerName` |
| Photos and video | `thumbnailUrl`, `imageUrls`, `imageCount`, `hasVideo` |
| Paid promotion and shipping flags | `isFeatured`, `isBumped`, `hasFreeShipping` |
| The spec block on the ad | `attributes` |
| Which of your searches found it, and where it sat | `searchQuery`, `searchUrl`, `page`, `position` |

### ▶️ How to scrape OLX Brazil listings

1. Open [OLX Brazil Scraper](https://apify.com/dami_studio/olx-brazil-scraper) and click
   **Try for free**.
2. Type a term into **Search terms**, or paste links into **OLX search URLs**.
3. Pick a **State (UF)** and a **Category** if you want to narrow it, and set a price band.
4. Set **Maximum listings**. Around 20 is enough to see what the rows look like.
5. Click **Start**, then download the dataset as JSON, CSV or Excel.

Run it with nothing to search and you get one labelled sample row, which is not billed.

### 💰 How much does it cost to scrape OLX Brazil listings?

**$0.85 per 1,000 listings** on the Free plan. Paid plans pay a little less: $0.84 on Starter, $0.83 on Scale and $0.82 on Business. On the free plan, the $5
Apify gives you each month covers about 5,800 listings.

One billed row per listing delivered. The sample row is not billed, diagnostic rows are not billed,
the region warning is not billed, and an ad found under two of your searches is billed once.

### 📥 What you give it

```json
{
  "searchQueries": ["notebook"],
  "state": "SP",
  "category": "informatica",
  "sortBy": "date",
  "minPrice": 500,
  "maxPrice": 3000,
  "maxItems": 250
}
```

| Field | Default | What it is |
|---|---|---|
| `searchQueries` | none | What to look for, one term per line. OLX indexes in Portuguese, so Portuguese terms return the most. |
| `startUrls` | none | OLX search or category pages pasted from the site. Works alongside the fields above. |
| `state` | all of Brazil | One Brazilian state, by two-letter code (`SP`, `RJ`) or full name. |
| `region` | none | A region slug from an OLX URL, to narrow inside a state. Needs a state set. |
| `category` | all categories | Pick one from the list, or type a category path you see in an OLX URL. |
| `sortBy` | `relevance` | OLX's own ordering. Also `date` for newest first, and `price_asc`. |
| `minPrice`, `maxPrice` | none | Price bounds in reais. |
| `maxItems` | `50` | Total listings across every search in the run, up to 5,000. |
| `proxyConfiguration` | none | Optional, under **Advanced**. Only if you want the run to go out through a network of your own. |

`maxItems` is a total, not a figure per search, so the first term in a long list can use the whole
allowance before the others get a turn. If you paste URLs and also pick a category in the form, the
category is not applied to the pasted links: their own paths win.

### 📤 What you get back

A real row from a run on 20 September 2026, with the `imageUrls` list cut short:

```json
{
  "listingId": "1536762825",
  "title": "iPhone 13",
  "price": 2000,
  "priceLabel": "R$ 2.000",
  "currency": "BRL",
  "oldPrice": null,
  "oldPriceLabel": null,
  "category": "Celulares e Smartphones",
  "categoryId": "3060",
  "parentCategoryId": "3000",
  "city": "Guaporé",
  "state": "RS",
  "stateName": "Rio Grande do Sul",
  "neighbourhood": null,
  "areaCode": "54",
  "locationLabel": "Guaporé - RS",
  "publishedAt": "2026-09-19T22:45:31.000Z",
  "publishedTimestamp": 1789857931,
  "sellerType": "private",
  "sellerName": "Luc...",
  "thumbnailUrl": "https://img.olx.com.br/images/17/173642924789016.jpg",
  "imageUrls": ["https://img.olx.com.br/images/17/173642924789016.jpg", "..."],
  "imageCount": 3,
  "hasVideo": false,
  "isFeatured": true,
  "isBumped": true,
  "hasFreeShipping": true,
  "attributes": {
    "Categoria": "Celulares e Smartphones",
    "Marca": "APPLE",
    "Modelo": "IPHONE 13",
    "Condição": "Usado - Excelente",
    "Memória interna": "128GB",
    "Cor": "Branco",
    "Saúde da bateria": "Boa (80% até 94%)",
    "Aceita trocas": "Não"
  },
  "url": "https://rs.olx.com.br/regioes-de-caxias-do-sul-e-passo-fundo/celulares/iphone-13-1536762825",
  "searchQuery": "iphone",
  "searchUrl": "https://www.olx.com.br/brasil?q=iphone",
  "page": 1,
  "position": 1,
  "scrapedAt": "2026-09-20T07:05:04.533Z"
}
```

| Field | How to read it |
|---|---|
| `price`, `priceLabel` | The number of reais, and OLX's own formatted string. |
| `oldPrice`, `oldPriceLabel` | Filled only when the seller cut the price. `null` otherwise. |
| `neighbourhood` | Only when the ad carries one. `null` on plenty of rows. |
| `areaCode` | The Brazilian DDD dialling code for the city. |
| `sellerType` | `private` or `business`, from OLX's own professional-ad flag. |
| `attributes` | The spec block OLX shows on the ad, keys in Portuguese. The keys differ per category: phones carry `Marca` and `Memória interna`, property carries `Quartos` and `IPTU`. |
| `isFeatured`, `isBumped` | Whether the seller paid to promote or re-float the ad. |

### 🧾 Reading the output

| Row | How to spot it | Billed |
|---|---|---|
| A listing | No `_sample` or `_diagnostic` key on it | yes |
| The sample row | `_sample: true` and `charged: false` | no |
| A diagnostic | `_diagnostic: true`, `ok: false`, `charged: false` and an `errorCode` | no |

Listing rows carry no `charged` field at all. The flag exists only on the sample and diagnostic
rows, to mark them as not real results. Filter on `_sample` and `_diagnostic` being absent.

| Code | What it means |
|---|---|
| `NO_RESULTS` | That search returned nothing. |
| `BAD_URL` | A pasted link that is not an OLX URL. |
| `NOT_A_SEARCH_URL` | An OLX URL, but a single ad page rather than a results page. |
| `REGION_NOT_APPLIED` | OLX did not recognise your region slug and returned the whole state. Sent once per run. |
| `HTTP_ERROR` | OLX answered with an error status. |
| `NOT_SERVED` | This listing was not served this run. Re-run it later. Runs before 13 October 2026 wrote `BLOCKED` here. |
| `PARSE_FAILED` | The page came back without the listing data in it. |
| `TIME_LIMIT` | The run reached its time limit, stopped a little before it and kept the listings it had delivered. Give it more time, or ask for fewer listings. |
| `UNEXPECTED_ERROR` | The run stopped early on an unexpected error. The results before this row are kept. |

One search failing never stops the others.

### 💡 What people use it for

- Price tracking for one model in one state on a schedule: sort by `date`, keep `maxItems` small,
  and diff on `listingId` to see what appeared and what sold.
- Property and rental research, where `attributes` carries `Quartos`, `Banheiros` and `IPTU`.
- Comparing the same search across several states in one run, since every row says which search and
  which URL produced it.

### 🚧 What it does not do

- **No seller phone numbers.** They are not on the pages this reads, and it does not go looking for
  them anywhere else.
- **No single ad pages.** Paste a search or category URL, not an ad URL. An ad URL comes back as an
  uncharged `NOT_A_SEARCH_URL` row.
- **No jobs.** `vagas-de-emprego` is a separate OLX product that renders differently and carries no
  listing data on the results page.
- **No "highest price first" sort.** OLX offers it in its own interface, but it cannot be requested
  here. Relevance, newest and lowest price all work.
- **About 5,000 listings per search is OLX's ceiling**, not ours. After page 100 OLX keeps handing
  back page 100. Split by state, category or price band to reach deeper stock.
- **A search can come back short.** If OLX stops serving pages partway through, the rows already
  collected are kept and the run moves on, and there is no row in the dataset marking where it
  stopped. Compare the count you asked for against the count you got.
- **Attribute keys are OLX's, not ours.** They are in Portuguese and they change per category, so do
  not hard-code them.
- It is not an official OLX tool. Dami's Studio is independent and is not affiliated with or endorsed by OLX, or by any other company named on this page.

### 🧭 Which marketplace scraper do you need?

| If you want | Use |
|---|---|
| Brazilian classified ads from OLX | This one |
| Brazilian car listings with prices against the FIPE table | [Webmotors Scraper](https://apify.com/dami_studio/webmotors-scraper) |
| Magalu products with card price, Pix price and seller | [Magazine Luiza Scraper](https://apify.com/dami_studio/magazine-luiza-scraper) |
| The deals board and best-seller lists on Mercado Libre | [Mercado Libre Scraper](https://apify.com/dami_studio/mercadolibre-scraper) |
| Russian classified ads from Avito | [Avito Listings Scraper](https://apify.com/dami_studio/avito-listings-scraper) |

### ❓ Questions people ask

#### Do I need an OLX account?

No. Nothing to register and nothing for you to set up.

#### Can I search OLX in English?

The term goes to OLX exactly as you typed it, and OLX's index is Portuguese, so English terms return
very little. State names do accept English spellings.

#### How do I get more than 5,000 listings for one term?

Split it up. Several states, several price bands, or narrower categories, all in the same run.

#### Why did my region get ignored?

OLX did not recognise the slug. Look for the uncharged `REGION_NOT_APPLIED` row: it lists slugs that
do work for that state.

#### Can I call it from code or connect it to an AI assistant?

The [API tab](https://apify.com/dami_studio/olx-brazil-scraper/api/python) has code for Python, JavaScript and the
CLI. MCP clients like Claude and ChatGPT use
`https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/olx-brazil-scraper`; coding assistants can load [our
skill file](https://api.apify.com/v2/key-value-stores/BTBHU3DdiuoF4JOsK/records/apify-classifieds-property-SKILL.md).
All three bill your Apify account at the same price.

#### Is scraping OLX legal?

These are public ads. They carry personal data, which GDPR and similar laws cover, so have a reason
for collecting it. Apify's write-up on
[the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a good starting
point, and we are not lawyers.

### 🆘 If something breaks

Open the **Issues** tab on the actor page. Send the search term or the URL you used and the run ID;
the `errorCode` on the diagnostic row usually names the problem on its own.

# Actor input Schema

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

What to look for on olx.com.br, one term per line. OLX is a Brazilian site, so Portuguese terms return the most ("iphone", "notebook", "bicicleta aro 29", "apartamento 2 quartos").

## `state` (type: `string`):

Optional. Limit the search to one Brazilian state. Accepts the two-letter code ("SP", "RJ", "MG") or the full name ("Sao Paulo"). Leave empty to search all of Brazil.

## `region` (type: `string`):

Optional. Narrows the search inside the state, using the region slug OLX shows in its own URLs, for example "sao-paulo-e-regiao", "rio-de-janeiro-e-regiao". Requires a state; ignored without one. OLX silently returns the whole state for a slug it does not recognise, so this Actor checks and adds one uncharged warning row listing the slugs that would have worked. Leave empty for the whole state.

## `category` (type: `string`):

Optional OLX category path. Pick one here, or type any path you see in an OLX URL (for example "imoveis/venda" or "autos-e-pecas/carros-vans-e-utilitarios").

## `maxItems` (type: `integer`):

Hard cap on rows returned across all searches (1-5000). You are charged per listing returned. OLX serves about 50 listings per page and stops paginating after page 100, so one search tops out near 5000 listings.

## `startUrls` (type: `array`):

Optional. Paste OLX search or category result pages and every filter already on the URL is kept, for example https://www.olx.com.br/celulares/estado-sp?q=iphone\&ps=1000\&pe=3000 . Works alongside the fields above. Single listing pages are not supported.

## `sortBy` (type: `string`):

How OLX orders the results. "Newest first" is the one to use for monitoring new listings.

## `minPrice` (type: `integer`):

Optional. Only return listings priced at or above this, in Brazilian reais.

## `maxPrice` (type: `integer`):

Optional. Only return listings priced at or below this, in Brazilian reais.

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

Optional. Leave this alone unless you need the run to go out through a particular network. Your own proxy servers are used exactly as given.

## Actor input object example

```json
{
  "searchQueries": [
    "iphone"
  ],
  "state": "",
  "category": "",
  "maxItems": 50,
  "startUrls": [],
  "sortBy": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One dataset row per OLX classified listing found. Empty input and failed searches produce an uncharged sample or diagnostic row instead.

# 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 = {
    "searchQueries": [
        "iphone"
    ],
    "maxItems": 50,
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/olx-brazil-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 = {
    "searchQueries": ["iphone"],
    "maxItems": 50,
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/olx-brazil-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 '{
  "searchQueries": [
    "iphone"
  ],
  "maxItems": 50,
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dami_studio/olx-brazil-scraper --silent --output-dataset

```

## MCP server setup

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