# OLX.uz Scraper (`lowlanddata/olx-uz-scraper`) Actor

Extract OLX.uz listings as clean JSON with zero seller personal data - prices in tiyin, full descriptions, city-level locations, business-vs-private flag. Price bands, newest-first monitoring, pay per result. Built for deal watching, market research and AI pipelines.

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

## Pricing

from $1.59 / 1,000 results

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

## OLX.uz Scraper — GDPR-safe listings data

Extract listings from **OLX.uz** — Uzbekistan's largest classifieds marketplace — as clean, structured JSON. Prices in UZS minor units, full descriptions, category attributes, city-level locations, photos and posting dates, ready for price monitoring, market research and data pipelines.

**No seller personal data, ever.** This scraper is built GDPR-first: seller names, profile photos, contact routes and exact map coordinates never appear in the output — not as an option you have to remember to switch off, but by design. The only seller information included is whether the listing comes from a business or a private seller.

### Quick start (30 seconds)

1. Put what you'd type in the OLX search box into **searchQuery** — e.g. `velosiped`.
2. Click **Start**. That's the whole minimum setup.
3. When the run finishes, open the dataset's **Overview** tab for a clean table, or **Export** it as CSV/Excel/JSON.

Optional knobs: a price band in UZS, a `categoryId`, newest-first sorting for monitoring — and any input works on a daily Schedule.

### What you can build with it

- **Watch a niche for underpriced listings.** Run `searchQuery: "velosiped"` with `priceMax: 800` and `sortBy: "date"` hourly — every new listing arrives with `priceTiyin` parsed and `negotiable` flagged, ready for your deal filter.
- **Price a used car with real specs.** Category attributes come through per listing: year, mileage, fuel, transmission — a dataset of comparables with mileage and year, not just titles.
- **Map business vs. private supply.** The `sellerType` flag on every listing tells you how much of any category is professional traders — market structure no OLX page shows you.
- **Feed an AI agent clean data.** Every field is structured, predictable and free of personal data, so an assistant or pipeline can consume it directly — no scrubbing, no compliance review before you store it.

### What you get

Each listing is one dataset item:

```json
{
  "listingId": "1090000001",
  "url": "https://www.olx.uz/d/obyavlenie/tog-velosipedi-kross-level-3-CID767-ID14zZz1.html",
  "title": "Tog' velosipedi Kross Level 3, yangidek",
  "description": "Velosiped sotiladi, kam ishlatilgan, holati juda yaxshi.",
  "priceTiyin": 500000,
  "currency": "UZS",
  "negotiable": true,
  "postedAt": "2026-08-18T17:40:00+02:00",
  "refreshedAt": "2026-08-20T09:12:00+02:00",
  "city": "Toshkent",
  "region": "Toshkent shahri",
  "categoryId": 767,
  "attributes": { "state": "Ishlatilgan", "typ": "Tog' velosipedi" },
  "sellerType": "private",
  "deliveryAvailable": true,
  "imageUrls": ["https://ireland.apollo.olxcdn.com/v1/files/example/image;s=1000x750"]
}
```

Category-specific specs come through in `attributes` — condition (`state`) on any item; year, mileage, fuel and transmission on vehicles; floor area and room count on property. Only a whitelist of non-personal attribute keys passes; anything else in the listing is dropped.

Field notes, so you know exactly what you are buying:

- `priceTiyin` is the asking price in tiyin (1/100 UZS), so `500000` = 5 000 som. Free give-aways carry no price.
- `postedAt` vs `refreshedAt`: sellers bump listings; `refreshedAt` is why an old listing can appear in a newest-first run.
- `city`/`region` are municipality-level. Exact coordinates exist in OLX's data and are deliberately never collected.
- `description` is the seller's full text with the site's HTML markup stripped to plain lines.
- `attributes` values are the site's Uzbek and Russian display labels — exactly what a local buyer sees.

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

$1.99 per 1,000 listings delivered, pay-as-you-go — no subscription, no charge for empty or failed runs. In plain dollars:

- **100 listings ≈ $0.20** — a daily niche watch.
- **500 listings ≈ $1.00** — a solid market snapshot.
- **A 5,000-listing crawl ≈ $9.95** — a full category across price bands, deduplicated.

The price is all-inclusive — your runs' platform usage is covered by it, no separate compute or proxy charges, even on large split crawls. Datacenter proxies are sufficient — no residential proxy surcharge needed.

Free-plan runs are limited to a sample of 25 items, enough to evaluate the output format against your real query.

### Not technical? Let your AI assistant set it up

Copy this into ChatGPT, Claude or any AI assistant, fill in the one line, and follow the conversation:

```text
Help me set up the "OLX.uz Scraper" actor on Apify
(https://apify.com/lowlanddata/olx-uz-scraper). Guide me one step at a time.

What I want to watch: [E.G. "bikes under 8000 sums in good condition"]

Guide me to:
1. Propose my input values: searchQuery (what I'd type in the OLX search box),
   an optional priceMin/priceMax band, sortBy "date" for newest-first
   monitoring, and maxItems.
2. Create a free Apify account (apify.com), open the actor page, paste the values
   into the Input form, and start a run.
3. Set up a daily Schedule in the Apify Console with the same input, plus an email
   or Slack integration so new results reach me automatically.
4. Show me how to export results as CSV/Excel, or read them from the API if I code.
5. If the results are what I wanted, remind me at the end to leave a quick rating on the actor page, and to report anything broken or missing on its Issues tab.
```

### Input

| Field                | Description                                                                                     |
| -------------------- | ----------------------------------------------------------------------------------------------- |
| `searchQuery`        | What you'd type in the OLX search box.                                                          |
| `categoryId`         | Numeric OLX category id to scope the search.                                                    |
| `priceMin`           | Only listings costing at least this many UZS.                                                   |
| `priceMax`           | Only listings costing at most this many UZS.                                                    |
| `sortBy`             | `date` (newest first, default), `price_asc`, `price_desc`, or `relevance`.                      |
| `postedAfter`        | Only listings posted on or after this date (YYYY-MM-DD). Stops early with newest-first sorting. |
| `postedBefore`       | Only listings posted on or before this date (YYYY-MM-DD).                                       |
| `maxItems`           | Stop after this many listings (default 1000).                                                   |
| `proxyConfiguration` | Proxy settings; keep Apify proxy enabled.                                                       |

A run minimally needs a `searchQuery` or a `categoryId`; invalid combinations (like an inverted price band) fail immediately with the reason in the run's status message.

#### Finding a category ID

Open the category on olx.uz and look for the id in the page URL, or run a broad search once — every scraped listing carries its `categoryId`, reusable as input for a scoped follow-up run.

### Use it from your code

Run the actor and get items straight back with one HTTP call (fine for scoped runs up to ~5 minutes):

```bash
curl "https://api.apify.com/v2/acts/lowlanddata~olx-uz-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"searchQuery": "velosiped", "maxItems": 100}'
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/olx-uz-scraper').call({
  searchQuery: 'velosiped',
  maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/olx-uz-scraper").call(
    run_input={"searchQuery": "velosiped", "maxItems": 100})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

For large split crawls, start the run asynchronously and fetch the dataset when the finished-run webhook fires. Schedules (e.g. a daily price snapshot), webhooks and the Make/Zapier/n8n integrations all work out of the box — this is a standard Apify actor.

### Use it with AI agents (MCP)

Claude, Cursor and other MCP-capable agents can run this scraper as a tool through Apify's hosted MCP server: the agent fills in the search itself, starts the run and reads the results — no glue code.

Claude Code:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/olx-uz-scraper"
```

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

```text
https://mcp.apify.com?actors=lowlanddata/olx-uz-scraper
```

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp), or start from this actor's own MCP page: [apify.com/lowlanddata/olx-uz-scraper/api/mcp](https://apify.com/lowlanddata/olx-uz-scraper/api/mcp).

Prompts that work once connected:

- "Search OLX Uzbekistan for 'velosiped' under 2 000 000 so'm and summarize the price distribution by condition."
- "Get 200 newest iPhone 15 listings from OLX.uz and flag private sellers asking below the median."
- "Watch OLX for 'treyler' and tell me when something under 5 000 000 so'm appears."

### Beyond the 1,000-result window

OLX serves at most 1,000 results per query, however you page. This actor splits bigger queries into price bands automatically, crawls each band and deduplicates by listing id — so a 5,000-listing category comes back complete without you thinking about the window. Shards that cannot be narrowed further are fetched to the window's edge and reported honestly.

### Is it legal to scrape OLX?

Public listing data — prices, descriptions, categories, locations — is public commercial information, and this scraper is built so that the hard part of the question never arises: **no personal data enters your dataset in the first place.** Uzbekistan has its own personal-data law, and this actor does not rely on any legal nuance: an output that carries none of the seller's personal data is the point of this actor, not an afterthought.

Structurally, the extractor maps a fixed whitelist of fields out of the listing payload. The seller block, the contact block and the map coordinates are never read into the output — the only seller-derived value is the business-vs-private flag. Requests are paced, load on the site is kept negligible, and no anti-bot protection is bypassed.

One honest limit: titles and descriptions are the seller's own words, delivered as-is (markup stripped). If a seller chooses to type contact details into their listing text, that text is not rewritten — the guarantee covers the data fields, not the content sellers publish about themselves.

### Is there an OLX API alternative?

OLX publishes no public API for reading listings (the partner API serves advertisers posting them). This actor is the practical alternative: the same listings as structured JSON through one HTTP call (`run-sync-get-dataset-items`), on a schedule, or as an MCP tool for AI agents — with the GDPR question already answered in the data itself.

### Does OLX block scrapers?

OLX serves its listings openly to ordinary requests — and this actor stays inside that welcome: paced requests, standard datacenter proxies, load kept negligible. No CAPTCHA fights, no bot-wall cat-and-mouse — which is also why runs are fast and reliable enough for daily schedules.

### How do I monitor OLX prices?

Set `sortBy: "date"` with your query, cap `maxItems` to a page or two, and add a daily (or hourly) Schedule in the Apify Console with an email/Slack integration on the runs — every new listing lands in your inbox with the price already parsed to tiyin. The AI-assistant prompt above walks a non-technical user through exactly this setup. Even tighter: set `postedAfter` to yesterday's date — the dataset then contains only the new listings, nothing to dedupe on your side.

### FAQ

**Can I get seller names or phone numbers?** No — by design. That is the product: data you can store, share and process without a GDPR review. The output tells you only whether the seller is a business or a private person.

**Why does an old listing show up in a newest-first run?** Sellers bump listings; OLX orders by refresh time. Compare `postedAt` with `refreshedAt` to tell fresh listings from bumped ones.

**Can I get only the newest listings?** Yes — set `postedAfter` to a date (yesterday, say) and the dataset contains only listings posted since then. With newest-first sorting the run stops paging as soon as it provably reaches older listings, so a daily watch stays fast and cheap.

**How fresh is the data?** Live at run time — every run queries OLX directly. For continuous freshness, schedule the actor.

**Can I export to Excel or CSV?** Yes — every dataset exports as CSV, Excel, JSON or XML from the Apify Console or API.

**What happens above 1,000 results?** The actor splits the query into price bands, crawls each and dedupes — see "Beyond the 1,000-result window" above.

**Does it cover other OLX countries?** This actor is OLX.uz only, on purpose — one site done completely. Other OLX markets may follow as separate actors.

**Does it work with Make, Zapier or n8n?** Yes — it is a standard Apify actor; all platform integrations, webhooks and schedules apply.

**What currency are prices in on OLX.uz?** Uzbek som. `priceTiyin` carries the amount in tiyin — 1/100 of a som — so `500000` equals 5 000 som, and because it is an integer, converting a whole snapshot to another currency is one multiplication per row.

**Should I type my search in Latin or Cyrillic script?** Type it exactly as you would in the search box on olx.uz — the actor passes `searchQuery` through unchanged, so whichever script finds your item on the site finds it here.

**Does OLX Uzbekistan have an API?** No read API is published; OLX's partner API exists for advertisers placing ads. This actor covers the reading side — the same listings as structured JSON, over HTTP, on a schedule, or as an MCP tool.

**How much do 1,000 listings from OLX.uz cost?** $1.99, pay-as-you-go. No subscription, and a failed or empty run is never billed.

**Can I scrape only Tashkent or Samarkand?** Not via the input — there is no location filter. Both `city` and `region` are on every listing, so one run plus a column filter gives you any per-city slice.

**I am not in the EU — why should I care that it is GDPR-clean?** Data travels. If your storage, clients or analysis sit in the EU, a dataset that never contained seller personal data means there is nothing to audit later — and that guarantee is structural here, not a setting.

**What if my search has more than 1,000 results?** OLX returns at most 1,000 per query, so the actor divides the search into price bands, crawls them all and dedupes by listing id. You just set `maxItems`.

**What do I get from a blocked run?** An honest partial dataset: every listing fetched before the block is kept, and the run's status message states that coverage stopped early. Retrying later usually finishes it.

**Are special proxies needed for olx.uz?** No — the default Apify datacenter proxy is enough. No residential proxy fees stack on top of the per-result price.

**Can I restrict results to a date range?** Yes — `postedAfter` and `postedBefore` take YYYY-MM-DD values. Paired with the default newest-first sort, `postedAfter` ends the run early once older listings appear.

**How much can I test for free?** Free-plan runs return up to 25 items — a working sample of the exact fields and format, using your own query.

**Can an AI agent use this scraper as a tool?** Yes: it is available through Apify's MCP server, so Claude, Cursor and other MCP clients can launch runs and read the output on their own. Setup is the single URL in the MCP section above.

### Related scrapers

Working the European second-hand market? The same GDPR-clean guarantee, same output discipline:

- [OLX.pl Scraper](https://apify.com/lowlanddata/olx-pl-scraper) — Poland, same OLX platform, same clean output.
- [Kleinanzeigen.de Scraper](https://apify.com/lowlanddata/kleinanzeigen-scraper) — Germany's biggest classifieds site.
- [Marktplaats.nl Scraper](https://apify.com/lowlanddata/marktplaats-scraper) — the Netherlands' biggest marketplace.
- [2dehands & 2ememain Scraper](https://apify.com/lowlanddata/tweedehands-scraper) — Belgium's classifieds duo, one actor for both language sites.

### Troubleshooting

The actor fails fast with the reason in the run's status message:

- **"Provide a search query, a category id, or both."** — the run needs a scope; add a searchQuery or categoryId.
- **"priceMin must not be higher than priceMax."** — swap the two values.
- **"OLX blocked the run before any results could be fetched. This is usually temporary - retry in a few minutes."** — a temporary block on the first request; a retry usually lands on a clean proxy session.
- **"... then the site blocked further requests. Partial coverage ..."** — the run kept everything collected before the block; re-run later or narrow the query.
- **Fewer items than requested on a free plan** — the 25-item free sample cap; run on a paid Apify plan for full results.

### Support

Found an issue or missing a field you need? Open an issue on the actor's **Issues tab** — reports get fixed, this actor is actively maintained.

Working well for you? A **rating on this page** takes ten seconds and helps other buyers find a GDPR-clean option among the lookalikes — it is also the clearest signal of what we should build next.

# Actor input Schema

## `searchQuery` (type: `string`):

What to search for on OLX.uz, exactly as you would type it in the site's search box, e.g. "velosiped" or "iphone 15".

## `categoryId` (type: `integer`):

Numeric OLX category id to limit the search to. Find it in the category page URL or in a previous run's categoryId output field. Empty = all categories.

## `priceMin` (type: `integer`):

Only include listings costing at least this many sums.

## `priceMax` (type: `integer`):

Only include listings costing at most this many sums.

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

Order of results: date (newest first, best for monitoring), price\_asc, price\_desc, or relevance.

## `postedAfter` (type: `string`):

Only include listings posted on or after this date (YYYY-MM-DD or a full ISO timestamp). With newest-first sorting the run stops early once older listings are reached.

## `postedBefore` (type: `string`):

Only include listings posted on or before this date (YYYY-MM-DD or a full ISO timestamp).

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

Stop after this many listings. Free-plan runs are capped at 25 items.

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

Proxy settings. Keep Apify proxy enabled.

## Actor input object example

```json
{
  "searchQuery": "velosiped",
  "sortBy": "date",
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Scraped OLX.uz listings, one JSON object per listing.

# 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 = {
    "searchQuery": "velosiped",
    "sortBy": "date",
    "maxItems": 25,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lowlanddata/olx-uz-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 = {
    "searchQuery": "velosiped",
    "sortBy": "date",
    "maxItems": 25,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lowlanddata/olx-uz-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 '{
  "searchQuery": "velosiped",
  "sortBy": "date",
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call lowlanddata/olx-uz-scraper --silent --output-dataset

```

## MCP server setup

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