# CarWale Used Car Listings Scraper (India) (`superslowsloth/carwale-used-cars`) Actor

Scrape CarWale used cars in India by city, make or model: price in INR, year, kilometres, fuel, transmission, owners, dealer or individual, locality and the Average Market Price. Sort by price or mileage to track new listings and price drops city by city.

- **URL**: https://apify.com/superslowsloth/carwale-used-cars.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 car listing scrapeds

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

## CarWale Used Car Listings Scraper (India)

Scrape the used cars listed on [CarWale](https://www.carwale.com/used/) (India's
large used-car marketplace) city by city, optionally narrowed to one make or one
model, and get one flat row per car: the asking price in **INR** (as a number and as
CarWale prints it), year, kilometres, fuel, transmission, number of owners, whether
the seller is a dealer or an individual, the locality, CarWale's **Average Market
Price** estimate, the reduction on a car shown as reduced, the link and the photo.

Built for a **per-city new-listing and price-drop alert**: run it on a schedule for
the cities you care about, keep the `stock_id`s you have seen, and diff the dataset
against last time. A `stock_id` that is new is a new listing; the same `stock_id`
with a lower `price_inr` is a price drop.

No account, no API key, no login, no browser.

### Input

| Field | Notes |
|---|---|
| `cities` | One or more CarWale city slugs, one per line: `mumbai`, `delhi`, `bangalore`, `pune`, `hyderabad`, `chennai`, `kolkata`. Required. Use the slug in the city's CarWale URL (`carwale.com/used/<city>/`). `New Delhi` and `new-delhi` are read as `delhi`, which is where CarWale redirects them. |
| `makeModel` | Optional. One make or one model as written in CarWale's URL: `maruti-suzuki`, `maruti-suzuki-swift`, `toyota-innova-crysta`. Applied to every city. |
| `maxItems` | Cars to read per city (default 100, up to 15,000 - Delhi, the largest city, has about 13,000). CarWale serves about 25 cars per request. |
| `sort` | `best-match` (CarWale's default), `price-asc`, `price-desc`, `year-newest`, `km-low`. See "Coverage". |
| `proxyConfiguration` | Apify datacenter proxy by default. |

An unknown city, an unknown make or model slug, or a make with no cars in that city
**fails that city at no charge** instead of returning something else. CarWale itself
answers those with a redirect to a different page (an unknown make or model slug is
sent to the whole city's page, an unknown city to the `/used/` hub); the actor
checks which page it was served and refuses to bill rows that are not the search you
asked for.

### Output

Prices are whole numbers of Indian rupees.

| Field | Notes |
|---|---|
| `city`, `search`, `position` | The city slug as CarWale resolved it, the CarWale path the row came from (`/used/mumbai/maruti-suzuki-swift/`), and the car's place in that search's result list (1 is first). Nearby-city extras and repeats are not counted. |
| `stock_id`, `url` | CarWale's stock id (`yxcd9y10`), stable for the life of the ad, and the absolute listing link. |
| `title`, `make`, `model`, `variant`, `year` | `title` is CarWale's car name (make, model and variant). `model` is the model family (`Creta`), `variant` the trim. |
| `price_inr`, `price_text` | The asking price as a number and as CarWale prints it (`11.5 Lakh`, `1.31 Crore`, `30,000`). One lakh is 100,000 and one crore 10,000,000. |
| `original_price_text`, `discount_text`, `discount_inr` | On a car CarWale shows as reduced: the earlier price and the reduction as printed (`Rs. 11.75 Lakh`, `Rs. 30,000`) and the reduction in rupees. **Null on every other car**, never 0. |
| `average_market_price_inr` | CarWale's "Average Market Price" estimate for the car. Null when CarWale has no estimate (it sends 0). |
| `km`, `fuel`, `transmission` | Odometer in kilometres, fuel and transmission as CarWale prints them (`Petrol`, `Automatic (TC)`). |
| `owners` | Previous owners as CarWale counts them (1 = first owner). **Null when CarWale sends 0**, which it does for cars with no owner count. |
| `seller_type`, `seller_name` | `dealer` or `individual`. The dealership's name for a dealer; **always null for an individual**, because a private seller's name is a person's name and is not published. |
| `is_promoted` | True for a car in one of CarWale's promoted slots, the "Sponsored" placements at the top of the default `best-match` sort. |
| `listing_city`, `area` | The city the car is actually in, and its locality (`Mulund (W)`, null when empty). CarWale lists some cars from other cities for home delivery in a city's results, so `listing_city` can differ from `city` (a Gurgaon car in Delhi's results, for example). |
| `image_url` | The listing photo; null when the listing has none (common for private sellers). |

Example row (Mumbai, 2026-10-15):

```json
{
  "city": "mumbai",
  "search": "/used/mumbai/",
  "position": 7,
  "stock_id": "azn2mwoy",
  "title": "Maruti Suzuki Grand Vitara Delta Smart Hybrid [2023-2025]",
  "make": "Maruti Suzuki",
  "model": "Grand Vitara",
  "variant": "Delta Smart Hybrid [2023-2025]",
  "year": 2025,
  "price_inr": 1145000,
  "price_text": "11.45 Lakh",
  "original_price_text": "Rs. 11.75 Lakh",
  "discount_text": "Rs. 30,000",
  "discount_inr": 30000,
  "average_market_price_inr": 1309817,
  "km": 13100,
  "fuel": "Petrol",
  "transmission": "Manual",
  "owners": 1,
  "seller_type": "dealer",
  "seller_name": "Reliable Carz",
  "is_promoted": false,
  "listing_city": "Mumbai",
  "area": "Link Road",
  "url": "https://www.carwale.com/used/mumbai/maruti-suzuki-grand-vitara/azn2mwoy/",
  "image_url": "https://imgd.aeplcdn.com/400x300/vimages/202609/4804684_13981_1_1790243211758.jpg?qp=80"
}
```

#### Honest nulls

A field CarWale did not send, or sent as 0 where 0 means "unknown" (owners, the
market estimate, the price), is `null`, never `0`. A car with no price is still
returned, because the listing exists.

### Pricing

Pay per event:

- **$0.002** per run (`actor-start`), charged only after your input is validated, so a
  run that fails on bad input costs nothing.
- **$0.0006** per car row written (`listing-scraped`), i.e. $0.60 per 1,000 cars. A row
  that is not written is not charged; cars CarWale adds from nearby cities, and cars
  it repeats, are neither written nor charged.

### Coverage - read this before you diff runs

CarWale pages its own "load more" with offsets that overlap and skip cars when the
order is not stable. Measured 2026-10-15 on Dehradun (653 cars on CarWale's count),
one run per sort:

| Sort | Cars read |
|---|---|
| `price-asc` | 646 (99%) |
| `price-desc` | 646 (99%) |
| `km-low` | 648 (99%) |
| `best-match` | 599 to 607 (92 to 93%) across two runs |
| `year-newest` | 578 (88%), many cars share a year |

**For a full sweep of a city, use a price or kilometres sort.** `best-match` is
CarWale's default and the only order with promoted slots, but its order shifts
between requests. A car CarWale counts but never serves (3 of 166 for Mumbai Maruti Suzuki Swifts, read in full on 2026-10-15) cannot be read at all.

### How it fetches

The first page of a city is CarWale's server-rendered page; the actor reads the JSON
CarWale's own page is built from, which is embedded in it (the listing cards use
obfuscated markup that changes). Further cars come from the "load more" JSON the page
itself calls (`/api/stocks/`), 24 to 33 cars per request, followed link by link. Measured
2026-10-15: HTTP 200 from Apify datacenter and residential exits and from a plain home
connection, no key or cookie needed; 25 sequential pages took 0.2 to 0.5 s each with no
rate limit. A refusal (403, 429, 202, 5xx), a 200 that is not the expected page or JSON,
or a dropped connection is treated as the address being blocked, and the actor rotates
to a fresh one and retries.

Things worth knowing, all measured:

- **The paging chain never ends by itself.** After a city's own cars CarWale serves
  cars from nearby cities, then wraps around and repeats the city's cars, then returns
  empty pages for ever (958 pages measured). The actor stops at the first page with no
  car from the city itself, and skips the nearby-city extras.
- **`/page-2/` URLs do not paginate** on CarWale (pages 2, 3, 322 and 400 of Mumbai
  share 23 of 24 cars), which is why the actor follows the "load more" chain.
- **CarWale's count is not always reachable.** `totalCount` is logged per city; the
  rows returned can be a little lower (see Coverage).
- **Promoted slots.** On `best-match` the first page carries about 9 promoted cars
  ahead of the organic ones; they are returned once, flagged `is_promoted`.
- **Cars from other cities.** Results can include cars CarWale offers for home delivery
  from another city; they are returned with their real `listing_city`.
- **No "recently listed" sort.** CarWale offers none, so new listings are found by
  diffing `stock_id`s between runs, not by sorting.
- **Not offered.** The other filters on the site (budget, body type, colour, owners)
  are not wired into this actor.

# Actor input Schema

## `cities` (type: `array`):

CarWale city slugs, one per line, exactly as they appear in carwale.com/used/<city>/ (for example mumbai, delhi, bangalore, pune, hyderabad, chennai, kolkata). 'New Delhi' and new-delhi are read as delhi, the slug CarWale redirects them to. Each city is read separately and its rows carry the city slug. A slug CarWale does not know fails that city at no charge.

## `makeModel` (type: `string`):

Limit every city to one make or one model, written as in CarWale's URL: maruti-suzuki for a make, maruti-suzuki-swift or toyota-innova-crysta for a model. Leave empty for every car. A slug CarWale does not know (or a make with no cars in that city) fails that city at no charge rather than returning the whole city.

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

Read at most this many cars for each city. Up to 15,000 are accepted, enough for Delhi, the largest city (about 13,000 used cars). CarWale lists about 25 cars per request.

## `sort` (type: `string`):

The order CarWale lists the cars in. 'Best match' is its default and the only order that carries promoted slots at the top. For a full sweep of a city (new-listing or price-drop alerts that diff stock ids between runs) use a price or kilometres sort: those read 99% of a city's cars in a measured run, against about 93% for 'Best match' and 88% for 'Year, newest first', because CarWale's paging overlaps and skips cars when its order is not stable.

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

Use Apify's automatic datacenter proxy (the default). CarWale answered datacenter and residential exits alike in testing. A refused request is retried from a fresh address.

## Actor input object example

```json
{
  "cities": [
    "mumbai"
  ],
  "maxItems": 100,
  "sort": "best-match",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# 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 = {
    "cities": [
        "mumbai"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/carwale-used-cars").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 = {
    "cities": ["mumbai"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/carwale-used-cars").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 '{
  "cities": [
    "mumbai"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/carwale-used-cars --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superslowsloth/carwale-used-cars"
        }
    }
}
```

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/PnE1Rdvc5QVM8cj6x/builds/KM638TQyBdScUJJOP/openapi.json
