# TikTok Shop Scraper - Products, Sales & Sellers (`muhammadafzal/tiktok-shop-scraper`) Actor

Scrape US TikTok Shop products, prices, sold counts, ratings, SKU stock and sellers by keyword, product URL or store URL for commerce research.

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

## Pricing

from $16.00 / 1,000 tiktok shop products

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

## TikTok Shop Scraper - Products, Sales & Sellers

Find public US TikTok Shop products by keyword, collect a seller's catalog, or enrich known product URLs with prices, displayed sold counts, ratings, sellers, and SKU stock. Data is retrieved through ScrapeCreators using the owner's private provider credential; customers do not supply an API key.

### Product research and competitor tracking

Use keyword search to discover products and sellers in a niche, seller mode to monitor a known shop, and product mode to retrieve detailed variants. Export the default dataset as JSON, CSV, Excel, or through the Apify API. Run repeated snapshots through a schedule to compare prices and source-reported counts over time.

This Actor supports **US TikTok Shop only**. It does not retrieve private orders, buyer identities, authenticated seller dashboards, verified revenue, daily sales, commissions, or historical sales. `soldCount` is a displayed product count, not an audited transaction total. Multiplying today's price by a sold count cannot establish revenue. SKU stock is a current source-reported snapshot and may change.

### Choose an input mode

| Field | Default | Meaning |
| --- | --- | --- |
| `mode` | `search` | `search`, `products`, or `seller` |
| `queries` | `makeup brush` if omitted | 1–20 keyword strings, each 1–100 characters; search only |
| `productUrls` | None | 1–20 public product URLs; products only |
| `sellerUrls` | None | 1–20 public store URLs; seller only |
| `maxItems` | 20 | Maximum distinct products across sources; 1–500 |
| `maxPages` | 1 | Maximum search/catalog pages per source; 1–20 |
| `maxRequests` | 30 | Maximum provider attempts including enrichment and retries; 1–100 |
| `timeoutSecs` | 300 | Scraping deadline; 30–600 seconds |
| `enrichProducts` | false | Add product-detail requests for search/catalog results |
| `sortBy` | `top` | Catalog ordering: `top` or `new_releases` |
| `region` | `US` | Other regions are rejected |

Keyword search preserves the provider’s ranking and may return loosely related recommendations, even for a nonsense query; it is not an exact-match filter. A nonexistent or region-unavailable product is reported as `NOT_FOUND` with zero product records. Supply only the source field corresponding to the chosen mode. Omitted search keywords use the default; an explicitly empty source list is rejected. Shortened links, TikTok user profiles, plain seller names, and arbitrary external URLs are unsupported. Duplicate input sources and product IDs are deduplicated. Verified Apify free-plan runs deliver **at most five products**. Paid runs retain the requested cap, subject to the event budget and operational bounds.

#### Search products by keyword

```json
{"mode":"search","queries":["makeup brush"],"maxItems":20,"maxPages":1}
```

#### Monitor a seller catalog

```json
{"mode":"seller","sellerUrls":["https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079"],"maxItems":10,"maxPages":1,"sortBy":"top"}
```

#### Get product details and SKU stock

```json
{"mode":"products","productUrls":["https://www.tiktok.com/shop/pdp/maange-professional-makeup-brushes-kit/1732268112597913939"],"maxItems":1}
```

Paste an example into the Apify Console input editor, or POST it to `https://api.apify.com/v2/acts/muhammadafzal~tiktok-shop-scraper/runs` with your own Apify authorization header. After the run completes, retrieve `defaultDatasetId` and `defaultKeyValueStoreId` from the run response. If using an Apify agent integration, select this Actor for public US shop product data and pass the same input object; check `SUMMARY` before interpreting an empty dataset.

### Output fields

Each dataset row is one unique product. Catalog metadata is repeated on its products to make CSV exports useful; **do not sum seller-wide counts across rows**.

| Fields | Source meaning |
| --- | --- |
| `productId`, `title`, `productUrl` | Public product identity and page |
| `price`, `originalPrice`, `currency` | Current starting price and source-reported list price |
| `soldCount`, `soldCountText` | Numeric and textual displayed sold counts when supplied |
| `rating`, `reviewCount` | Product rating and review count |
| `imageUrls` | Public product images; CDN URLs may expire |
| `skus` | Detail variants: `skuId`, `stock`, `price`, `originalPrice`, `currency`, `options` |
| `sellerId`, `sellerName`, `sellerUrl` | Seller identity and public store |
| `sellerRating`, `sellerLocation` | Available shop rating and seller location |
| `sellerSoldCount`, `sellerProductCount`, `sellerFollowersCount` | Available shop-wide metadata, especially in catalog mode |
| `region`, `source`, `inputSource`, `inputMode`, `scrapedAt` | Coverage, provenance and collection timestamp |

Unavailable values are `null`; unavailable arrays are empty. A missing sold count is never replaced with zero. Rounded counts such as `1.2K+` are not converted into fabricated exact counts. The Actor accepts both flattened and wrapped detail responses currently encountered from the provider. Product IDs remain strings to preserve their precision.

A representative captured search record contains product `1732268112597913939`, title beginning `MAANGE Professional Makeup Brushes Kit`, currency `USD`, price `11.99`, displayed sold count `2708`, and rating `4.8`. These are a historical probe snapshot, not a promise of current availability or price. The complete record schema is defined in `.actor/dataset_schema.json`.

### Pricing

The Actor is prepared for all-in Pay per event: one synthetic run-start event and one primary default-dataset-item event per delivered product, including enriched products. It never manually charges either synthetic event or adds a second enrichment charge. The proposed tier table is below. **Live pricing awaits owner approval and billing verification.**

| Event | FREE | BRONZE (2.5% off) | SILVER (5% off) | GOLD (20% off) |
| --- | ---: | ---: | ---: | ---: |
| Run start | $0.0125 | $0.0121875 | $0.011875 | $0.0100 |
| Delivered product | $0.0200 | $0.0195 | $0.0190 | $0.0160 |

At the proposed FREE prices, one product costs $0.0325, 20 products cost $0.4125, and 100 products cost $2.0125. No separate enrichment event is charged. Owner-run platform usage and the separately billed provider credits are measured independently; provider invoice costs are not established by Apify run usage. Platform-usage pass-through remains disabled.

Empty results and failed retrievals produce no product events. A configured synthetic start fee still applies to a started run, including unsuccessful runs. `maxTotalChargeUsd` controls event charges; `maxRequests`, `maxPages`, `maxItems`, and the scraping deadline independently bound work. A provider request may return more records than the remaining result limit; only the permitted products are delivered and charged.

### Reliability and diagnostics

ScrapeCreators is the explicitly selected data source. Public direct probes returned a TikTok security check or invalid-product response, so this Actor does not attempt to solve CAPTCHAs or use customer cookies. Provider requests run sequentially with a 45-second timeout, bounded retries, exponential backoff, and jitter. Seller pagination uses the response cursor; keyword pagination uses page numbers. To bound low-value work, the Actor stops after five consecutive provider attempts without a delivered product. This circuit breaker can end a list containing many empty sources; `NO_VALUE_REQUEST_LIMIT` is reported explicitly. It also stops on empty pages, repeated cursors, no new product identities, source exhaustion, or any configured limit. It does not promise a complete catalog beyond those limits.

Valid partial results are preserved. Optional enrichment failure retains validated listing data and records a warning. Credential errors and exhausted provider credits stop the run promptly. Systemic provider denial or rate limits stop further spending. Run diagnostics belong in the `SUMMARY` key-value record, never in the product dataset. Review its status, delivered count, requests, provider credit consumption, warnings, stop reason, and result event count. Source schema changes or provider failures are distinguished from a healthy no-match response; a successful container alone does not prove that data was returned.

Migration/abort signals stop pending requests, and dataset identities are loaded on a resumed run to prevent duplicate writes. Local storage is not uploaded and cannot prove cloud billing behavior.

### Owner setup, development and support

The owner must configure `SCRAPECREATORS_API_KEY` as a private Actor-version secret. Keep keys out of customer input, source files, logs, examples, and public metadata. Development commands are `npm ci`, `npm test`, `npm run check`, and a bounded `apify run --purge`. `scripts/configure-secret.py` transfers only the current owner's configured credential via stdin, withholding the API response.

Use collected public commerce data for legitimate research and follow the source platform and provider terms. Respect applicable data-protection requirements. This Actor is independent of TikTok and makes no affiliation claim. Report reproducible problems with the run ID, mode, redacted input and `SUMMARY` record; never include API keys. Private deployment and test evidence are recorded in `evidence/`; publication and branding remain the owner's actions.

# Actor input Schema

## `mode` (type: `string`):

Use search for keywords, products for known product URLs, or seller for a shop catalog. Only US public TikTok Shop data is supported.

## `queries` (type: `array`):

Use with search mode only. Enter 1–20 keywords, each 1–100 characters, for example makeup brush. Omit to use makeup brush; an explicit empty array is rejected.

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

Use with products mode only. Enter up to 20 HTTPS TikTok Shop /shop/pdp/ URLs ending in a product ID. Short links and usernames are unsupported.

## `sellerUrls` (type: `array`):

Use with seller mode only. Enter up to 20 TikTok /shop/store/ URLs, for example https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079. User profiles are unsupported.

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

Use to cap deduplicated products across all sources. Default 20; range 1–500. Verified free-plan runs deliver at most five results. Billing limits can reduce the effective cap.

## `maxPages` (type: `integer`):

Use to bound search or seller pagination. Default 1; range 1–20 per source. Product-detail mode uses one request per URL. Catalog cursor and search page pagination stop at other limits.

## `maxRequests` (type: `integer`):

Use to cap total ScrapeCreators attempts, including enrichment and retries. Default 30; range 1–100. Reaching this cap preserves already fetched valid products.

## `timeoutSecs` (type: `integer`):

Use to bound scraping time excluding startup. Default 300; range 30–600. Each provider request also has a 45-second deadline.

## `enrichProducts` (type: `boolean`):

Use to request additional SKU stock, seller location, and product-detail fields for each search/catalog result. Adds one provider request per product before retries. Unavailable detail fields remain null; listing data is preserved on optional enrichment failure.

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

Use with seller mode to request best-selling or newest products. Does not reorder keyword searches.

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

US only. Other regions are rejected because current provider coverage is inconsistent.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "makeup brush"
  ],
  "maxItems": 20,
  "maxPages": 1,
  "maxRequests": 30,
  "timeoutSecs": 300,
  "enrichProducts": false,
  "sortBy": "top",
  "region": "US"
}
```

# Actor output Schema

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

Deduplicated public products, displayed sales counts and seller fields.

## `summary` (type: `string`):

Delivered counts, request/credit usage, errors and stop reason.

# 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 = {
    "queries": [
        "makeup brush"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/tiktok-shop-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 = { "queries": ["makeup brush"] }

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/tiktok-shop-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 '{
  "queries": [
    "makeup brush"
  ]
}' |
apify call muhammadafzal/tiktok-shop-scraper --silent --output-dataset

```

## MCP server setup

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