# TikTok Comment Exporter & Scraper by Username (`thodor/tiktok-comments-scraper`) Actor

Find and export TikTok comments by username. Auto-discovers all videos from a profile and loads every comment into a spreadsheet. CSV or JSON, replies included, no limit.

- **URL**: https://apify.com/thodor/tiktok-comments-scraper.md
- **Developed by:** [Thodor](https://apify.com/thodor) (community)
- **Categories:** Social media, Automation, Videos
- **Stats:** 13 total users, 6 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 comment scrapeds

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Comment Exporter & Scraper by Username

A **TikTok comment finder tool** that works by username. Find and export TikTok comments by username, auto-discover all videos from a profile, and **load all comments into a spreadsheet**. CSV or JSON, replies included, no limit.

1. You input a profile (or direct video URLs).
2. All videos are discovered automatically.
3. Every comment and reply is extracted to your preferred format.

### How to load all TikTok comments into a spreadsheet

To load all TikTok comments into a spreadsheet with this TikTok comment exporter: run this actor with a profile username, then download the dataset as CSV or Excel from the **Storage** tab of your run. You can get TikTok comments in the following formats:

* **CSV or Excel:** Perfect for loading directly into a spreadsheet for sorting, filtering, and analysis.
* **JSON:** Ideal for developers feeding the data into other apps or databases.

### Find TikTok comments by username, not by video URL

Most TikTok comment scrapers only accept video URLs as input, meaning you need to manually find each video yourself. This **TikTok comment scraper** accepts a profile username and handles the rest. It is the easiest way to find TikTok comments by username, it discovers all videos from the profile and scrapes comments across all of them in one run.

| Feature | This actor | Typical alternatives |
|---------|-----------|---------------------|
| Input a profile username | Yes | No (video URLs only) |
| Auto-discover all videos | Yes | Manual |
| Comment limit | None | Often capped at 5,000 |
| Reply threads | Full depth | Varies |
| Image comments | Extracted | Often skipped |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `profileUrls` | string[] | `[]` | TikTok profile URLs or usernames (e.g. `@kingconnah` or `https://www.tiktok.com/@kingconnah`) |
| `videoUrls` | string[] | `[]` | Direct video URLs: combined with any videos discovered from profiles |
| `maxCommentsPerVideo` | integer | `0` (all) | Maximum comments per video. 0 = no limit |
| `includeReplies` | boolean | `false` | Fetch reply threads for each comment |

#### Scrape all comments from a profile

```json
{
    "profileUrls": ["kingconnah"],
    "includeReplies": true
}
````

#### Scrape specific videos

```json
{
    "videoUrls": [
        "https://www.tiktok.com/@username/video/7622233769231142165"
    ],
    "maxCommentsPerVideo": 1000,
    "includeReplies": true
}
```

#### Profile + extra videos

```json
{
    "profileUrls": ["kingconnah"],
    "videoUrls": [
        "https://www.tiktok.com/@other/video/7622233769231142165"
    ]
}
```

### Output

Each comment is one flat row in the dataset. Replies are separate rows linked to their parent via `parent_comment_id`.

#### Output fields

| Field | Type | Description |
|---|---|---|
| `video_url` | string | The video this comment belongs to |
| `comment_id` | string | Unique comment ID |
| `parent_comment_id` | string | Parent comment ID (empty for top-level) |
| `reply_to_reply_id` | string | ID of the specific reply being responded to within a thread |
| `depth` | integer | `0` = top-level, `1` = reply |
| `comment` | string | Comment text (empty for image-only comments) |
| `comment_image_url` | string | Image URL for image-only comments |
| `likes` | integer | Like count |
| `reply_count` | integer | Number of replies |
| `created_at` | string | ISO 8601 timestamp (UTC) |
| `author_username` | string | Commenter's @username |
| `author_display_name` | string | Commenter's display name |
| `author_id` | string | TikTok numeric user ID |
| `reply_to_username` | string | Username being replied to |
| `liked_by_video_creator` | boolean | Creator liked this comment |
| `pinned` | boolean | Creator pinned this comment |
| `purchase_intent` | boolean | TikTok's flag for buying intent (e.g. "Where can I buy this?") |
| `comment_language` | string | Language code (`"un"` = undetermined) |
| `share_url` | string | Direct share link |

#### Example output

**Top-level comment:**

```json
{
    "video_url": "https://www.tiktok.com/@txmfitt/video/7613032455011945748",
    "comment_id": "7616086972566078230",
    "parent_comment_id": "",
    "reply_to_reply_id": "",
    "depth": 0,
    "comment": "how many did you do in an hour? I once did 500",
    "comment_image_url": "",
    "likes": 62,
    "reply_count": 3,
    "created_at": "2026-03-11T19:47:22+00:00",
    "author_username": "alanas698",
    "author_display_name": "2027",
    "author_id": "6765931488842613766",
    "reply_to_username": "",
    "liked_by_video_creator": true,
    "pinned": false,
    "purchase_intent": false,
    "comment_language": "en",
    "share_url": "https://m.tiktok.com/v/7613032455011945748.html?..."
}
```

**Reply:**

```json
{
    "video_url": "https://www.tiktok.com/@txmfitt/video/7613032455011945748",
    "comment_id": "7617031854978024193",
    "parent_comment_id": "7616086972566078230",
    "reply_to_reply_id": "",
    "depth": 1,
    "comment": "i did 1,017",
    "comment_image_url": "",
    "likes": 45,
    "reply_count": 0,
    "created_at": "2026-03-14T08:54:01+00:00",
    "author_username": "txmfitt",
    "author_display_name": "Toby",
    "author_id": "7193948041925403654",
    "reply_to_username": "",
    "liked_by_video_creator": false,
    "pinned": false,
    "purchase_intent": false,
    "comment_language": "en",
    "share_url": ""
}
```

**Image-only comment:**

```json
{
    "video_url": "https://www.tiktok.com/@txmfitt/video/7613032455011945748",
    "comment_id": "7615909607940588310",
    "parent_comment_id": "7614996613496390408",
    "reply_to_reply_id": "",
    "depth": 1,
    "comment": "",
    "comment_image_url": "https://p16-comment-sign-no.tiktokcdn-eu.com/tos-no1a-i-jj85edgx6n-no/b5efb28ad8934663aa1831ef422142d7~tplv-jj85edgx6n-image-origin.image?...",
    "likes": 4,
    "reply_count": 0,
    "created_at": "2026-03-11T08:19:24+00:00",
    "author_username": "unicukornis",
    "author_display_name": "Unicukornis",
    "author_id": "6845319934780654598",
    "reply_to_username": "",
    "liked_by_video_creator": false,
    "pinned": false,
    "purchase_intent": false,
    "comment_language": "un",
    "share_url": "https://m.tiktok.com/v/7613032455011945748.html?..."
}
```

#### Understanding threading

For most use cases, `parent_comment_id` + `depth` is all you need:

- **Top-level comments:** `depth == 0`
- **Find replies:** filter by `parent_comment_id`
- **Full threads:** group by `parent_comment_id`, sort by `created_at`

The `reply_to_reply_id` field shows which specific reply within a thread someone responded to, which is useful for conversation analysis.

### FAQ

**How do I search and view TikTok comments from a profile?**
Run this actor with a username to view all TikTok comments from every video on the profile in one dataset. Once exported to CSV or Excel, you can search TikTok comments by author, keyword, date, or engagement using your spreadsheet's filter and search tools.

**Can I export TikTok comments to CSV?**
Yes. After the actor finishes, open the **Storage** tab of your run and download the dataset as CSV. Excel (XLSX), JSON, JSONL, XML, and HTML are also available from the same page or via the Apify API.

**Can I use this as a TikTok comment tracker?**
Yes. Because you can input a specific username, you can schedule this actor to run daily or weekly to monitor new comments and engagement on a specific profile. It functions as a reliable **TikTok comment tracker**.

**How does the comment limit work with replies enabled?**
When `includeReplies` is on, both comments and replies count toward `maxCommentsPerVideo`. The actor processes comments page by page. For each page, it first extracts the top-level comments, then fetches their replies before moving to the next page. This means the final output is a mix of comments and replies. If you need all top-level comments first, run once without replies, then run again with replies enabled.

**What happens if a proxy gets blocked?**
The actor automatically retries with a fresh proxy. You will see a "rotating proxy" warning in the logs but scraping continues from where it left off. No data is lost.

**Are there duplicate comments in the output?**
No. Every comment and reply is deduplicated by ID before being added to the dataset. You only pay for unique results.

**Can I find TikTok comments by username free?**
Yes. When you sign up for Apify, you automatically get free monthly usage credits on their free tier. You can use these platform credits to run this actor and extract comments completely free of charge. No credit card is required to start.

# Actor input Schema

## `profileUrls` (type: `array`):

Profile URLs or usernames (e.g. https://www.tiktok.com/@username or just 'username'). All videos from each profile will be discovered first, then comments scraped.

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

Direct video URLs to extract comments from. Combined with any videos discovered from profiles.

## `maxCommentsPerVideo` (type: `integer`):

Maximum number of comments to extract per video. Set to 0 for all comments.

## `includeReplies` (type: `boolean`):

Whether to fetch reply threads for each comment.

## Actor input object example

```json
{
  "profileUrls": [],
  "videoUrls": [
    "https://www.tiktok.com/@ishowspeed/video/7621300668329905422"
  ],
  "maxCommentsPerVideo": 500,
  "includeReplies": false
}
```

# Actor output Schema

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

No description

# 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 = {
    "profileUrls": [],
    "videoUrls": [
        "https://www.tiktok.com/@ishowspeed/video/7621300668329905422"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thodor/tiktok-comments-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 = {
    "profileUrls": [],
    "videoUrls": ["https://www.tiktok.com/@ishowspeed/video/7621300668329905422"],
}

# Run the Actor and wait for it to finish
run = client.actor("thodor/tiktok-comments-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 '{
  "profileUrls": [],
  "videoUrls": [
    "https://www.tiktok.com/@ishowspeed/video/7621300668329905422"
  ]
}' |
apify call thodor/tiktok-comments-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Comment Exporter & Scraper by Username",
        "description": "Find and export TikTok comments by username. Auto-discovers all videos from a profile and loads every comment into a spreadsheet. CSV or JSON, replies included, no limit.",
        "version": "0.6",
        "x-build-id": "PdTJjiFwVvU6wKEjf"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/thodor~tiktok-comments-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-thodor-tiktok-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/thodor~tiktok-comments-scraper/runs": {
            "post": {
                "operationId": "runs-sync-thodor-tiktok-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/thodor~tiktok-comments-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-thodor-tiktok-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "profileUrls": {
                        "title": "TikTok Profile URLs",
                        "type": "array",
                        "description": "Profile URLs or usernames (e.g. https://www.tiktok.com/@username or just 'username'). All videos from each profile will be discovered first, then comments scraped.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "videoUrls": {
                        "title": "TikTok Video URLs",
                        "type": "array",
                        "description": "Direct video URLs to extract comments from. Combined with any videos discovered from profiles.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxCommentsPerVideo": {
                        "title": "Max comments per video",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of comments to extract per video. Set to 0 for all comments.",
                        "default": 500
                    },
                    "includeReplies": {
                        "title": "Include replies",
                        "type": "boolean",
                        "description": "Whether to fetch reply threads for each comment.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
