# Chotot Scraper — Vietnam Marketplace Ads, Prices & Sellers (`logiover/chotot-vn-marketplace-scraper`) Actor

Scrape Chợ Tốt, Vietnam's biggest classifieds site, by keyword, category or region. Extract price, area, location, GPS, seller name and rating from property, vehicle and electronics ads. No API key, no login.

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

## Pricing

from $2.50 / 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/platform/actors/running/actors-in-store#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

## Chợ Tốt Scraper — Vietnam Marketplace Listings, Prices & Sellers

Turn Vietnam's largest classifieds site into a clean, structured dataset: property, vehicles, electronics and every other Chợ Tốt category, with price, area, GPS coordinates and seller reputation on every row.

### What does the Chợ Tốt Scraper do?

This Actor collects live listings from **Chợ Tốt (chotot.com)**, the marketplace where most of Vietnam buys and sells. Instead of driving a browser over rendered pages, it reads the same public JSON gateway the site's own front end calls, which is why one request returns fifty complete records and why a redesign of the site cannot silently empty your dataset.

You choose a category — real estate, vehicles, electronics, home goods, fashion, pets and more — plus an optional keyword, region and sale-versus-rental filter. The Actor then walks the result list page by page, de-duplicates by listing id, and pushes a flat row per ad: title, full description, price in VND, area in square metres, ward, district, province, latitude, longitude, posting time, seller name, seller rating and image URLs. No API key, no login, no cookies.

### Who is it for?

- **Property analysts and real-estate investors** tracking asking prices and listing volume across Ho Chi Minh City, Hanoi and the provinces.
- **Car and motorbike dealers** monitoring what competitors list, at what price, and how quickly stock turns over.
- **E-commerce and pricing teams** benchmarking second-hand electronics prices against retail.
- **Market researchers and journalists** measuring supply, demand and price movement in a market with little open data.
- **Lead-generation teams** building lists of active business sellers with their reputation signals.

### Use cases

- Track the asking price per square metre for apartments in a specific district, week over week.
- Build a rental dataset for Ho Chi Minh City — Chợ Tốt rentals quote a monthly price, so the rows are directly comparable.
- Watch a used-car model's price curve by pulling the vehicles category and filtering on the title.
- Find every business seller ("company ad") in a category and rank them by live-ad count and rating.
- Feed an AI agent a fresh snapshot of a category so it can answer "what's the going rate for X in Da Nang?".

### Why use this Chợ Tốt Scraper?

- **Keyless and login-free** — nothing to register, nothing to rotate, no account to get banned.
- **41 fields per listing**, including GPS coordinates and seller reputation that most scrapers drop.
- **Bulk by design** — 50 listings per request and up to 10,000 per filter; run several regions or categories to go wider.
- **Every vertical in one Actor** — the same run shape works for flats, motorbikes, iPhones or puppies.
- **Sale and rental separated correctly** — rental prices are per month on Chợ Tốt, and the Actor labels them as such instead of mixing them into sale prices.
- **Export anywhere** — JSON, CSV, Excel, or straight into Google Sheets, and pay only per result.

### What data can you extract?

Every row is one listing. Fields left blank by the seller come back as `null` rather than an empty string, so a missing value is never confused with a zero.

| Field | Type | Description |
|---|---|---|
| `listingId` | string | Chợ Tốt's own ad id |
| `title` | string | Ad headline |
| `description` | string | Full ad body text |
| `url` | string | Direct link to the listing |
| `price` | number | Price in VND (monthly for rentals) |
| `priceText` | string | Price exactly as displayed, e.g. "4,8 tỷ" |
| `pricePerSqmMillionVnd` | number | Price per m² in millions of VND, where the site computes it |
| `currency` | string | Always `VND` when a price is quoted |
| `categoryId` | string | Numeric category id |
| `categoryName` | string | Category name in Vietnamese, e.g. "Căn hộ/Chung cư" |
| `adType` | string | `for sale` or `for rent` |
| `areaSqm` | number | Floor or land area in m² |
| `areaUnit` | string | Unit the area was quoted in |
| `rooms` | number | Room count, where the seller filled it in |
| `floors` | number | Number of floors |
| `lengthMeters` / `widthMeters` | number | Plot dimensions for land and houses |
| `houseTypeCode` | string | Chợ Tốt's house-type code |
| `legalDocumentCode` | string | Ownership-paper code (red book, pink book, etc.) |
| `isMainStreet` | boolean | Whether the property fronts a main street |
| `streetName` | string | Street |
| `wardName` | string | Ward (phường/xã) |
| `districtName` | string | District (quận/huyện) |
| `regionName` | string | Province or city |
| `latitude` / `longitude` | number | GPS coordinates |
| `postedAt` | string | ISO 8601 posting timestamp |
| `postedText` | string | Relative time as shown, e.g. "6 phút trước" |
| `sellerId` | string | Seller account id |
| `sellerName` | string | Seller display name |
| `sellerIsCompany` | boolean | Business seller flag |
| `sellerAvatarUrl` | string | Seller avatar image |
| `sellerLiveAds` | number | How many ads the seller currently has live |
| `sellerSoldAds` | number | How many the seller has sold |
| `sellerRating` | number | Average rating |
| `sellerRatingCount` | number | Number of ratings |
| `shopName` | string | Shop name for storefront sellers |
| `imageUrl` | string | Main photo |
| `imageCount` | number | Number of photos |
| `images` | string | Up to 20 photo URLs, pipe-separated |
| `hasVideo` | boolean | Whether the ad includes video |
| `scrapedAt` | string | ISO 8601 collection timestamp |

#### Sample output

```json
{
  "listingId": "134125447",
  "title": "Giỏ hàng đẹp Trellia Cove - Mizuki 77m2 2PN 2WC trực tiếp CĐT",
  "description": "Căn hộ 2 phòng ngủ, view nội khu, bàn giao nội thất cơ bản...",
  "url": "https://www.chotot.com/134125447.htm",
  "price": 4800000000,
  "priceText": "4,8 tỷ",
  "pricePerSqmMillionVnd": 62.3,
  "currency": "VND",
  "categoryId": "1010",
  "categoryName": "Căn hộ/Chung cư",
  "adType": "for sale",
  "areaSqm": 77,
  "areaUnit": "m²",
  "rooms": 2,
  "streetName": "Nguyễn Văn Linh",
  "wardName": "Xã Bình Hưng",
  "districtName": "Huyện Bình Chánh",
  "regionName": "Tp Hồ Chí Minh",
  "latitude": 10.7211,
  "longitude": 106.6702,
  "postedAt": "2026-08-13T17:13:19.000Z",
  "sellerName": "PKD CĐT Nam Long",
  "sellerIsCompany": true,
  "sellerLiveAds": 4,
  "sellerSoldAds": 3,
  "imageCount": 8,
  "hasVideo": false,
  "scrapedAt": "2026-08-13T17:14:02.118Z"
}
```

### How to use the Chợ Tốt Scraper

#### Option A — browse a whole category

Pick a category and let the Actor walk it newest-first. This is the right shape for monitoring: run it on a schedule and every new ad shows up at the top.

```json
{
  "category": "1010",
  "region": "13000",
  "adType": "s",
  "sortBy": "date",
  "maxResults": 1000,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "VN" }
}
```

1. Choose **Category** — for example *Real estate — apartments*.
2. Choose a **Region**, or leave it nationwide.
3. Set **Ad type** to *For sale* or *For rent* if you want them separated.
4. Set **Max results** and run.

#### Option B — search by keyword

Search exactly as you would on the site. The keyword works across every category, so pair it with a broad category when you want reach and a narrow one when you want precision.

```json
{
  "keyword": "Toyota Vios",
  "category": "2000",
  "sortBy": "date",
  "maxResults": 500,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "VN" }
}
```

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `keyword` | string | — | Free-text search term. Leave empty to browse the category. |
| `category` | string | `1000` | Category to crawl (real estate, vehicles, electronics, …). |
| `categoryId` | string | — | Raw category id, overrides the dropdown. Use for sub-categories such as `2010` (cars) or `2020` (motorbikes). |
| `region` | string | `""` | Province or region; empty means nationwide. |
| `adType` | string | `""` | `s` for sale, `u` for rent, empty for both. |
| `sortBy` | string | `date` | `date` (newest first) or `relevance`. |
| `maxResults` | integer | `500` | How many listings to collect. |
| `proxyConfiguration` | object | Residential / VN | Chợ Tốt answers reliably from Vietnamese IPs. |

### Tips for best results

- **Newest-first plus a schedule beats one huge run.** Chợ Tốt caps a single filter at about 10,000 ads; a daily run sorted by date keeps a complete rolling history without ever hitting the ceiling.
- **Split by region to go past the cap.** Thirteen regions × 10,000 is a lot more coverage than one nationwide run.
- **Use `categoryId` for precision.** The dropdown covers the big verticals; sub-category ids from the site's own URLs get you exactly one product type.
- **Rental prices are monthly.** Filter `adType` to `u` before comparing rents, or you will average a monthly rent against a sale price.
- **Keep the Vietnam proxy country.** The gateway is served from Vietnam and non-local exits are throttled harder.
- **`sellerIsCompany` separates dealers from private sellers** — useful both for lead lists and for cleaning price analyses.
- **`pricePerSqmMillionVnd` is the site's own computation**, so it matches what buyers see; derive your own from `price` and `areaSqm` if you need a different basis.
- **Deduplicate across runs on `listingId`**, not on URL: sellers sometimes repost with a new slug.
- **Empty result?** Widen the category first, then drop the keyword — a very specific Vietnamese phrase can legitimately match nothing.

### Integrations

Connect the Actor to the rest of your stack from the Apify platform:

- **Google Sheets** — push each run's dataset straight into a sheet for non-technical colleagues.
- **Slack** — post a message when a run finds new listings.
- **Zapier / Make** — trigger downstream automations on run completion.
- **Webhooks** — call your own endpoint with the dataset id the moment a run succeeds.
- **Schedules** — run hourly or daily; combined with newest-first sorting this gives you a change feed.

### API usage

Run the Actor and collect its dataset from anywhere.

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/logiover~chotot-vn-marketplace-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"category":"1010","region":"13000","maxResults":200}'
```

**Node.js**

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('logiover/chotot-vn-marketplace-scraper').call({
    category: '1010',
    region: '13000',
    adType: 's',
    maxResults: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'listings');
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")

run = client.actor("logiover/chotot-vn-marketplace-scraper").call(run_input={
    "keyword": "Toyota Vios",
    "category": "2000",
    "maxResults": 500,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price"])
```

### Use with AI agents (MCP)

This Actor works as a tool for AI agents through Apify's MCP server, so an assistant can pull live Vietnamese marketplace data mid-conversation instead of guessing from stale training data. Point your MCP client at `https://mcp.apify.com` and expose this Actor, then ask questions in plain language.

> *"Use the Chợ Tốt scraper to collect 200 apartment listings for sale in Ho Chi Minh City, then tell me the median price per square metre by district."*

### FAQ

#### Do I need a Chợ Tốt account or API key?

No. The Actor reads public listing data through the site's own public gateway. There is nothing to register and no credential to store.

#### Which categories are supported?

All of them. The dropdown covers real estate (all, apartments, houses, land, rooms), vehicles, electronics, appliances, home and furniture, fashion, entertainment, food, office and agriculture, mother and baby, pets, and services. Any sub-category id from the site's own URLs works through the `categoryId` field.

#### How many listings can one run return?

Chợ Tốt exposes roughly 10,000 ads per filter combination. Within that, set `maxResults` to whatever you need. To go beyond it, split the crawl by region, by sub-category, or by keyword.

#### Why did my run return zero rows?

Almost always an over-narrow filter: a rare keyword combined with a specific region and a sub-category can genuinely match nothing. Clear the keyword first, then widen the category. The log states the number of matches Chợ Tốt reports for your filter, which tells you immediately whether the filter or the crawl is the problem.

#### Why are some fields null?

Because the seller left them blank. Room counts, plot dimensions and legal-document codes are optional on Chợ Tốt and are common on property ads but absent on electronics. A `null` means "not published", never "zero".

#### Are rental prices monthly?

Yes. Chợ Tốt quotes rentals per month ("triệu/tháng") and sale prices as a total. The `adType` field tells you which one a row is, so filter on it before averaging.

#### How fresh is the data?

Every run fetches live pages. With `sortBy` set to newest first, the first page contains ads posted minutes ago — `postedAt` and `postedText` let you verify freshness on every row.

#### Can I export to CSV or Excel?

Yes. Every dataset can be downloaded as JSON, CSV, Excel, XML or RSS from the run's Storage tab, or fetched through the API in any of those formats.

#### How fast is it?

Roughly 50 listings per request with a short pause between pages to stay polite. A 500-row run typically finishes in well under a minute.

#### Is scraping Chợ Tốt legal?

The Actor collects only publicly visible listing information — the same data any visitor sees without logging in. It does not touch private messages, accounts or anything behind authentication. See the legal note below.

#### How often is the Actor updated?

It is monitored and maintained. Because it reads a structured JSON source rather than CSS selectors, it survives visual redesigns that break card-parsing scrapers.

#### Can I get seller phone numbers?

No. Chợ Tốt keeps phone numbers behind a session-gated reveal, so they are not part of the public listing payload and this Actor does not attempt to extract them. You get the seller's name, id, reputation and shop link.

### Is it legal to scrape Chợ Tốt?

This Actor collects publicly available information only — listings that Chợ Tốt publishes openly to every visitor, with no login and no paywall. Scraping public data is broadly lawful in most jurisdictions, but you remain responsible for how you use what you collect.

Review Chợ Tốt's Terms of Service before running large-scale or commercial collection, and take care with personal data. Seller display names may constitute personal data under Vietnam's PDPD, the GDPR or similar regimes; make sure you have a lawful basis before storing or processing them. If in doubt, consult a lawyer — this is not legal advice.

### Related scrapers

- **[Tokopedia Product Scraper](https://apify.com/logiover/tokopedia-product-scraper)** — Indonesia's largest marketplace, product and price data.
- **[Tiki.vn Scraper](https://apify.com/logiover/tiki-vn-scraper)** — Vietnamese e-commerce catalogue and pricing.
- **[Lazada Scraper](https://apify.com/logiover/lazada-scraper)** — Southeast Asian marketplace listings across six countries.
- **[Rumah123 Scraper](https://apify.com/logiover/rumah123-scraper)** — Indonesian property listings and agent contacts.

# Actor input Schema

## `keyword` (type: `string`):

Free-text search, exactly as you would type it into Chợ Tốt — e.g. 'iphone 15', 'Toyota Vios', 'căn hộ quận 7'. Leave empty to browse the whole category.

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

Which part of the marketplace to crawl. Real estate covers flats, houses, land and rooms; vehicles covers cars, motorbikes and trucks.

## `categoryId` (type: `string`):

Overrides the dropdown with a raw Chợ Tốt category id, for sub-categories not listed above (e.g. 2010 for cars, 2020 for motorbikes). Read it from the site's own filter URL.

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

Restrict the crawl to one region. Leave on nationwide to cover all of Vietnam.

## `adType` (type: `string`):

Chợ Tốt splits every vertical into sale ads and rental ads — 'for rent' prices are per month.

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

Newest first is what you want for monitoring; relevance mirrors the site's default ranking.

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

How many listings to collect. Chợ Tốt exposes up to 10,000 ads per filter; use several runs with different regions or categories to go past that.

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

Chợ Tốt answers reliably from Vietnamese IPs, so residential proxies pinned to Vietnam are used by default.

## Actor input object example

```json
{
  "keyword": "iphone",
  "category": "1000",
  "region": "",
  "adType": "",
  "sortBy": "date",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "VN"
  }
}
```

# Actor output Schema

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

Every record collected in this run. Open the Dataset tab to browse, filter or export as JSON, CSV or Excel.

# 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 = {
    "category": "1000",
    "region": "",
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "VN"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/chotot-vn-marketplace-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 = {
    "category": "1000",
    "region": "",
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "VN",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/chotot-vn-marketplace-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 '{
  "category": "1000",
  "region": "",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "VN"
  }
}' |
apify call logiover/chotot-vn-marketplace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,logiover/chotot-vn-marketplace-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/tRGPGOZhhX4hgMHYw/builds/HpBTTOc1qfU6Hlo1g/openapi.json
