# Tokopedia Scraper: Product Prices, Sold Counts, Shops (`deepurple/tokopedia-product-scraper`) Actor

Tokopedia product data for price monitoring and competitor tracking: IDR price, discount, rating, sold count, shop city, Official Store and Power Merchant flags. Filters by price, rating, official only. Detail mode: variants with stock, specs, rating breakdown. Pay per product.

- **URL**: https://apify.com/deepurple/tokopedia-product-scraper.md
- **Developed by:** [Misha Ershov](https://apify.com/deepurple) (community)
- **Categories:** E-commerce, Business, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.20 / 1,000 product (search result)s

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/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 Product Scraper

Collect Tokopedia product data by keyword: prices in rupiah (as numbers and as text), discounts, ratings, sold counts, shop city, official-store and Power Merchant flags, categories and images. Switch on **detail mode** and every product also gets its specifications, variants with stock, full description and the star-by-star rating breakdown. No login, no cookies, no API key.

Built for price monitoring, market research, dropshipping and sourcing in Indonesia, competitor tracking and catalog enrichment.

### What you get

**Listing mode (default)** returns one row per product found by your keyword search:

| Group | Fields |
|---|---|
| Identity | `productId`, `url`, `title`, `searchKeyword`, `searchRank`, `searchPage` |
| Price | `priceIDR` (integer), `priceFormatted` ("Rp199.900"), `originalPriceIDR`, `originalPriceFormatted`, `discountPct`, `currency` |
| Social proof | `rating`, `soldCount` (integer), `soldCountText` (as shown on the site), `soldCountIsApproximate` |
| Shop | `shopId`, `shopName`, `shopDomain`, `shopUrl`, `shopLocation` (city), `shopTier`, `isOfficialStore`, `isPowerMerchant`, `badges` |
| Listing extras | `labels`, `hasFreeShipping`, `isSponsored`, `categoryId`, `categoryName`, `breadcrumbs`, `thumbnailUrl`, `imageUrls`, `imageCount`, `scrapedAt` |

**Detail mode** (`includeDetails: true`) opens each product page and additionally fills `reviewCount`, `ratingBreakdown` (1 to 5 stars), exact `soldCount`, `description`, `specs`, `variants` (option, price, stock, buyable flag), `stock`, `condition`, `status`, `minOrder`, `maxOrder`, `weight`, `weightUnit`, `weightGram` and the full image gallery.

Numbers are real numbers: prices and sold counts are integers, so "1,2rb+ terjual" becomes `1200` with `soldCountIsApproximate: true`. A field the site does not publish stays `null` instead of a made-up zero.

### Input

| Field | Meaning |
|---|---|
| `keywords` | Search terms, for example `sepatu pria`. Each keyword is searched separately. |
| `productUrls` | Optional direct product links. Each one is read in detail mode. |
| `sort` | `relevance` (default), `newest`, `reviews`, `price_low`, `price_high` |
| `maxResults` | Products per keyword, 1 to 3000 (default 20) |
| `minPrice` / `maxPrice` | Price range in rupiah |
| `minRating` | Minimum star rating, 0 to 5 |
| `officialOnly` | Only Official Store listings |
| `includeDetails` | Add product-page fields (see above) |
| `proxyConfiguration` | Apify Proxy, residential group, Indonesia. Pre-filled; keep it for reliable access. |

Example:

```json
{
  "keywords": ["sepatu pria", "tas ransel"],
  "sort": "reviews",
  "maxResults": 100,
  "minPrice": 100000,
  "officialOnly": false,
  "includeDetails": false
}
```

### Pricing (pay per event)

You pay per record saved, nothing else:

- **`product`** - one listing record.
- **`product-detail`** - one record enriched from the product page (more data, higher price).

A run that finds nothing saves nothing and charges nothing. If a product page cannot be read in detail mode, you get the listing record and are charged the lower `product` price. Set a maximum spend on the run and the actor stops cleanly when it is reached.

### How it works

The actor reads the same public data the Tokopedia website loads for visitors. All traffic goes through Apify residential proxies located in Indonesia, and a request that is rate-limited or needs a retry is repeated automatically with a fresh connection. Duplicate products across pages and keywords are removed.

### Tips

- Start with a small `maxResults` to check the fields you need, then scale up.
- Use `sort: "newest"` for new-arrival tracking and `price_low` for cheapest-first sourcing.
- `reviewCount` and `ratingBreakdown` are only available in detail mode; listing mode keeps them empty rather than guessing.
- `soldCount` in listing mode is the site's rounded figure ("50+", "1rb+"); detail mode returns the more exact number when the site shows one.
- Schedule the actor daily and compare `priceIDR` over time for price monitoring.

### FAQ

**Do I need a Tokopedia account?** No.

**Which country does it cover?** Indonesia (Tokopedia storefront, rupiah prices).

**Is the data complete?** It is what Tokopedia shows publicly for each product. Fields the site does not display for a product are returned as `null`.

**What if a run returns fewer products than requested?** The search may simply have fewer matches, or the site stopped paging. The status line of the run says how many products were saved.

Use this actor only for publicly available data and in line with the applicable terms and laws in your jurisdiction.

# Actor input Schema

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

One search per keyword, e.g. sepatu lari, iphone 15, kopi arabika. Leave empty if you only provide product links.

## `productUrls` (type: `array`):

Direct product page links (https://www.tokopedia.com/<shop>/<product>). Each one returns a full detail record.

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

Order of search results.

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

Upper bound on products saved for each keyword. Tokopedia exposes roughly 3,000 results per search.

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

Only products priced at or above this amount in rupiah.

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

Only products priced at or below this amount in rupiah.

## `minRating` (type: `integer`):

Only products rated at least this many stars (1-5). Products without ratings are skipped when set.

## `officialOnly` (type: `boolean`):

Keep only products sold by Tokopedia Official Stores.

## `includeDetails` (type: `boolean`):

Open every product page to add description, specifications, variants with stock, exact sold and review counts and the star breakdown. Billed at the product-detail rate.

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

Apify Proxy settings. Indonesian residential IPs are used by default and give the most reliable results.

## Actor input object example

```json
{
  "keywords": [
    "sepatu"
  ],
  "productUrls": [],
  "sort": "relevance",
  "maxResults": 20,
  "officialOnly": false,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ID"
  }
}
```

# Actor output Schema

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

Dataset with the scraped products.

# 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"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "ID"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("deepurple/tokopedia-product-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"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "ID",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("deepurple/tokopedia-product-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"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ID"
  }
}' |
apify call deepurple/tokopedia-product-scraper --silent --output-dataset

```

## MCP server setup

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