# Tokopedia Scraper · Products, Shops & Reviews (`memo23/tokopedia-scraper`) Actor

Scrape Tokopedia products from keywords, search URLs, categories, shops or product links. Get IDR prices, discounts, exact sold counts, ratings, specs, every variant with its own price and stock, reviews, seller stats and TikTok Shop IDs. Monitor mode returns only price changes.

- **URL**: https://apify.com/memo23/tokopedia-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (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.50 / 1,000 products

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

## Tokopedia Scraper · Products, Shops & Reviews

Turn Tokopedia keywords, search results, category pages, shop catalogues or product links into clean product rows: IDR prices, discounts, sold counts, ratings, every variant with its own price and stock, reviews and seller stats. No login, no cookies, no browser.

Schedule it in monitor mode and each run returns only new products and price moves, so you pay for changes instead of the whole catalogue again. Or switch to one row per review to collect a product's or a whole shop's reviews.

| Input | Rows you get |
|---|---|
| Keyword (`keywords`) | Products from Tokopedia search, with Tokopedia's own filters applied |
| Search URL (`/search?q=…`) | The same results you see in the browser, filters kept |
| Category URL (`/p/…`) | Products in that category |
| Shop URL (`/shop-name`, `/product`, `/etalase/…`) | The shop's catalogue; add `includeShopInfo` for the shop's stats |
| Product URL (`/shop-name/product-name`) or bare product id | One product with full details |

***

### Why Use This Scraper?

- ✅ Every Tokopedia entry point in one run: keywords, search URLs, category pages, shop catalogues and product links
- ✅ Tokopedia's own filters: price range, 4 stars and up, Official Store or Power Shop, COD, discounts, condition, seller location and listing date
- ✅ Full product pages on demand: description, brand and full specifications, all images, wishlist count, free-shipping flag, and every variant SKU with its own price, stock and link
- ✅ Exact sold counts and per-star rating breakdowns, not only the rounded "10 rb+ terjual" badge
- ✅ Written reviews nested in each product, or one row per review for a product or a whole shop, sorted and filtered your way (newest, most helpful, 1–2 stars only, with photos)
- ✅ Monitor mode with an optional webhook: new products, price drops, discount changes, stock and sales moves, removed listings
- ✅ TikTok Shop product, SKU and seller IDs on every row, for joining Tokopedia with TikTok Shop data

***

### Overview

The Tokopedia Scraper is built for price-monitoring teams, brands watching their resellers, marketplace sellers researching competitors and analysts sizing categories on Indonesia's largest marketplace.

The dataset is always one row per product. A shop URL, a category page and a keyword all end up as product rows; the shop's own numbers travel with each product as `shop…` columns, and reviews are nested inside the product they belong to. Error rows (a URL that is not a Tokopedia page, a product that no longer exists) are separate, carry an `error` field and are never charged.

Listing rows come from Tokopedia's search API and are fast: about 200 products per request. Turn on full details when you need specifications, variants, stock or exact sold counts; those are read from the product page, six products per request.

***

### Supported Inputs

#### URL types

| Type | Example |
|---|---|
| Search results | `https://www.tokopedia.com/search?q=sepatu&pmin=100000&ob=3` |
| Keyword landing page | `https://www.tokopedia.com/find/sepatu-pria` |
| Category | `https://www.tokopedia.com/p/fashion-pria/sepatu-pria/pantofel-pria` |
| Shop | `https://www.tokopedia.com/tomkinsofficial` |
| Shop tab or showcase | `https://www.tokopedia.com/tomkinsofficial/product`, `…/etalase/sneakers` |
| Product | `https://www.tokopedia.com/tomkinsofficial/tomkins-hamnet-black-white-sepatu-sneakers-pria-1733389550990952357` |
| Product id | `11869486942` |

`m.tokopedia.com` links work too. Tracking parameters such as `extParam` are ignored.

#### Copy-pasteable startUrls

```json
{
  "startUrls": [
    "https://www.tokopedia.com/search?q=tas%20wanita&pmin=100000&pmax=300000",
    "https://www.tokopedia.com/p/fashion-pria/sepatu-pria",
    "https://www.tokopedia.com/tomkinsofficial"
  ]
}
```

#### Keyword mode

```json
{ "keywords": ["sepatu", "laptop gaming", "skincare"], "maxItemsPerSource": 200, "maxItems": 600 }
```

Each keyword is its own search; `maxItemsPerSource` gives every keyword the same share of `maxItems`. Indonesian terms return the most products.

#### Unsupported inputs

- Pages behind a login: cart, orders, chat, wishlist, seller center
- Tokopedia Play, feeds, promo and help pages
- TikTok Shop URLs (use the TikTok Shop IDs in the output to join the two)
- Share links from the app (`tk.tokopedia.com/…`): open the link and paste the full product URL
- Digital goods (pulsa, BPJS, insurance, game vouchers): Tokopedia sends those searches to its own digital pages, which list no marketplace products

***

### Use Cases

| Who | What they do with it |
|---|---|
| Brands and distributors | Track resellers, spot unauthorised sellers and price breaks across Official and regular stores |
| Price-monitoring teams | Schedule monitor mode on key products and get price drops through a webhook |
| Marketplace sellers | Benchmark competitors' prices, variants, sold counts and ratings |
| Category and market analysts | Size categories by sold counts and rating volume, city by city |
| Product and catalogue teams | Pull specifications, variant SKUs and images for feeds and PIM |
| Researchers | Collect written reviews with ratings, variant and date for sentiment work |

***

### How It Works

![How the Tokopedia Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-tokopedia.png)

1. Every keyword and URL is classified as a search, category, shop or product.
2. Searches and categories are read from Tokopedia's search API, about 200 products per request, with Tokopedia applying your filters.
3. Shop catalogues are read 80 products per page.
4. With full details on, product pages are read six at a time: description, specifications, variants, stock, exact sold count and rating breakdown. Reviews and shop stats are added when asked for.
5. Products are de-duplicated across all inputs and pushed as they are ready. In monitor mode each product is compared with the previous run first and only new or changed ones are pushed.

***

### Input Configuration

#### Input fields

| Field | Type | Default | Description |
|---|---|---|---|
| `outputMode` | string | `products` | `products`: one row per product. `reviews`: one row per written review; a shop URL gives the shop's reviews |
| `keywords` | array | | Searches, one per line, as typed in Tokopedia's search bar |
| `startUrls` | array | | Search, category, shop or product URLs and bare product ids, in any mix |
| `scrapeDetails` | boolean | `false` | Read each product page for description, specifications, images, variants, stock, exact sold count and rating breakdown |
| `maxReviewsPerProduct` | integer | `0` | Written reviews to attach to each product (0 = off, max 1000) |
| `reviewSort` | string | `newest` | `newest`, `most_helpful`, `highest_rating`, `lowest_rating` |
| `reviewStars` | array | | Only reviews with these star ratings, e.g. `["1","2"]` |
| `reviewsWithMediaOnly` | boolean | `false` | Only reviews with buyer photos or videos |
| `includeShopInfo` | boolean | `false` | Add followers, active products, transactions, open-since date and shop rating to every row |
| `sortBy` | string | `relevance` | `relevance`, `reviews` (best sellers first), `newest`, `price_high`, `price_low` |
| `minPrice` / `maxPrice` | integer | | Price range in rupiah |
| `ratingFourPlus` | boolean | `false` | Only products rated 4 stars and up |
| `condition` | string | `any` | `any`, `new`, `used` |
| `shopType` | string | `any` | `any`, `official_store`, `power_shop` |
| `codOnly` | boolean | `false` | Only products that can be paid cash on delivery |
| `discountedOnly` | boolean | `false` | Only discounted products |
| `deliveryType` | string | `any` | `any`, `instant`, `same_day` |
| `minRating` | string | `0` | `0`, `3`, `3.5`, `4`, `4.5`, `4.8`: drops products rated lower (applied after the search) |
| `stockType` | string | `any` | `any`, `ready_stock`, `preorder` |
| `listedWithinDays` | string | `any` | `any`, `7`, `14`, `30`, `90` |
| `locations` | array | | Seller areas: Jakarta, Jabodetabek, Bandung, Medan, Surabaya or any province |
| `cityIds` | string | | Tokopedia city ids (`fcity`) for cities not in the list, comma separated |
| `categoryId` | string | | Narrow keyword searches to one category id (`sc`) |
| `convertToCurrency` | string | `none` | Also give prices in `USD`, `EUR`, `GBP`, `SGD`, `MYR`, `AUD`, `JPY`, `CNY`, `KRW`, `HKD`, `INR`, `THB`, `PHP`, `CAD` or `CHF` |
| `monitorMode` | string | `off` | `off`, `price-changes`, `all-changes`, `new-only` |
| `monitorName` | string | | Baseline name for monitor mode; made from your inputs when empty |
| `emitRemoved` | boolean | `false` | In monitor mode, one `removed` row per tracked product a complete run no longer finds |
| `webhookUrl` | string | | Receives the changed products as JSON after each monitor run |
| `maxItems` | integer | `100` | Products to collect across all keywords and URLs (review rows in review-rows mode) |
| `maxItemsPerSource` | integer | | Optional cap per keyword or URL |
| `maxConcurrency` | integer | `10` | Requests in flight at once (1 to 30) |
| `proxyConfiguration` | object | Apify Proxy | The default datacenter proxy works for Tokopedia |

Filters apply to keywords and category pages. A pasted search URL keeps its own filters, and the input filters only fill in the ones the URL leaves unset. Shop catalogues take `minPrice`, `maxPrice` and `minRating` (applied to each product) and `sortBy: "reviews"` (best sellers first).

#### Common scenarios

**Search with Tokopedia's filters**

```json
{
  "keywords": ["iphone 15"],
  "shopType": "official_store",
  "minPrice": 10000000,
  "ratingFourPlus": true,
  "sortBy": "price_low",
  "maxItems": 200
}
```

**Full details, reviews and seller stats for a shop**

```json
{
  "startUrls": ["https://www.tokopedia.com/tomkinsofficial"],
  "scrapeDetails": true,
  "maxReviewsPerProduct": 20,
  "includeShopInfo": true,
  "maxItems": 100
}
```

**Complaints from one product's reviews**

```json
{
  "startUrls": ["https://www.tokopedia.com/tomkinsofficial/tomkins-hamnet-black-white-sepatu-sneakers-pria-1733389550990952357"],
  "maxReviewsPerProduct": 200,
  "reviewSort": "lowest_rating",
  "reviewStars": ["1", "2"]
}
```

**A shop's reviews, one row each, lowest rating first**

```json
{
  "outputMode": "reviews",
  "startUrls": ["https://www.tokopedia.com/tomkinsofficial"],
  "reviewSort": "lowest_rating",
  "maxItems": 500
}
```

**Daily price monitor with a webhook**

```json
{
  "startUrls": ["https://www.tokopedia.com/p/handphone-tablet/handphone"],
  "monitorMode": "price-changes",
  "monitorName": "phones-daily",
  "webhookUrl": "https://hooks.example.com/tokopedia",
  "maxItems": 2000
}
```

Schedule the monitor input in Apify and keep `monitorName` the same on every run.

***

### Output Overview

Each row is one product and has up to five groups of fields:

- **Listing:** ids, name, URL, price, original price, discount, rating, sold count, image, category, seller name, city and type, badges, whether it is an ad, and where it was found (keyword, page, position)
- **Details** (`scrapeDetails`, or any product URL): description, specifications, images, videos, condition, weight, order limits, stock, rating count and per-star breakdown, review topics, COD, pre-order, wholesale tiers, flash-sale campaign, category tree, creation date, variant groups and every variant SKU
- **Reviews** (`maxReviewsPerProduct` above 0): written reviews in the order and with the filters you chose, plus `writtenReviewCount`
- **Converted prices** (`convertToCurrency`): `convertedPrice` and `convertedOriginalPrice` in your currency, with the rate and its date
- **Seller stats** (`includeShopInfo`): followers, active products, items sold, transactions, open-since date, location, shop rating and breakdown
- **Monitor** (`monitorMode`): `changeType`, `changedFields`, previous values and the price difference

In review-rows mode (`outputMode: "reviews"`) every row is one written review instead: stars, text, variant bought, date, reviewer, photos, likes, seller reply and Tokopedia's low-rating reason, plus the product it belongs to (id, name, URL, price, rating) and the shop.

***

### Output Samples

Real row from a keyword search for `sepatu` with `sortBy: "reviews"`, `scrapeDetails`, `maxReviewsPerProduct: 2` and `includeShopInfo`, scraped 2026-09-24. Long lists are cut to one or two entries.

```json
{
  "productId": "100070724287",
  "parentId": "100070724279",
  "productName": "PVN Taeri Sepatu Sneakers Olahraga Wanita Sport Shoes blue Grey 265",
  "productUrl": "https://www.tokopedia.com/pavillionshoes/pvn-taeri-sepatu-sneakers-olahraga-wanita-sport-shoes-blue-grey-265-1730635635437963091",
  "price": 187181,
  "originalPrice": 499900,
  "discountPercentage": 63,
  "currency": "IDR",
  "rating": 4.9,
  "soldCount": 296248,
  "categoryName": "Sneakers Wanita",
  "shopName": "pvnshoes",
  "shopCity": "Tangerang",
  "shopType": "official_store",
  "ttsProductId": "1729435508359596883",
  "source": "search",
  "searchKeyword": "sepatu",
  "position": 1,
  "specifications": [{ "name": "Kondisi", "value": "Baru" }, { "name": "Kategori", "value": "Sneakers Wanita" }],
  "condition": "new",
  "weightGrams": 1000,
  "stock": 189,
  "ratingCount": 40092,
  "ratingBreakdown": { "1": 177, "2": 107, "3": 370, "4": 3092, "5": 36346 },
  "isCod": true,
  "campaign": { "name": "Spesial Diskon", "originalPrice": 499900, "discountedPrice": 187181, "endsAt": "2026-09-30T16:59:59.000Z" },
  "variantSkus": [
    { "productId": "100070724280", "options": ["Pink", "36(1)"], "price": 187181, "originalPrice": 499900, "stock": 0, "ttsSkuId": "1730635635437897555" }
  ],
  "writtenReviewCount": 10000,
  "reviews": [
    { "reviewId": "2318519907", "rating": 5, "text": "Bentuk dan ukuran: Pas", "variantName": "White - 40(5)", "createdAt": "2026-09-24T15:24:54.000Z", "isAnonymous": true }
  ],
  "shopFollowers": 73165,
  "shopOpenSince": "May 2021",
  "shopRating": 4.9,
  "shopRatingCount": 174923
}
```

Review-rows mode row from a shop URL (`outputMode: "reviews"`, `reviewSort: "lowest_rating"`, real run):

```json
{
  "reviewId": "702618568",
  "rating": 1,
  "text": "minta ukuran 39 dikasih 33 padahal sudah dichat.. diretur ongkir harus 2x pembeli yg bayar... lo biaya 1 x pengiriman gpp sih. makasih.",
  "variantName": "33",
  "createdAtText": "Lebih dari 1 tahun lalu",
  "createdAtApprox": "2025-09-25",
  "reviewerName": "Daedi",
  "sellerResponse": "Terima kasih banyak telah berbelanja di Tomkins Official.\nkami kirimkan sesuai varian/size yang dipilih ya kak\nterimakasih",
  "badRatingReason": "Kendala: Pelayanan penjual kurang",
  "productId": "2436506346",
  "productName": "TOMKINS Primal Alpha - Hitam Putih Sneakers Wanita Sepatu Olahraga",
  "productUrl": "https://www.tokopedia.com/tomkinsofficial/tomkins-primal-alpha-hitam-putih-sneakers-wanita-sepatu-olahraga",
  "shopName": "TOMKINS",
  "source": "shop"
}
```

Monitor mode row: the same kind of product row plus these fields (real run, `price-changes`):

```json
{
  "productId": "1523827550",
  "price": 25900,
  "changeType": "price-drop",
  "changedFields": ["price"],
  "previousPrice": 50900,
  "priceDelta": -25000,
  "priceDeltaPercentage": -49.12,
  "firstSeenAt": "2026-09-24T20:13:38.009Z",
  "previousSeenAt": "2026-09-24T20:13:39.937Z"
}
```

***

### Key Output Fields

#### Product

`productId`, `parentId`, `productName`, `productUrl`, `brand`, `condition`, `status`, `createdAt`, `description`, `specifications`, `images`, `videos`, `weightGrams`, `wishlistCount`

#### Price and stock

`price`, `priceText`, `originalPrice`, `discountPercentage`, `currency`, `convertedPrice`, `convertedOriginalPrice`, `convertedCurrency`, `exchangeRate`, `exchangeRateDate`, `stock`, `minOrder`, `maxOrder`, `wholesale`, `campaign`, `cashbackPercentage`, `isPreorder`, `preorderDays`, `isCod`, `hasFreeShipping`, `shippingFromPrice`, `shippingEstimateText`

#### Variants

`variantGroups` (each option with stock and image), `variantSkus` (each SKU with its own price, original price, discount, stock, order limits, URL, image and TikTok Shop SKU id)

#### Demand and ratings

`soldCount`, `soldCountText`, `rating`, `ratingCount`, `ratingBreakdown`, `satisfactionText`, `reviewTopics`, `writtenReviewCount`, `reviews` (each with `rating`, `text`, `variantName`, `createdAt`, `images`, `videos`, `likeCount`, `sellerResponse`, `badRatingReason`)

#### Seller

`shopId`, `shopName`, `shopDomain`, `shopUrl`, `shopCity`, `shopType`, `isOfficialStore`, `isPowerMerchant`, `shopFollowers`, `shopActiveProducts`, `shopTotalSold`, `shopTotalTransactions`, `shopShowcaseCount`, `shopOpenSince`, `shopLocation`, `shopIsOpen`, `shopRating`, `shopRatingCount`, `shopRatingBreakdown`

#### Category

`categoryId`, `categoryName`, `categoryPath`, `categoryTree`, `ttsCategoryId`

#### Where it was found

`source`, `searchKeyword`, `sourceUrl`, `page`, `position`, `isAd`, `labels`, `scrapedAt`

#### TikTok Shop IDs

`ttsProductId`, `ttsSkuId`, `ttsShopId`, `ttsCategoryId`

#### Review rows (`outputMode: "reviews"`)

`reviewId`, `rating`, `text`, `variantName`, `createdAt` (product reviews), `createdAtText` and `createdAtApprox` (shop reviews), `reviewerName`, `isAnonymous`, `images`, `videos`, `likeCount`, `sellerResponse`, `badRatingReason`, `productId`, `productName`, `productUrl`, `productPrice`, `productRating`, `writtenReviewCount`, `shopId`, `shopName`, `shopDomain`

#### Monitor

`changeType` (`new`, `price-drop`, `price-increase`, `discount-change`, `out-of-stock`, `back-in-stock`, `sales-change`, `rating-change`, `removed`), `changedFields`, `previousPrice`, `previousOriginalPrice`, `priceDelta`, `priceDeltaPercentage`, `previousStock`, `previousSoldCount`, `soldDelta`, `previousRatingCount`, `firstSeenAt`, `previousSeenAt`

***

### FAQ

#### Which Tokopedia URLs are supported?

Search results, `/find/` keyword pages, category pages (`/p/…`), shops and their tabs, and product pages. Login pages, Tokopedia Play, promo pages and app share links are not; see Supported Inputs.

#### I pasted a shop URL. Why do I get product rows?

The dataset is always one row per product. The shop's catalogue becomes product rows, and with `includeShopInfo` on, each row also carries the shop's followers, transactions and rating.

#### Why does `soldCount` differ between runs with and without details?

Search results only show a rounded badge such as "100 rb+", which becomes `100000`. The product page has the exact count (`296248` in the sample above), so rows with details carry the exact number and `soldCountText` keeps Tokopedia's own label.

#### Why are there fewer reviews than ratings?

Many buyers leave stars without text. `ratingCount` counts every rating; `reviews` holds written reviews only, and `writtenReviewCount` says how many exist that match your review filters. Tokopedia reports at most 10,000 written reviews per product.

#### How many products can one search return?

Tokopedia serves up to 6,000 results per search, filter or category. For more, split the search by price range, seller location or category and put each part in its own keyword or URL.

#### Is there a best-selling sort?

Tokopedia no longer offers one. `sortBy: "reviews"` sorts by review volume, which puts the best sellers first: the top ten products for "sepatu" on that sort each showed "100 rb+" sold.

#### How does monitor mode charge?

The first run returns every product and saves them as the baseline. Later runs with the same `monitorName` return only new products and products whose watched fields changed. Unchanged products are not pushed and not charged. `price-changes` watches price and original price; `all-changes` also watches stock status, sold count and rating count, and needs `scrapeDetails` for stock and exact sales.

#### Can I get one row per review, or all of a shop's reviews?

Yes. Set `outputMode` to `reviews`. Keywords, categories and product URLs give each product's reviews as separate rows, with the product's id, name, URL, price and rating on every row; a shop URL gives the shop's reviews across all its products. `maxItems` then counts review rows, and each row is billed as one review.

#### Why do shop reviews have an approximate date?

Tokopedia shows shop reviews with relative times only ("2 bulan lalu", "Lebih dari 1 tahun lalu"). Each row keeps that text in `createdAtText` and a date worked out from it in `createdAtApprox`. Product reviews have the exact `createdAt`. Some older shop reviews also come without a product URL.

#### What does "removed" mean in monitor mode?

With `emitRemoved` on, a product that an earlier run found and this run no longer finds gets one `removed` row: it was delisted, dropped out of the results, or no longer matches your filters. Removals are only reported by runs that read every keyword and URL to the end, so a run stopped by `maxItems`, a per-source cap or Tokopedia's 6,000-result limit reports none.

#### Where do converted prices come from?

From the European Central Bank's daily reference rates (via frankfurter.dev), fetched once per run. The rupiah price always stays in `price`; if the rate cannot be fetched, the run continues without converted fields.

#### Is there a free-shipping filter?

No. Tokopedia no longer marks free shipping in its search results, so there is nothing to filter on. The delivery-speed filter (`deliveryType`) is available.

#### Do I need residential proxies?

No. The default Apify datacenter proxy works for Tokopedia's API, and runs recover from blocked requests by switching IP. Switch to RESIDENTIAL only if you see many retries in the log.

#### Can it scrape data behind a login?

No. It reads the public data any visitor sees: products, prices, public reviews and shop pages. Buyer accounts, orders, chats and seller dashboards are out of scope.

#### What are the TikTok Shop IDs for?

Tokopedia merged with TikTok Shop Indonesia in 2024, and Tokopedia's own API returns a TikTok Shop id for every product, SKU and seller. Use them to match Tokopedia listings with TikTok Shop data.

***

### Support

Found a bug or need a field that is not there? Open an issue on the actor's **Issues** tab.

Email: muhamed.didovic@gmail.com

***

### Additional Services

Need a custom scraper, a tailored export, or an integration into your own pipeline? Custom builds are available: muhamed.didovic@gmail.com.

***

### Explore More Scrapers

- **Shopee Scraper**: search, product and shop data across 11 Shopee markets
- **TikTok Shop Scraper**: products, reviews, shops and creators
- **TikTok Shop Sales Scraper**: units sold and revenue per product
- **AliExpress Scraper**: products, prices and discounts
- **Coupang Scraper**: Korean marketplace products, prices and ratings

Browse the full collection at [apify.com/memo23](https://apify.com/memo23).

***

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/tokopedia-scraper`).

**Purpose:** Public Tokopedia (Indonesia) product rows from keywords or search, category, shop and product URLs, with optional full details, reviews, seller stats and run-over-run change monitoring. No login.

**Minimal input:**

```json
{ "keywords": ["sepatu"], "maxItems": 20 }
```

**Output:** one dataset row per product: productId, productName, productUrl, price, originalPrice, discountPercentage, currency (IDR), rating, soldCount, imageUrl, categoryName, shopName, shopDomain, shopCity, shopType, ttsProductId, source, searchKeyword, position. With `scrapeDetails`: description, specifications, images, stock, ratingCount, ratingBreakdown, variantSkus \[{productId, options, price, stock}], campaign. With `maxReviewsPerProduct`: reviews \[{rating, text, variantName, createdAt}], writtenReviewCount. Failed inputs return `{error, errorKind, message, url}`.

**Behaviors an agent should know:**

- Always set `maxItems`; it counts products across all keywords and URLs. One search stops at 6,000 results.
- Product URLs always return full details. For other inputs set `scrapeDetails: true` when stock, variants or exact sold counts are needed.
- Filters (`minPrice`, `shopType`, `locations`…) apply to keywords and categories; a pasted search URL keeps its own.
- Monitor mode (`monitorMode`, `monitorName`) keeps a baseline in a named key-value store in the caller's account and returns only new or changed products after the first run; `emitRemoved` adds `removed` rows after complete runs.
- Reviews: `reviewSort` (`newest`, `most_helpful`, `highest_rating`, `lowest_rating`), `reviewStars` (e.g. `["1","2"]`), `reviewsWithMediaOnly`. `outputMode: "reviews"` returns one row per review instead of product rows (a shop URL gives the shop's reviews) and `maxItems` counts reviews.
- Billing: `product` per delivered row, `product-detail` per row with full details, `review` per attached review. Error rows and unchanged monitor products are free.
- Not available: login-only data, Tokopedia Play, app share links.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by PT Tokopedia, TikTok, ByteDance Ltd., or any of their subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available Tokopedia product, category, shop and review data, with no authenticated endpoints, paid features, or content behind the Tokopedia login wall. Users are responsible for ensuring their use complies with Tokopedia's Terms of Service, applicable data-protection law (Indonesia's PDP Law, GDPR, CCPA, etc.), and any contractual obligations of their own organization.

***

### SEO Keywords

Tokopedia scraper, scrape Tokopedia, Tokopedia API, Tokopedia product scraper, Tokopedia shop scraper, Tokopedia reviews scraper, Tokopedia shop reviews, Tokopedia price monitor, Apify Tokopedia, tokopedia.com scraper, Indonesia ecommerce scraper, Indonesian marketplace data, Tokopedia sold count, Tokopedia seller data, Tokopedia category scraper, ecommerce price tracking, competitor price monitoring, product catalog export, marketplace analytics Indonesia, TikTok Shop Indonesia data, Southeast Asia ecommerce data

# Actor input Schema

## `outputMode` (type: `string`):

Products: one row per product, with optional details, nested reviews and shop stats. Reviews: one row per written review with the product it belongs to; a shop URL gives the shop's reviews across all its products. Review filters and sort apply, and each row is billed as a review.

## `keywords` (type: `array`):

One search per line, typed as you would in Tokopedia's search bar. Indonesian terms return the most results (sepatu, tas wanita, laptop gaming).

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

Any mix of search results (tokopedia.com/search?q=...), category pages (tokopedia.com/p/...), shops (tokopedia.com/shop-name, including its /product and /etalase/... tabs), single products (tokopedia.com/shop-name/product-name) and bare product ids such as 11869486942. Filters already in a URL are kept.

## `scrapeDetails` (type: `boolean`):

Open each product page for the description, specifications, all images and videos, every variant with its own price and stock, exact sold count, per-star rating breakdown, weight, condition, stock, wholesale tiers and flash-sale campaign. Billed as a product-detail event on top of the product. Product URLs always get full details.

## `maxReviewsPerProduct` (type: `integer`):

Written reviews to attach to each product (text, star rating, variant bought, date, photos, seller reply). 0 turns reviews off. Each review is billed as a review event. In review-rows mode 0 means 100 per product.

## `reviewSort` (type: `string`):

Which reviews come first when reviews are on. Lowest rating first is the quickest way to collect complaints.

## `reviewStars` (type: `array`):

Keep only reviews with these star ratings, e.g. 1 and 2 for complaints. Leave empty for all ratings. Allowed values: 1, 2, 3, 4, 5.

## `reviewsWithMediaOnly` (type: `boolean`):

Keep only reviews that include buyer photos or videos.

## `includeShopInfo` (type: `boolean`):

Add the seller's followers, active products, total items sold, completed transactions, open-since date, district and shop rating with its per-star breakdown. Looked up once per shop and not billed separately.

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

Tokopedia's sort order for search and category results. Tokopedia no longer offers a best-selling sort; most reviews brings the best sellers to the top.

## `minPrice` (type: `integer`):

Only products at or above this price in rupiah.

## `maxPrice` (type: `integer`):

Only products at or below this price in rupiah.

## `ratingFourPlus` (type: `boolean`):

Tokopedia's rating filter: only products rated 4 or higher.

## `condition` (type: `string`):

New or used items.

## `shopType` (type: `string`):

Limit results to Official Stores (brand and authorised sellers) or Power Shop sellers.

## `codOnly` (type: `boolean`):

Only products that can be paid on delivery (COD).

## `discountedOnly` (type: `boolean`):

Only products with a price cut.

## `deliveryType` (type: `string`):

Tokopedia's delivery-speed filter: products that can arrive instantly or the same day (as seen from central Jakarta).

## `minRating` (type: `string`):

Drop products rated below this. Finer than Tokopedia's own 4-star filter; applied after the search, so products without a rating are dropped too.

## `stockType` (type: `string`):

Ready-stock items or pre-order items.

## `listedWithinDays` (type: `string`):

Only products added recently.

## `locations` (type: `array`):

Only sellers shipping from these areas: Jakarta, Jabodetabek, Bandung, Medan, Surabaya or any province. Pick several to combine them.

## `cityIds` (type: `string`):

Tokopedia city ids for cities not in the list above, comma separated. Apply a city filter on tokopedia.com and copy the fcity value from the address bar.

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

Narrow keyword searches to one Tokopedia category: the number after sc= in a filtered search URL. To scrape a whole category, paste its /p/... URL above instead.

## `convertToCurrency` (type: `string`):

Add convertedPrice and convertedOriginalPrice in this currency, using the day's European Central Bank rate. Rupiah prices stay in price and originalPrice.

## `monitorMode` (type: `string`):

The first run returns everything and saves it as the baseline. Later runs with the same monitor name return only new products and products whose watched fields changed, with the previous values and the price difference. "New products only" ignores changes. Stock and exact sales need full product details on.

## `monitorName` (type: `string`):

Name of the baseline to compare against. Keep it the same on every scheduled run of the same watch. Left empty, a name is made from your keywords, URLs and filters, so changing any of them starts a new baseline.

## `emitRemoved` (type: `boolean`):

Also return one row (changeType "removed") for each tracked product that a later run no longer finds: delisted, sold out of the results, or no longer matching your filters. Only runs that read every keyword and URL to the end report removals; a run stopped by Maximum products, a per-source cap or Tokopedia's 6,000-result limit does not.

## `webhookUrl` (type: `string`):

Optional. After each monitor run that found changes (never the first run), the changed products are POSTed here as JSON: Slack, Zapier, Make or your own endpoint.

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

Stop after this many products across all keywords and URLs (review rows in review-rows mode). Tokopedia serves up to 6,000 results per search; split a large search by price range or location to go further.

## `maxItemsPerSource` (type: `integer`):

Optional cap for each keyword or URL, so one broad search cannot use up the whole run. Leave empty for no per-source cap.

## `maxConcurrency` (type: `integer`):

Requests in flight at once. The default is fast and safe; lower it if you see retries in the log.

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

Apify's default datacenter proxy works for Tokopedia and costs nothing extra. Switch to RESIDENTIAL only if runs start seeing retries.

## Actor input object example

```json
{
  "outputMode": "products",
  "keywords": [
    "sepatu"
  ],
  "startUrls": [
    "https://www.tokopedia.com/p/fashion-pria/sepatu-pria",
    "https://www.tokopedia.com/tomkinsofficial"
  ],
  "scrapeDetails": false,
  "maxReviewsPerProduct": 0,
  "reviewSort": "newest",
  "reviewsWithMediaOnly": false,
  "includeShopInfo": false,
  "sortBy": "relevance",
  "ratingFourPlus": false,
  "condition": "any",
  "shopType": "any",
  "codOnly": false,
  "discountedOnly": false,
  "deliveryType": "any",
  "minRating": "0",
  "stockType": "any",
  "listedWithinDays": "any",
  "convertToCurrency": "none",
  "monitorMode": "off",
  "emitRemoved": false,
  "maxItems": 100,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `products` (type: `string`):

Every product row: listing fields, plus details, reviews and shop stats when enabled.

# 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 = {
    "keywords": [
        "sepatu"
    ],
    "startUrls": [
        "https://www.tokopedia.com/p/fashion-pria/sepatu-pria",
        "https://www.tokopedia.com/tomkinsofficial"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/tokopedia-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 = {
    "keywords": ["sepatu"],
    "startUrls": [
        "https://www.tokopedia.com/p/fashion-pria/sepatu-pria",
        "https://www.tokopedia.com/tomkinsofficial",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/tokopedia-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 '{
  "keywords": [
    "sepatu"
  ],
  "startUrls": [
    "https://www.tokopedia.com/p/fashion-pria/sepatu-pria",
    "https://www.tokopedia.com/tomkinsofficial"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call memo23/tokopedia-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/tokopedia-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/INUfJCC04WVckeuBu/builds/z9YIyepbgc1ehDBby/openapi.json
