Cho Tot Scraper: Vietnam Listings, Property & Motorbikes
Pricing
from $1.00 / 1,000 listing returneds
Cho Tot Scraper: Vietnam Listings, Property & Motorbikes
Cho Tot scraper covering goods, Nha Tot property and Cho Tot Xe vehicles: get one row per listing (price, category, seller, link). Turn on monitoring for only new listings and price drops since your last run. No login required; quiet monitoring runs are free.
Pricing
from $1.00 / 1,000 listing returneds
Rating
0.0
(0)
Developer
Adrian Voss
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Watch a search, get only what's new. This actor runs your search against Cho Tot's own public gateway API — Vietnam's biggest classifieds group, which also runs the "Nha Tot" property vertical and the "Cho Tot Xe" vehicles vertical on the same backend — and returns one clean row per listing: title, price, category, seller, and a link. Turn on monitoring and it becomes a watchlist: new listings and price drops since your last run, charged per new row, free on quiet days. Schedule it hourly and send the results to Discord, Slack, Google Sheets, or n8n.
Who it's for
A reseller or arbitrage buyer watching one category (phones, motorbikes, apartments) on Cho Tot for underpriced or newly-posted listings wants a live feed of what's actually there right now, without refreshing the search page by hand. A property agent or renter tracking Hanoi or Ho Chi Minh City apartment listings on Nha Tot, or a used-vehicle buyer watching Cho Tot Xe for a specific brand and model, gets the same shape here: paste a keyword, get back a flat row per listing, and pay only for listings actually returned — a search that finds nothing costs nothing.
This actor covers all three of Cho Tot's verticals from one input (
vertical: goods / property / vehiclesWhy this one
- The only actor covering Cho Tot Xe (vehicles). The current Apify Store leader for Cho Tot,
haketa, has 15 lifetime users and covers goods only — there is no dedicated actor for used cars or motorbikes on Cho Tot at all. This actor adds that vertical from day one, plus Nha Tot property. - Monitoring first, not a one-off dump. Turn on "Only return results that are new, or dropped in price" and this actor becomes a watchlist: it remembers every listing ID it has already shown you, and only bills you for what's actually new or has dropped in price since the last run. A quiet run — nothing new, nothing cheaper — still finishes and costs only the base run fee.
- Reads Cho Tot's own gateway API directly, not scraped HTML — , the same JSON endpoint the site's own search pages call. Price, category, and seller fields are exact, typed values, not text parsed out of rendered markup.gateway.chotot.com/v1/public/ ad-listing
- Never charged for a miss, or a quiet monitoring run. A search that finds nothing, or a scheduled watchlist run where nothing changed, still gets a row explaining what happened — and costs nothing.
- Honest about what's actually confirmed. A handful of fields (the exact listing-page URL slug, a house-type or condition code with no discovered label, most Vietnamese provinces' region ids) are documented as best-effort or unverified rather than guessed — see "Data & privacy" and the FAQ.
What you get
One row per listing by default (turn off "Expand rows" in Advanced to get one row per search
instead, with the listings nested under listings).
| Field | Type | Description |
|---|---|---|
query | text | The search you submitted, echoed back |
found | boolean | true if Cho Tot returned a real result for this search |
status | text | OK on a match; NOT_FOUND, BLOCKED, or BAD_FORMAT on a miss |
message | text | Plain-English reason for a miss — only present when found is false |
searchQuery | text | The search line as submitted |
vertical | text | goods, property, or vehicles — inferred from the actual category returned, not just echoed from your setting |
listingCount | number | Listings returned and billed for this search |
totalAvailable | number | Total listings Cho Tot reports matching this search (capped at 10,000 by Cho Tot itself) |
truncated | boolean | true if more results existed than were returned |
newCount / priceDropCount | number | New listings / price drops this run (monitoring only) |
listingId | text | Cho Tot's public listing id (list_id — a different, internal ad_id also exists and is never output) |
url | text (link) | Best-effort listing link — see "Data & privacy" for what's unverified about it |
title / description | text | Listing title and description (contact info redacted) |
price / priceDisplay / currency | number / text / text | Price in VND, Cho Tot's own display string, and VND always |
postedAt | date | When the listing was posted |
category / categoryId | text | Category name and Cho Tot's own numeric cg id |
region / regionId / area / ward | text | Province, province id (region_v2), district, ward |
sellerType / sellerRating / soldAdsCount / sellerHash | text / number / number / text | business or private, the seller's average rating, their sold-ads count, and an anonymous per-seller fingerprint |
accountName | text | Opt-in only. The seller's raw display name — off unless "Include raw seller name" is on |
size, rooms, toilets, houseTypeCode, streetName, pricePerM2 | — | Property only |
carBrand, carModel, year, mileageKm, fuelCode, gearboxCode, condition | — | Vehicles only |
conditionCode | number | Goods only — a raw Cho Tot code; no label was ever found for it, so it's not translated |
changeType, isNew, previousPrice, priceDropPct, firstSeenAt | — | Monitoring-only fields (see "Monitoring" below) |
scrapedAt | date | When this row was fetched |
Deselect any field in the Input tab's column picker to drop it from every row — query, found,
status, message, and scrapedAt always stay.
Pricing
Pay-per-event. A flat per-run fee covers session/proxy warmup; you're billed
per item only when data is actually found and returned — see
.actor/pay_per_event.json for exact prices. A miss is never charged.
Monitoring / only new results
Turn on "Only return results that are new, or dropped in price" and a search line becomes a watchlist instead of a one-off dump:
- A listing counts as new the first time its Cho Tot listing id is returned by this watchlist.
- A listing counts as a price drop when its price falls by at least "Minimum price drop" (5% by default) since it was last seen — Cho Tot has no bidding system, so every listed price is a real, comparable fixed price.
- Already-seen, unchanged listings are dropped before you're billed. A quiet run — nothing new, nothing cheaper — still finishes and returns one free row, so a scheduled task shows it actually ran.
- The first run has nothing to compare against. By default it returns everything it finds as "new". Turn on "Seed silently" to instead have the first run bank everything quietly with zero rows and zero charge, and start alerting from the second run on.
Schedule recipe. Save this actor as an Apify Task with deltaMode: true and a deltaName
you choose, add an hourly (or daily) Schedule, and point the task's webhook at Discord,
Slack, Google Sheets, or an n8n/Make webhook URL to get pinged only when something actually
changes.
Price-drop window limitation. A price drop is only ever seen while the listing is still inside
what a run actually fetches — if a listing falls out of your maxListingsPerSearch window or your
price filters between runs, this actor has no way to notice it dropped. Keep searches reasonably
narrow rather than one huge catch-all if price-drop coverage matters to you.
How to use
- In the Apify Console. Open the actor page and click Start — the
searchesfield is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found. - Via the API. Call it directly with a POST request — no Console needed once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~chotot-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"searches":["iphone"]}'
- On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
- Pick your Vertical (goods / property / vehicles) and, optionally, a Category override and Region under Search settings — see "What you get" and the FAQ for the confirmed category and region ids. Turn on "Only return results that are new, or dropped in price" under Monitoring once you want a watchlist instead of a one-off dump.
Input
{"searches": ["iphone"]}
One per line. A plain keyword ("iphone", "honda") searches the vertical/category/region picked below. A pasted gateway.chotot.com/v1/public/ad-listing URL (copy one from your browser's network tab) overrides cg/st/region_v2/area_v2 for that one line only — useful for a for-rent-only property watch, since there is no separate "purpose" field. No login required. Accepted formats: iphone, honda, https://gateway.chotot.com/v1/public/ad-listing?cg=1010&st=u®ion_v2=12000.
Sample output
| query | found | status | searchQuery | vertical | listingCount | totalAvailable | truncated | newCount | priceDropCount | monitorStatus | listings | listingId | url | title | description | price | priceDisplay | currency | postedAt | category | categoryId | region | regionId | area | ward | listingStatus | sellerType | sellerRating | soldAdsCount | photoCount | imageUrl | sellerHash | accountName | size | rooms | toilets | houseTypeCode | streetName | pricePerM2 | carBrand | carModel | year | mileageKm | fuelCode | gearboxCode | condition | conditionCode | changeType | isNew | previousPrice | priceDropPct | firstSeenAt | scrapedAt |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| iphone | true | OK | <vertical (goods / property / vehicles)> | <monitoring status (quiet / seeded runs)> | <all listings found (full list)> | <cho tot listing id (list_id)> | <listing link (best-effort, see readme)> | <description (contact info redacted)> | <price (vnd)> | <category id (cg)> | <province / city> | <province id (region_v2)> | <business / private> | <seller's sold-ads count> | <seller display name (raw, opt-in)> | <property: size (m²)> | <property: rooms> | <property: toilets> | <property: house type (raw code, no label found)> | <property: street name> | <property: price per m² (million vnd)> | <vehicles: car/bike brand> | <vehicles: car/bike model> | <vehicles: manufacture year> | <vehicles: mileage (km)> | <vehicles: fuel type (raw code, no label found)> | <vehicles: gearbox (raw code, no label found)> | <vehicles: condition> | <goods: condition (raw code, no label found)> | <new / price-drop / seen> | <is this listing new?> | <previous price (vnd)> | <price drop %> | 1970-01-01T00:00:00.000Z |
A search that finds nothing comes back as a row with "found": false and is never charged. A quiet
monitoring run comes back as a row with listingCount: 0 and is also never charged.
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~chotot-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"searches":["iphone"]}'
n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~chotot-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"searches":["iphone"]} (swap in an expression from an earlier node for a real value).
Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~chotot-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"searches":["{{search}}"]}, mapping the row's search into the searches array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Cho Tot Scraper | Apify" — the agent will find and run this actor.
For monitoring, point the Task's webhook (Console → your Task → Webhooks) at a Discord or Slack incoming-webhook URL, a Google Sheets automation, or an n8n/Make workflow's own webhook trigger, so new listings and price drops land wherever you actually work.
Tips
- Start monitoring with "Seed silently" on for any watchlist you're setting up on a schedule — it avoids a wall of "new" alerts for your entire current search result on day one.
- Want rentals only, or another combination this actor's Input tab doesn't expose directly (like
Cho Tot's own sale-vs-rent split on property)? Paste a full URL (copy it from your browser's network tab while browsing Nha Tot with the filters you want) as a search line — it overrides the vertical/category/region settings for that line.gateway.chotot.com/v1/public/ ad-listing
- Only Ho Chi Minh City and Hanoi have a friendly region name built in. For any other province, run
once with no region filter and read
regionIdoff any returned row for your city, then paste that numeric id into "Region" on later runs. - Keep a monitored search reasonably narrow (a model, a tight category, a price band) — see "Price- drop window limitation" above.
- A
BLOCKEDstatus means Cho Tot returned a 403, 429, or 503 — lowering "Max concurrency" or trying again shortly usually clears it; this actor doesn't need a proxy by default.
vs. haketa's Cho Tot actor, and Cho Tot's own alerts
Cho Tot's own site has no public "save this search and alert me" feature comparable to what this
actor does from outside — the closest thing is manually re-checking a search. The current Apify
Store leader for Cho Tot, haketa, has 15 lifetime users and covers the goods vertical only, with
no monitoring mode and no property or vehicles coverage.
| What it costs | What you get | Trade-off | |
|---|---|---|---|
| This actor | Pay per listing returned; nothing for a miss or a quiet monitoring run | Goods, Nha Tot property, and Cho Tot Xe vehicles from one actor; monitoring mode (new + price drop) | A handful of fields (exact listing-URL slug, a couple of raw category codes, most provinces' ids) are best-effort or need a numeric id you look up once — see the FAQ |
| haketa's actor | Per-listing, goods only | Goods vertical scraping | No property, no vehicles, no monitoring |
| Doing it yourself | Your time to build and maintain a scraper, a seen-listing store, and a price-tracking layer | The same data | This actor's gateway parsing, monitoring state, and redaction are the maintenance burden it absorbs |
Data & privacy
This actor reads Cho Tot's own public gateway API — the same JSON its search pages call in your
browser, without logging in. It doesn't log in, solve CAPTCHAs, or reveal hidden contact details.
Cho Tot's listing API exposes no phone number or email field of any kind; as a defensive measure,
any phone-like or email-like text a seller pasted directly into a description is still redacted to
[redacted]. Seller identity beyond a business/private flag, an average rating, and a sold-ads
count is off by default — turning on "Include raw seller name" would make you responsible for
having a lawful reason to process it. Not affiliated with Cho Tot / Carousell Group.
Is this allowed? It collects the same public listing data your browser shows, for the searches you choose. It's built for monitoring a search, not for copying the marketplace. Check that your use fits Cho Tot's terms and your local law.
FAQ
Why is a row empty, or why does found say false?
Either the input line was blank (status: BAD_FORMAT), Cho Tot returned a 403/429/503
(status: BLOCKED), or the search matched nothing right now (status: NOT_FOUND). Check the
message column for the specific reason. None of these are billed.
Am I charged for a quiet monitoring run?
No. When monitoring finds nothing new and no price drops, you get one row with listingCount: 0 —
Actor.charge() only fires when listingCount is greater than zero.
How sure are you the listing link (url) actually works?
Not fully. Cho Tot's own gateway API returns no link field at all. A real listing URL was observed
once, live, elsewhere on the site: a slug plus the numeric listing id, e.g.
xe.chotot.com/mua-ban-oto-quan-7-tp-ho-chi-minh/134761051.htm. The numeric id (confirmed against
this actor's own listingId) is real; the descriptive slug text before it was not independently
rebuilt this session, so url here is <domain>/<listingId>.htm without that slug — unverified for
whether Cho Tot's routing accepts a bare id with no slug prefix.
What are houseTypeCode, fuelCode, gearboxCode, and conditionCode?
Raw numeric codes Cho Tot returns with no accompanying label anywhere in the payload or the site's
own category data. Rather than invent a translation, this actor outputs the code as-is — cross-check
a code against the listing on chotot.com/nhatot.com/xe.chotot.com if you need its meaning.
Which category (cg) and region (region_v2) ids are confirmed?
Confirmed live: goods 5010 phones (default), 5020 TV/audio, 5030 laptops, 5040 tablets, 5050
cameras; property 1000 all real estate (default), 1010 apartments, 1020 houses, 1040 land, 1050
rooms for rent; vehicles 2010 cars (default), 2020 motorbikes, 2030 parts, 2050 trucks, 2060
bicycles, 2090 electric vehicles. Regions: Ho Chi Minh City (13000) and Hanoi (12000) by name; any
other province needs its numeric region_v2 id, discoverable for free from regionId on any
returned row.
Do I need to configure proxies? No. This actor uses Apify's default proxy configuration (no proxy group) out of the box — Cho Tot's gateway API isn't Cloudflare-challenged the way its HTML search pages sometimes are. RESIDENTIAL VN is available as a fallback if that ever changes.
Can an AI agent call this directly? Yes. It's registered on the Apify MCP server — an agent in Claude, Cursor, or another MCP client can find and run it by name ("Cho Tot Scraper | Apify"), or you can call the REST endpoint shown above from any script or workflow tool.
Related actors
- OLX India Scraper — the same search-and-monitor shape for OLX India's own open JSON search API.