# TikTok Comments Scraper (Cheap) (`data_api/tiktok-comments-scraper-cheap`) Actor

TikTok comment scraper that pulls comments and replies from any public post, so researchers and marketers get usable data without copying a single comment by hand.

- **URL**: https://apify.com/data\_api/tiktok-comments-scraper-cheap.md
- **Developed by:** [Data API](https://apify.com/data_api) (community)
- **Categories:** Social media, Automation, Developer tools
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 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 Comments Scraper

![TikTok Comments Scraper](cover.jpg)

Reading a TikTok comment section by hand is slow, and there is no export button. If you want to know what people actually say under a video — the praise, the questions, the complaints, who is replying to whom — you end up scrolling and copy-pasting forever. This scraper does the scrolling for you. Paste one or more TikTok links and it pulls every comment as a clean row: the text, the author handle, the like count, the language, the post time, and the reply threads tucked underneath. Hand it a single video or a whole list, and export the lot to a spreadsheet.

### What you get

Each comment comes back as one row with a steady shape, so your columns line up when you load the data into a sheet or database. Three kinds of data per comment:

- **Who and where** — `videoUrl`, `videoId`, `commentRef`, `authorHandle`, `authorName`
- **The comment itself** — `commentBody`, `likesTotal`, `repliesTotal`, `languageCode`, `pinnedByCreator`, `postedAt`
- **Threads and timing** — `replyList` (the nested replies) and `collectedAt`

### Quick start

1. Hit **Try for free** and open the input form.
2. Paste one or more TikTok links into **TikTok video URLs** — video, photo, or short vm.tiktok.com links all work.
3. Set **Comments per video** to cap the run, and leave **Collect reply threads** on if you want the replies too.
4. Press **Start**, then export the results as JSON, CSV, Excel, or XML when it finishes.

![How it works](how-it-works.jpg)

### Use cases

- **Audience research** — read what your followers ask for and react to, in their own words
- **Brand and sentiment monitoring** — track how people respond to a campaign or a mention across many videos
- **Creator and competitor analysis** — see which comments get pinned and which ones pull the most likes
- **Community management** — pull questions and complaints into one list so nothing slips by
- **Trend spotting** — catch the slang, links, and recurring asks bubbling up in a niche
- **Translation and language work** — filter by `languageCode` to gather comments in a specific language

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `videoUrls` | array of strings | Yes | Public TikTok post links to scrape comments from. Video, photo, and short vm.tiktok.com links all work; each is scraped on its own. |
| `commentsLimit` | integer | No | Top-level comments to pull per link. Default `50`; set up to `100000` for the full thread. |
| `fetchReplies` | boolean | No | Also collect the replies nested under each comment. Default `true`. |
| `repliesLimit` | integer | No | Maximum replies to grab per comment. Default `30`; only used when `fetchReplies` is on. |
| `requestTimeoutSeconds` | integer | No | Seconds to wait on each request to TikTok. Default `45`; raise it if timeouts appear. |
| `proxyConfiguration` | object | No | Proxies used for requests. Datacenter is the default; switch to Residential if TikTok blocks datacenter IPs. |

#### Example input

```json
{
    "videoUrls": [
        "https://www.tiktok.com/@khaby.lame/video/7137423965982997765",
        "https://www.tiktok.com/@zachking/video/7195741739927440683"
    ],
    "commentsLimit": 50,
    "fetchReplies": true,
    "repliesLimit": 30,
    "requestTimeoutSeconds": 45,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
}
```

### Output

Every comment becomes one row, with its replies embedded as an array on that same row. If a link cannot be processed, the scraper still writes a row carrying the `videoUrl` and an `errorMessage` so nothing is lost silently.

#### Example output

```json
{
    "videoUrl": "https://www.tiktok.com/@khaby.lame/video/7137423965982997765",
    "videoId": "7137423965982997765",
    "commentRef": "7137580012345678901",
    "authorHandle": "marco.vlogs",
    "authorName": "Marco",
    "commentBody": "This had me laughing way harder than it should have 😂",
    "likesTotal": 1843,
    "repliesTotal": 2,
    "languageCode": "en",
    "pinnedByCreator": false,
    "postedAt": "2026-06-21T14:32:07+00:00",
    "replyList": [
        {
            "commentId": "7137590098765432109",
            "username": "lena_k",
            "nickname": "Lena",
            "commentText": "same, replayed it five times",
            "likeCount": 37,
            "commentLanguage": "en",
            "createdAt": "2026-06-21T15:01:44+00:00",
            "scrapedAt": "2026-06-30T12:00:00.000000+00:00"
        }
    ],
    "collectedAt": "2026-06-30T12:00:00.000000+00:00",
    "errorMessage": null
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `videoUrl` | string | The TikTok post link this row was pulled from |
| `videoId` | string | TikTok's numeric post ID, read out of the URL |
| `commentRef` | string | Unique identifier TikTok assigns to the comment |
| `authorHandle` | string | The @username of the commenter |
| `authorName` | string | Display name shown next to the comment |
| `commentBody` | string | Full text of the comment |
| `likesTotal` | integer | How many likes the comment has collected |
| `repliesTotal` | integer | Number of replies sitting under this comment |
| `languageCode` | string | Language tag TikTok detected, such as en, es, or fr |
| `pinnedByCreator` | boolean | True when the post author pinned this comment |
| `postedAt` | string | ISO 8601 timestamp of when the comment was written |
| `replyList` | array | Replies nested under the comment, each with commentId, username, nickname, commentText, likeCount, commentLanguage, createdAt, and scrapedAt |
| `collectedAt` | string | ISO 8601 timestamp of when the row was captured |
| `errorMessage` | string | Reason a link failed; `null` on success |

### Tips for best results

- **Start small.** Run one or two links with a low `commentsLimit` first to confirm the output fits your pipeline, then open it up.
- **Turn off `fetchReplies` for speed.** Replies mean an extra call per comment thread. If you only need top-level comments, switch it off and the run finishes faster and cheaper.
- **Switch to Residential if you get blocked.** Datacenter proxies clear most videos; residential helps when you see repeated errors or empty responses.
- **Raise `requestTimeoutSeconds`** to around 60 on residential proxies or when pulling very large threads.
- **Big threads take time.** A high `commentsLimit` paired with replies on a viral video is a lot of pages — cap it while testing, then raise it for the full pull.

### How can I use TikTok comments data?

**How can I use the TikTok Comments Scraper to gauge how an audience reacted to a video?**
Paste the video link, leave `fetchReplies` on, and run it. Each row gives you the `commentBody`, `likesTotal`, and `postedAt`, so you can read the top reactions, sort by likes to find what resonated, and see how the conversation built over time.

**How can I monitor TikTok comments across several videos at once?**
Drop a list of links into `videoUrls` and the scraper works through them one by one, tagging every row with its `videoUrl` and `videoId`. Export to CSV or Excel and you have one combined sheet of comments to filter, search, and chart however you like.

**How can I pull TikTok reply threads for community research?**
Keep `fetchReplies` on and set `repliesLimit` to the depth you need. Every comment row carries a `replyList` of the responses underneath it, so you can follow a back-and-forth, find unanswered questions, and spot the comments that sparked the most discussion.

**How can I collect TikTok comments in a specific language?**
Run the scrape, then filter the rows by `languageCode`. TikTok tags each comment with a detected language, so you can isolate, say, only the Spanish or French comments for translation, support, or regional analysis.

### Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses or private contact information. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Support

Questions, feature requests, or a field you'd like added? Reach out at <data.apify@proton.me> and we'll get back to you.

# Actor input Schema

## `videoUrls` (type: `array`):

Public TikTok post links you want comments from. Video posts, photo posts, and short vm.tiktok.com links all work — each entry is scraped on its own.

## `commentsLimit` (type: `integer`):

How many top-level comments to pull from each link. Push it up to 100000 to grab the whole thread; keep it low to trim run time and spend.

## `fetchReplies` (type: `boolean`):

Turn this on to also pull the replies nested under each comment.

## `repliesLimit` (type: `integer`):

Ceiling on how many replies to grab beneath a single comment. Only matters when Collect reply threads is switched on.

## `requestTimeoutSeconds` (type: `integer`):

Seconds to wait on each call to TikTok before giving up. Bump it up if timeout errors keep showing.

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

Pick the proxies to route requests through. Useful for sidestepping IP blocks and rate limits — datacenter is quickest, residential is the hardest to flag.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.tiktok.com/@khaby.lame/video/7137423965982997765",
    "https://www.tiktok.com/@zachking/video/7195741739927440683"
  ],
  "commentsLimit": 10,
  "fetchReplies": true,
  "repliesLimit": 10,
  "requestTimeoutSeconds": 45,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "videoUrls": [
        "https://www.tiktok.com/@hatrickr72nd/video/7651970356663667990"
    ],
    "commentsLimit": 10,
    "repliesLimit": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_api/tiktok-comments-scraper-cheap").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 = {
    "videoUrls": ["https://www.tiktok.com/@hatrickr72nd/video/7651970356663667990"],
    "commentsLimit": 10,
    "repliesLimit": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("data_api/tiktok-comments-scraper-cheap").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 '{
  "videoUrls": [
    "https://www.tiktok.com/@hatrickr72nd/video/7651970356663667990"
  ],
  "commentsLimit": 10,
  "repliesLimit": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call data_api/tiktok-comments-scraper-cheap --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data_api/tiktok-comments-scraper-cheap"
        }
    }
}

```

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/clJT2HFEme4RGBJGh/builds/I5fE4WlI86tSxCAwg/openapi.json
