# TikTok Shop Reviews Scraper (`toolzerhub/tiktok-shop-reviews-scraper`) Actor

Collect customer reviews for a TikTok Shop product by ID or URL, filtered by star rating or media, with automatic pagination and the product's full star distribution attached to every row.

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

## Pricing

from $5.00 / 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

## TikTok Shop Reviews Scraper

Collect customer reviews for any TikTok Shop product — star rating, review text, photos, and whether the buyer actually purchased — from a product ID or URL.

Every row also carries the product's full star breakdown, so one review is enough to know what you are looking at. A 4.7 average reads differently once you can see it is 5,543 five-star reviews and 242 one-star.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `product_id` | string | — | **Required.** A product ID, or a product page URL. |
| `region` | enum | `US` | `US`, `GB`, `SG`, `MY`, `PH`, `TH`, `VN`, `ID`. |
| `maxItems` | integer | `100` | Caps how many reviews are saved. `0` means no limit. |
| `reviewFilter` | enum | `no_filter` | `no_filter`, `with_media` (photos or video only), `verified_purchase`. |
| `reviewRating` | enum | `all` | `all`, or `5_star` … `1_star` to collect one rating only. |

```json
{
  "product_id": "1729397618688364854",
  "region": "US",
  "maxItems": 100,
  "reviewFilter": "no_filter",
  "reviewRating": "all"
}
```

A product page URL works anywhere the ID does — `https://shop.tiktok.com/view/product/1729397618688364854` and the bare ID behave identically, regional subdomains and query strings included.

### Output

One row per review.

| Field | What it holds |
|---|---|
| `review_id` | TikTok Shop review ID |
| `product_id` | Product the review belongs to |
| `sku_id` | The specific variant reviewed |
| `reviewer_id` | Account that left the review |
| `reviewer_name` | Display name, partially masked by TikTok |
| `reviewer_avatar_url` | Reviewer avatar |
| `review_rating` | 1 to 5 |
| `review_text` | Review body — empty when they rated without writing |
| `review_time` | Millisecond epoch, as a string |
| `review_images` | Photos or video attached |
| `display_image_url` | Primary review image |
| `is_verified_purchase` | TikTok confirmed they bought it |
| `is_incentivized_review` | They were rewarded for reviewing |
| `sku_specification` | Which variant — size, colour |
| `review_country` | Where the review came from |
| `product_name` | Product name carried on the record |
| `review_ratings` | Star breakdown for the whole product |

```json
{
  "review_id": "7668316668074886926",
  "review_rating": 5,
  "review_text": "Amazing 🤩",
  "is_verified_purchase": true,
  "is_incentivized_review": false,
  "review_country": "US",
  "review_ratings": {
    "review_count": "6550",
    "overall_score": 4.7,
    "rating_result": { "1": "242", "2": "86", "3": "150", "4": "529", "5": "5543" }
  }
}
```

### What people use it for

- **Read the complaints, not the average.** Set `reviewRating` to `1_star` and you get only the reviews that say what is wrong.
- **Separate real sentiment from seeded reviews.** `is_incentivized_review` marks reviewers who got a free sample or discount; `is_verified_purchase` marks confirmed buyers.
- **See the product before you sell it.** `with_media` returns only reviews with photos, which is where you find out what actually arrives in the box.
- **Track sentiment over time.** Schedule a run and diff `review_ratings.rating_result` between runs.

### Questions

**Why did I get fewer reviews than `maxItems`?**
Two reasons, and they look the same from outside. Either the product genuinely has fewer reviews, or you set a filter and it ran out of matches. A product with 6,550 reviews might have only 242 one-star ones, so `reviewRating: "1_star"` with `maxItems: 500` stops at 242. `review_ratings.rating_result` tells you the ceiling for each rating before you run.

**Why is `review_text` empty on some rows?**
TikTok lets buyers leave a star rating without writing anything. Those still count toward the product's rating and still appear here, with `review_rating` set and `review_text` empty. If you only want written reviews, filter on non-empty `review_text` after the run.

**What is `is_incentivized_review`?**
TikTok's own flag for reviewers who received something in exchange — a free sample, a discount, a gift card. It is worth splitting on: incentivized reviews skew positive, so a 4.8 average made mostly of incentivized reviews is a different signal from a 4.8 built on ordinary purchases.

**Does the star breakdown cost an extra request?**
No. `review_ratings` arrives with every page the upstream returns, so it is attached to each row for free. It describes the whole product, not the page — the same values appear on every row of a run.

**Why is `review_time` a string and not a date?**
It comes back as a millisecond epoch string, and it is passed through unchanged rather than reformatted, so nothing is lost to a timezone guess. `new Date(Number(review_time))` gives you a date.

**Can I scrape reviews for several products at once?**
One product per run. Take `product_id` from any row returned by [TikTok Shop Search Scraper](https://apify.com/toolzerhub/tiktok-shop-search-scraper) or [TikTok Shop Seller Products Scraper](https://apify.com/toolzerhub/tiktok-shop-seller-products-scraper), then drive one run per product through the Apify API.

### Other TikTok Shop Actors

| Actor | Use when |
|---|---|
| [TikTok Shop Search Scraper](https://apify.com/toolzerhub/tiktok-shop-search-scraper) | You are finding products by keyword |
| [TikTok Shop Products Scraper](https://apify.com/toolzerhub/tiktok-shop-products-scraper) | You want products plus full detail |
| [TikTok Shop Product Scraper](https://apify.com/toolzerhub/tiktok-shop-product-scraper) | You want one product's full record |
| [TikTok Shop Seller Products Scraper](https://apify.com/toolzerhub/tiktok-shop-seller-products-scraper) | You want one shop's entire catalogue |
| [TikTok Shop Category Products Scraper](https://apify.com/toolzerhub/tiktok-shop-category-products-scraper) | You want a whole category, without a keyword |

### Support

Questions, bugs, or feature requests: **contact@toolzerhub.com**

Browse the rest: [apify.com/toolzerhub](https://apify.com/toolzerhub)

# Actor input Schema

## `product_id` (type: `string`):

TikTok Shop product ID, or a product page URL (https://shop.tiktok.com/view/product/<id>), to fetch full product details for.

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

TikTok Shop region code.

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

Maximum number of products to save in search mode. Set 0 for no limit.

## `reviewFilter` (type: `string`):

Which reviews to collect.

## `reviewRating` (type: `string`):

Only collect reviews with this rating.

## Actor input object example

```json
{
  "product_id": "1732432759321694958",
  "region": "US",
  "maxItems": 20,
  "reviewFilter": "no_filter",
  "reviewRating": "all"
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all 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 = {
    "product_id": "1729401495861891109",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("toolzerhub/tiktok-shop-reviews-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 = {
    "product_id": "1729401495861891109",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("toolzerhub/tiktok-shop-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "product_id": "1729401495861891109",
  "maxItems": 20
}' |
apify call toolzerhub/tiktok-shop-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=toolzerhub/tiktok-shop-reviews-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/syPf4EiYYcuF54M3u/builds/hWdstNBdg6GB4RZ6C/openapi.json
