# TikTok Shop Related Products Scraper (`thenetaji/tiktok-shop-recommendations-scraper`) Actor

See what TikTok Shop recommends next to any product. Choose a carousel — 'you may like', 'more from this shop', or the seller's top-reviewed items — and export every product it shows, with prices, ratings and units sold.

- **URL**: https://apify.com/thenetaji/tiktok-shop-recommendations-scraper.md
- **Developed by:** [The Netaji](https://apify.com/thenetaji) (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 $3.19 / 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 Recommendations Scraper

The Actor collects one of three recommendation carousels that TikTok Shop attaches to a product page: the `you may like` rail, the `more from this shop` rail, or the seller's top-reviewed products. `scraperType` selects which carousel a run collects, and the two rail families return different card shapes rather than one shared shape.

```json
{
  "scraperType": "youMayLike",
  "product_ids": [
    "1730927783781307026",
    "https://shop.tiktok.com/us/pdp/maybelline-new-york-serum-lipstick-8h-moisture-satin-matte/1731756086010286738"
  ],
  "region": "US",
  "maxItems": 100,
  "enrichProductDetails": false
}
```

### Accepted input

`scraperType` is required and defaults to `youMayLike`; the other options are `moreFromShop` and `topReviewed`. `product_ids` is required and accepts TikTok Shop product page links, product IDs, or both mixed in the same list; each product is fetched with its own request, so a run against ten `product_ids` makes ten requests regardless of `scraperType`. `region` is required, defaults to `US`, and selects the storefront read (`US`, `GB`, `SG`, `MY`, `PH`, `TH`, or `VN`); this changes the products, prices, and currency returned, not only the display language. `maxItems` defaults to `100` and bounds the number of rows saved across the whole run; a value of `0` removes the bound. `enrichProductDetails` defaults to `false` and adds the full product page to every row: description, every variant, the shop profile, a page of reviews with the star breakdown, and the category path. It costs one extra request per row, so it is worth leaving off on a first pass.

### Result fields

Every row carries `product_id`, `rail` (`you_may_like`, `more_from_shop`, or `top_reviewed`, matching `scraperType`), and `source_product_id`, which names the product whose page produced the recommendation rather than the recommended product itself. Beyond those three, the row shape depends on which carousel was collected.

`youMayLike` and `moreFromShop` return TikTok's standard listing card: `title`, `image`, `product_price_info`, `rate_info`, `sold_info`, `seller_info`, `seo_url`, `sku_info`, `brand_info`, and `product_marketing_info`. `topReviewed` returns a different card built around review standing rather than a listing feed: `name` where the listing card has `title`, `price_info` where it has `product_price_info`, `product_rating` and `review_count` where it has `rate_info`, `review_overviews` (short excerpts pulled from real reviews), and `canonical_url` where it has `seo_url`. A `youMayLike` or `moreFromShop` row leaves `name`, `price_info`, `product_rating`, `review_overviews`, and `canonical_url` null; a `topReviewed` row leaves `title`, `product_price_info`, `rate_info`, `sold_info`, and `seo_url` null. `product_card` holds the untouched card exactly as TikTok returned it either way, so nothing broken out above is ever the only copy.

With `enrichProductDetails` set to `true`, every row also gains `shop_info`, `review_info`, `categories`, `promotion_tag`, and `product_detail`: the same detail fields the product's own page carries.

```json
{
  "product_id": "1731896769144001226",
  "rail": "you_may_like",
  "source_product_id": "1730927783781307026",
  "title": "Hydrating Lip Gloss - High Shine & Tinted, Infused with Hyaluronic Acid, Jojoba Oil & Shea Butter",
  "product_price_info": { "currency_name": "USD", "sale_price_format": "13.23", "discount_format": "59%" },
  "rate_info": { "score": 4.5, "review_count": "7814" },
  "sold_info": { "sold_count": 73428 },
  "seller_info": { "seller_id": "7495153913553128138", "shop_name": "Truly Beauty" }
}
```

The same page's `topReviewed` carousel returns a card shaped like this instead:

```json
{
  "product_id": "1729447567685489298",
  "rail": "top_reviewed",
  "source_product_id": "1730927783781307026",
  "name": "Lifter Gloss, Hydrating Lip Gloss with Hyaluronic Acid, High Shine for Plumper Looking Lips, Maybelline New York",
  "product_rating": 4.6,
  "review_count": "332",
  "canonical_url": "https://shop.tiktok.com/us/pdp/lifter-gloss-by-maybelline-new-york-hydrating-lip-gloss-with-hyaluronic-acid/1729447567685489298"
}
```

These are trimmed, live-verified rows; `product_price_info`, `seller_info`, `review_overviews`, and `product_card` each carry more fields than shown here.

### A product that cannot be read

Any product whose request fails is logged with a warning and skipped, and the run continues with the remaining `product_ids` rather than ending. This holds whether the ID is unresolvable or the request failed for another reason, so one bad entry in a list of ten costs that entry alone. A run in which every product fails still finishes normally with zero rows saved, and the warnings in the log are where the reason is recorded. The one input rejected before any request is made is an empty `product_ids` list.

### Whether maxItems drives further requests

It does not. None of the three carousels paginate. `you may like`, `more from this shop`, and the top-reviewed list are each returned complete in a single response, however long TikTok made that response, so `maxItems` only trims what came back. A product whose `you may like` rail carries six cards returns at most six rows for that product no matter how high `maxItems` is set.

### What source\_product\_id points at

`source_product_id` always names the product being read, never the product being recommended. Running the Actor against several `product_ids` with `scraperType` set to `topReviewed` produces one `source_product_id` per input product, each attached to that seller's own best-reviewed cards. The rating carried on those cards belongs to the recommended products, not to the input product.

### Related Actors

For a single product's own full record (description, images, reviews, and category path), use the [TikTok Shop Product Scraper](https://apify.com/thenetaji/tiktok-shop-product-scraper). For discovering products by keyword rather than starting from a product page, use the [TikTok Shop Search Scraper](https://apify.com/thenetaji/tiktok-shop-search-scraper). For what surrounds a keyword search instead of a product page (related terms, the shops ranking for it, or its own recommendation widgets), use the [TikTok Shop Search Insights Scraper](https://apify.com/thenetaji/tiktok-shop-search-insights-scraper). For what TikTok Shop is featuring on its homepage rather than on one product's page, use the [TikTok Shop Trending Scraper](https://apify.com/thenetaji/tiktok-shop-trending-scraper).

# Actor input Schema

## `scraperType` (type: `string`):

Choose which product-page recommendation carousel this run collects.

## `product_ids` (type: `array`):

One or more TikTok Shop products to fetch. Paste product page links, or product IDs — both work, and you can mix them.

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

Which TikTok Shop storefront to read. This changes the products, prices, and currency you get back — not just the display language.

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

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

## `enrichProductDetails` (type: `boolean`):

Add the full product page to every row — description, all variants, shop profile, a page of reviews with the star breakdown, and the category path. This makes one extra request per product.

## Actor input object example

```json
{
  "scraperType": "youMayLike",
  "product_ids": [
    "1730927783781307026"
  ],
  "region": "US",
  "maxItems": 20,
  "enrichProductDetails": false
}
```

# Actor output Schema

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

All records scraped by this run

# 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_ids": [
        "https://shop.tiktok.com/us/pdp/1730927783781307026"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/tiktok-shop-recommendations-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_ids": ["https://shop.tiktok.com/us/pdp/1730927783781307026"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/tiktok-shop-recommendations-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 '{
  "product_ids": [
    "https://shop.tiktok.com/us/pdp/1730927783781307026"
  ],
  "maxItems": 20
}' |
apify call thenetaji/tiktok-shop-recommendations-scraper --silent --output-dataset

```

## MCP server setup

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