# OLX India Scraper: Used Cars, Phones & Classifieds (`hexagone-data/olx-india-scraper`) Actor

Scrape olx.in category listings and ads: title, price in INR, location, posting date, car attributes (make, model, year, km, fuel), images, business-seller flag. No seller personal data. Pay per result.

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

## Pricing

$1.50 / 1,000 ads

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

## OLX India Scraper — Classified Ads from olx.in

Collect classified ads from **olx.in** (OLX India), India's biggest classifieds marketplace. Paste category URLs for full listings (Cars, Mobile Phones, and every other OLX category) or single ad URLs for ad-page records. Each record carries the asking price as a number, the public location, the ad attributes the site publishes (brand, model, year, km, fuel…), and the photos.

Use dated exports to follow a local market, track asking prices over time, or feed your own analytics.

**No seller personal data.** This Actor never collects the seller's name, identifier, phone number or profile: only the ad itself and a boolean telling whether the seller is a business. See Output.

### Try it with 20 ads

1. Paste a category URL into **Start URLs**.
2. Set **Maximum number of ads** to `20`.
3. Start the Actor and open its dataset.
4. Read **Run summary** before exporting JSON, CSV or Excel: a successful process can still contain incomplete URLs or check warnings.

```json
{
  "startUrls": [{"url": "https://www.olx.in/cars_c84"}],
  "maxItems": 20
}
```

The form's ad-count prefill is 20, while the schema default is 500. Set `maxItems` explicitly in API calls; `0` removes the limit. Indian categories are huge (Cars: 300 000+ ads, 40 per page): start small.

### What to paste

| Input | Data | Notes |
|---|---|---|
| Category `https://www.olx.in/cars_c84` | Every ad of the category, paginated to the end of the list (40 ads per page) | The category identifier is the `_c<number>` part of the URL you see on the site. |
| Ad `https://www.olx.in/item/…-iid-123456789` | One ad record | Richer location (neighbourhood) and the ad's canonical URL. |

You can mix both. Explicit ad URLs are processed first; an ad-page record takes precedence over its duplicate listing record. Ads are deduplicated by `adId` within the run.

Search pages (`/q-…`), the site's API and private pages (posting, account, chat…) are disallowed by the site's robots.txt and rejected with a reason. Location-prefixed category paths are not supported: paste the plain category URL.

### Output

| Field | Meaning |
|---|---|
| `adId` | OLX ad identifier (the `-iid-` part of the ad URL). Match ads on this, not on titles. |
| `url` | Public ad page. |
| `title`, `description` | Ad title and body as written by the advertiser. |
| `price` | Asking price as a number, in `currency` (₹ 15,90,000 gives `1590000`). Null when the ad shows no price. |
| `currency`, `priceDisplay` | Currency published by OLX (INR) and the price exactly as displayed. |
| `category`, `categoryId` | OLX category name and identifier. |
| `location` | Public location shown on the ad: neighbourhood, city, state. Levels the ad does not give are skipped. |
| `postedAt` | Ad creation date, ISO 8601 (site timezone). |
| `mainInfo` | The summary line the site shows under the title (e.g. `2023 - 26,000 km` for a car). Often null for electronics. |
| `attributes` | Ad attributes keyed by the site's parameter key (`make`, `model`, `year`, `petrol` = fuel, `transmission`, `mileage` = km driven…), values as displayed. Depends on the category. |
| `images` | Photo URLs, in the site's order. Null when the ad has no photo. |
| `isBusinessSeller` | True when OLX marks the seller as a business. Null on records that come from a single ad page. |
| `position`, `page`, `sourceUrl`, `scrapedAt` | Collection provenance. |

A field the site does not publish is `null`, never an empty string. `attributes` is an object (and `images` an array): account for them when transforming JSON or choosing spreadsheet columns.

#### Real output example

The following ad record was collected on **22 October 2026**. It demonstrates the format, not today's price.

```json
{
  "adId": "1841264627",
  "url": "https://www.olx.in/item/cars-c84-used-mahindra-thar-in-nurpur-himachal-pradesh-iid-1841264627",
  "title": "Mahindra Thar LX D AT 4WD HT, 2023, Diesel",
  "price": 1590000,
  "currency": "INR",
  "priceDisplay": "₹ 15,90,000",
  "categoryId": "84",
  "category": "Cars",
  "location": "Nurpur, Himachal Pradesh",
  "postedAt": "2026-10-01T13:48:26+05:30",
  "mainInfo": "2023 - 26,000 km",
  "attributes": {"make": "Mahindra", "model": "Thar", "variant": "LX D AT 4WD HT",
                 "year": "2023", "petrol": "Diesel", "transmission": "Automatic",
                 "mileage": "26,000 km", "first_owner": "1st"},
  "images": ["https://apollo.olx.in:443/v1/files/sly31310pyre-IN/image", "…"],
  "isBusinessSeller": true,
  "description": "well maintaine car\n\nADDITIONAL VEHICLE INFORMATION:…",
  "position": 1,
  "page": 1,
  "sourceUrl": "https://www.olx.in/cars_c84",
  "scrapedAt": "2026-10-22T09:00:00+00:00"
}
```

### Run summary

The **OUTPUT** record (and its readable **SUMMARY** page) tells, for every pasted URL, how many ads were delivered and why a URL delivered nothing (`no_ads`, `not_found`, `blocked_by_site`, …), plus the `anomalies` list — empty when the automatic checks found nothing unusual. An invalid URL never blocks the others; a URL that really fails is reported, and the run fails only if nothing at all could be collected.

### Known limits

- **Location scope.** Category pages list ads across all of India (the site's default). The Actor cannot pick a city: location-prefixed paths are not supported yet.
- **Attribute keys follow OLX.** `attributes` uses the site's own keys, so the fuel attribute is keyed `petrol` and the km driven `mileage`. They vary by category (a Mobile Phones ad carries only `make` at the time of writing).
- **Prices are asking prices**, set by advertisers; a price shown as negotiable or absent gives `null`.
- **Ad availability.** OLX ads expire and get reposted: match on `adId` and keep `scrapedAt` with your exports. This Actor returns observations, not a maintained history.

### Proxy

Not needed by default: the Actor browses like Chrome. Only enable the proxy configuration if your runs get blocked; the Actor then retries through it, and as a last resort through Apify datacenter then India residential proxies.

# Actor input Schema

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

www.olx.in pages to scrape. Accepted: category pages (https://www.olx.in/cars_c84, https://www.olx.in/mobile-phones_c1453) and ad pages (https://www.olx.in/item/…-iid-…). The site's robots.txt disallows search (q-…), API and private pages: they are rejected with a reason. Location-prefixed category paths are not supported; paste the plain category URL.

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

Stops after this many unique ads across all start URLs. 0 = no limit. Indian categories hold hundreds of thousands of ads (Cars: 300 000+ at the time of writing): start small.

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

Not needed by default. Only enable it if your runs get blocked.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.olx.in/cars_c84"
    }
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `records` (type: `string`):

All ad records, one per ad and source URL, with every field.

## `ads` (type: `string`):

Ad view: photo, title, price, location, posted date, category.

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

Readable per-URL summary: status, ads delivered, reason for any URL that returned nothing.

## `summaryJson` (type: `string`):

The same summary as JSON (OUTPUT record), for programmatic use.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.olx.in/cars_c84"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("hexagone-data/olx-india-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 = {
    "startUrls": [{ "url": "https://www.olx.in/cars_c84" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("hexagone-data/olx-india-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 '{
  "startUrls": [
    {
      "url": "https://www.olx.in/cars_c84"
    }
  ],
  "maxItems": 20
}' |
apify call hexagone-data/olx-india-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hexagone-data/olx-india-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/H2xCW5a5jfhJv6IFo/builds/eBS35aLrm27teaz6G/openapi.json
