# TikTok Shop Review Scraper — Ratings & Photos (`herus13/tiktok-shop-review-scraper`) Actor

Scrape TikTok Shop product reviews by product URL or keyword across 10 storefronts, Indonesia included. Each row carries rating, review_text, review_time, reviewer_name, sku_specification, is_verified_purchase and image_urls. Filter by star rating. Export JSON, CSV or Excel.

- **URL**: https://apify.com/herus13/tiktok-shop-review-scraper.md
- **Developed by:** [herus13](https://apify.com/herus13) (community)
- **Categories:** E-commerce, Social media, Automation
- **Stats:** 3 total users, 1 monthly users, 73.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 product reviews

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

The TikTok Shop Review Scraper extracts product reviews from TikTok Shop, one row per review: star rating, review text, review date, masked reviewer name, the variant bought, the verified-purchase flag and review photos. Give product URLs or keywords, pick one of 10 storefronts, and filter by star rating.

### What you get

One row per review, most recent first. Products are only looked up to find their reviews: they are not rows and are not charged.

```json
{
  "record_type": "review",
  "review_id": "7683011426013054734",
  "product_id": "1729470894545670276",
  "sku_id": "1732526919169183876",
  "reviewer_id": "7356323980992791595",
  "reviewer_name": "g**1",
  "rating": 5,
  "review_text": "Sound is clear and the case charges fast. Fits well for runs.",
  "review_time": "2026-09-08T12:34:58Z",
  "is_verified_purchase": true,
  "is_incentivized": false,
  "image_urls": ["https://p16-oec-va.ibyteimg.com/tos-maliva-i-o3syd03w52-us/example~tplv-o3syd03w52-origin-jpeg.jpeg"],
  "sku_specification": "Dark Grey",
  "review_country": "TH",
  "product_url": "https://shop.tiktok.com/th/pdp/1730043105674103721",
  "region": "TH",
  "scraped_at": "2026-09-29T09:00:00Z",
  "_meta": {"author": "https://apify.com/herus13", "status": "ok", "message": null}
}
```

`_meta` is run metadata, not scraped data. A product whose reviews could not be read appears as a row with only `_meta` (status `failed`, the reason in `message`); those rows are never charged. Reviewer names arrive masked by the storefront itself. Indonesian rows come from Tokopedia, where TikTok Shop Indonesia sells, and carry the same columns; `is_verified_purchase` and `is_incentivized` are empty there.

### What it costs

| Event | Price |
|---|---|
| Actor Start (`apify-actor-start`) | $0.00005 |
| product review (`review-result`) | $0.0015 |

You pay per review delivered: $1.50 per 1,000 reviews, plus a start charge of $0.00005 per GB of run memory (about $0.0001 per run at the default 2 GB). Products are never charged, and unused headroom costs nothing: ask for 100 reviews from a product that has 17 and you are charged for 17. The residential proxy the run needs is included in the price.

### Input

| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
| `productUrls` | array | no | — | Product page URLs to pull reviews from, one per entry. Most regions: `https://shop.tiktok.com/{region}/pdp/{slug}/{product_id}`. For `ID` (Indonesia, served by Tokopedia): `https://www.tokopedia.com/{shop}/{product-slug}`. Give at least one of productUrls or searchTerms; leave empty to take products from searchTerms only. |
| `searchTerms` | array | no | — | Keywords to search the storefront for. The top products of each search (see maxProductsPerSearch) are looked up and their reviews returned; the products themselves are not rows. Examples: `wireless earbuds`, `serum`. Give at least one of productUrls or searchTerms; leave empty to use productUrls only. |
| `region` | string | no | `"TH"` | TikTok Shop storefront the products belong to. It decides the language of the reviews and where the products are searched. Default `TH`. Supported: `US`, `VN`, `TH`, `PH`, `MY`, `SG`, `ID` (reviews come from Tokopedia, where TikTok Shop Indonesia sells), `GB`, `MX`, `JP` (no keyword search on these three; use productUrls). `BR` is unavailable: choosing it ends the run at once, charging only the start fee. Product URLs must belong to this storefront. |
| `maxReviewsPerProduct` | integer | no | `100` | How many reviews to return for each product, most recent first. Default 100, minimum -1. Set 0 to return none. Set -1 for no limit, which reads every review the storefront lists for the product. Each review row is charged, so a product with thousands of reviews at -1 is a large run. |
| `maxProductsPerSearch` | integer | no | `10` | How many of the top products of each search term to pull reviews from. Default 10, minimum 0, maximum 1000. Set 0 to skip searchTerms entirely. Products are not charged; only their reviews are. |
| `ratings` | array | no | — | Only reviews with these star ratings, for example 1 and 2 for complaints or 5 for praise. With several ratings, each rating's reviews come in turn, lowest first, most recent first within a rating, sharing maxReviewsPerProduct. Leave empty for every rating. |
| `proxyUrls` | array | no | — | Leave empty: the run uses the residential proxy this actor ships with, included in the price of the run. To route the run through your own provider instead, add one gateway URL per entry, for example `http://user:pass@host:port` — works with any provider that issues URLs. When set, the run uses these first and switches to the included proxy if they stop working, so a broken proxy never fails the run. |

### How to run it

1. Paste product URLs, type keywords, or both, and pick the storefront in Region.
2. Set Max reviews per product: 100 by default, -1 for every review.
3. Optionally pick star ratings, for example 1 and 2 to read only complaints.
4. Run it and export the dataset as JSON, CSV or Excel.

The 1- and 2-star reviews of the top 10 wireless earbuds on the Thai storefront, up to 50 each:

```json
{
  "searchTerms": ["wireless earbuds"],
  "region": "TH",
  "maxProductsPerSearch": 10,
  "maxReviewsPerProduct": 50,
  "ratings": ["1", "2"]
}
```

Minimal input:

```json
{
  "productUrls": ["https://shop.tiktok.com/th/pdp/rongethaaeta-hawot-hot-khnad-40-44-phuen-hna-2-cm-sinkha-phrom-sng/1729516526618249873"],
  "region": "TH",
  "maxReviewsPerProduct": 20
}
```

Available as the MCP tool `herus13--tiktok-shop-review-scraper` on mcp.apify.com, so an AI agent can call it with the same input.

### Use cases

- **Sellers and brands** read what buyers say about their own and competing products, and watch new reviews after a launch or a restock.
- **Product research**: collect the 1- and 2-star reviews of a category's best sellers to find the defects and gaps a new product could fix.
- **Sentiment and topic analysis**: feed review text, stars and dates into a model or a spreadsheet to track satisfaction over time, per variant.
- **Agencies and affiliates** vet a product before promoting it, using real buyer photos and the verified-purchase flag.
- **Market comparison across Southeast Asia**: pull reviews of the same product type in Vietnam, Thailand, the Philippines, Malaysia, Singapore and Indonesia, each in the buyers' own language.

### FAQ

**Does it need a TikTok account?** No. It reads the reviews any visitor can see on the storefront, without logging in.

**Which storefronts work?** Pick one of US, VN, TH, PH, MY, SG, ID, GB, MX or JP in Region. Product URLs must belong to that storefront. Indonesia (ID) is served by Tokopedia, so give Tokopedia product URLs there. GB, MX and JP have no keyword search on TikTok Shop, so give product URLs for those. Brazil (BR) is unavailable: a run that names it ends at once with a message.

**Are the products charged?** No. Products found by URL or keyword are only used to reach their reviews. Only review rows are charged.

**How does the star filter work?** Pick one or more ratings. The storefront is asked for those stars only, so a run for 1-star reviews does not read the 5-star ones. With several ratings, each rating's reviews come in turn, lowest first, sharing Max reviews per product.

**Why did a product return no rows?** Either it has no reviews (or none with the stars you picked), which the log says, or the storefront refused to list its reviews for that run, which shows as a failed row with only `_meta`. A refused product is never reported as having zero reviews; try again later.

**How many reviews can one product return?** As many as the storefront lists, with Max reviews per product set to -1. Each review is one charged row, so start with the default of 100.

**Is a proxy included?** Yes, a residential proxy in the storefront's country is included in the price of the run. You can paste your own gateway URLs into Your own proxy URLs instead.

### Related actors

- [TikTok Shop Scraper](https://apify.com/herus13/tiktok-shop-scraper) — TikTok Shop products by keyword, category or URL, with price, seller, rating and sold count.
- [Lazada Scraper](https://apify.com/herus13/lazada-scraper) — products from Lazada across Southeast Asia.

# Actor input Schema

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

Product page URLs to pull reviews from, one per entry. Most regions: `https://shop.tiktok.com/{region}/pdp/{slug}/{product_id}`. For `ID` (Indonesia, served by Tokopedia): `https://www.tokopedia.com/{shop}/{product-slug}`. Give at least one of productUrls or searchTerms; leave empty to take products from searchTerms only.

## `searchTerms` (type: `array`):

Keywords to search the storefront for. The top products of each search (see maxProductsPerSearch) are looked up and their reviews returned; the products themselves are not rows. Examples: `wireless earbuds`, `serum`. Give at least one of productUrls or searchTerms; leave empty to use productUrls only.

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

TikTok Shop storefront the products belong to. It decides the language of the reviews and where the products are searched. Default `TH`. Supported: `US`, `VN`, `TH`, `PH`, `MY`, `SG`, `ID` (reviews come from Tokopedia, where TikTok Shop Indonesia sells), `GB`, `MX`, `JP` (no keyword search on these three; use productUrls). `BR` is unavailable: choosing it ends the run at once, charging only the start fee. Product URLs must belong to this storefront.

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

How many reviews to return for each product, most recent first. Default 100, minimum -1. Set 0 to return none. Set -1 for no limit, which reads every review the storefront lists for the product. Each review row is charged, so a product with thousands of reviews at -1 is a large run.

## `maxProductsPerSearch` (type: `integer`):

How many of the top products of each search term to pull reviews from. Default 10, minimum 0, maximum 1000. Set 0 to skip searchTerms entirely. Products are not charged; only their reviews are.

## `ratings` (type: `array`):

Only reviews with these star ratings, for example 1 and 2 for complaints or 5 for praise. With several ratings, each rating's reviews come in turn, lowest first, most recent first within a rating, sharing maxReviewsPerProduct. Leave empty for every rating.

## `proxyUrls` (type: `array`):

Leave empty: the run uses the residential proxy this actor ships with, included in the price of the run. To route the run through your own provider instead, add one gateway URL per entry, for example `http://user:pass@host:port` — works with any provider that issues URLs. When set, the run uses these first and switches to the included proxy if they stop working, so a broken proxy never fails the run.

## Actor input object example

```json
{
  "productUrls": [
    "https://shop.tiktok.com/th/pdp/tws-air31-hufang-bluthuth-airsay-5-3-edr-kan-ehngueo-aela-fun/1730043105674103721"
  ],
  "region": "TH",
  "maxReviewsPerProduct": 100,
  "maxProductsPerSearch": 10
}
```

# Actor output Schema

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

One row per product review with rating, review text, review time, reviewer, variant and photos. Each row also carries `_meta`: run metadata, not scraped data.

# 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 = {
    "productUrls": [
        "https://shop.tiktok.com/th/pdp/tws-air31-hufang-bluthuth-airsay-5-3-edr-kan-ehngueo-aela-fun/1730043105674103721"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("herus13/tiktok-shop-review-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 = { "productUrls": ["https://shop.tiktok.com/th/pdp/tws-air31-hufang-bluthuth-airsay-5-3-edr-kan-ehngueo-aela-fun/1730043105674103721"] }

# Run the Actor and wait for it to finish
run = client.actor("herus13/tiktok-shop-review-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 '{
  "productUrls": [
    "https://shop.tiktok.com/th/pdp/tws-air31-hufang-bluthuth-airsay-5-3-edr-kan-ehngueo-aela-fun/1730043105674103721"
  ]
}' |
apify call herus13/tiktok-shop-review-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,herus13/tiktok-shop-review-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/qfVf6psqNQ5ZR3Di8/builds/cWfoV0rHJWaNNaukE/openapi.json
