# TikTok Comments Scraper — Comments & Replies, No Cookies (`meka.im/tiktok-comments-scraper`) Actor

TikTok comments scraper/API for video URLs and profiles. Export public comments and replies without login or cookies. From $0.20/1,000 delivered rows; Free $0.24/1,000.

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

## Pricing

from $0.20 / 1,000 delivered comment or replies

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

Use this **TikTok comments scraper and API** to collect public comments and replies from full video URLs or profile usernames. Export comment text, likes, dates, public author fields and reply IDs to **JSON, CSV or Excel**. No TikTok login or cookies are needed. Result pricing starts at **$0.20 per 1,000 delivered comments or replies**; **Free is $0.24 per 1,000 delivered comments or replies**, Starter $0.23/1,000 and Scale $0.22/1,000. Apify platform usage is included in the published customer pricing.

- **Collect replies deliberately:** separate total, top-level and per-parent reply caps; main comments are collected first.
- **Discover profile videos:** choose latest, popular or oldest videos, public reposts, publication dates and pinned-post exclusion.
- **Pay for delivered rows:** invalid inputs, duplicates and undelivered failures have no result charge. No startup or automatic Dataset result-event fee.
- **Inspect completion:** verified partial results remain available; the run summary explains source failures and budget stops.

### Quick start: scrape TikTok comments and replies

1. Paste full public video URLs into **TikTok video URLs**.
2. Set the total, top-level and reply limits, then start the run in Apify.
3. Open the **Comments and replies** Dataset view and export JSON, CSV or Excel.

This example requests up to 20 comments and replies from one public Nike video:

```json
{
  "postURLs": ["https://www.tiktok.com/@nike/video/7693986066830839054"],
  "commentsPerPost": 20,
  "topLevelCommentsPerPost": 10,
  "maxRepliesPerComment": 5,
  "maxConcurrency": 1
}
```

Defaults are 100 total comments and replies, 100 top-level comments and **zero replies**. Set `maxRepliesPerComment` above zero and set the top-level cap below the total cap to leave room for replies. Every reply counts toward the total. Caps are ceilings, not promised quantities.

#### Scrape comments from a TikTok profile

Enter usernames in **Profile usernames**, separately from video URLs. This example discovers up to two recent videos from Nike and collects a bounded discussion from each:

```json
{
  "profiles": ["nike"],
  "resultsPerPage": 2,
  "profileSorting": "latest",
  "profileScrapeSections": ["videos"],
  "commentsPerPost": 20,
  "topLevelCommentsPerPost": 10,
  "maxRepliesPerComment": 5,
  "maxConcurrency": 1
}
```

Profiles accept an optional `@`. You can combine up to 100 video URLs and 100 profiles. Videos discovered from profiles use their actual video URL in the Dataset's `input` and `submittedVideoUrl`. Photos are skipped and reported. Explicit video targets are excluded from profile discovery; overlapping rows are deduplicated before delivery and charging.

#### Ready-made samples and recurring exports

Start with the [small top-level comment sample](https://apify.com/meka.im/tiktok-comments-scraper/examples/sample-public-tiktok-comments) or the [comments and replies sample](https://apify.com/meka.im/tiktok-comments-scraper/examples/sample-tiktok-comments-and-replies), then replace the example URL. Save your input as an Apify task and schedule fresh samples for audience research, campaign feedback or spreadsheet review. Each run is a separate snapshot; scheduling does not automatically track deleted or edited comments.

### Input reference

| Input | Default | Meaning |
| --- | --- | --- |
| `postURLs` | `[]` | Up to 100 full HTTPS TikTok video URLs. |
| `profiles` | `[]` | Up to 100 usernames, with optional `@`. |
| `commentsPerPost` | 100 | Total unique comments plus replies per video, 1–10,000. |
| `topLevelCommentsPerPost` | 100 | Top-level comments per video, 1–10,000. |
| `maxRepliesPerComment` | 0 | Replies per parent, 0–500. Zero disables replies. |
| `resultsPerPage` | 1 | Discovered posts per profile, 1–100; applies across selected sections. |
| `profileSorting` | `latest` | Native video order: latest, popular or oldest. Reposts retain source order. |
| `profileScrapeSections` | `["videos"]` | Videos, public reposts or both, in selection order. |
| `oldestPostDateUnified` | None | Inclusive UTC publication day `YYYY-MM-DD` or days back `1`–`36500`; `1` means today, `2` yesterday. |
| `newestPostDate` | None | Inclusive UTC publication day `YYYY-MM-DD`. |
| `excludePinnedPosts` | false | Exclude pinned profile videos; does not filter comments. |
| `maxConcurrency` | 16 | Process 1–16 video/profile units at once; each profile handles its videos sequentially. |

Direct inputs require `https://www.tiktok.com/@username/video/ID` or the equivalent `https://tiktok.com` form. Short links, query strings, fragments and profile URLs in `postURLs` are unsupported. Invalid URLs are skipped independently. Repeated video IDs retain the first valid occurrence. Empty API input `{}` returns zero rows and zero result charges; no paid example is inserted by default.

Date filters apply to profile discovery before comments are collected. Relative days freeze at each profile's first request and survive continuation; profiles starting across UTC midnight can use different date bases. Pin exclusion uses verified profile pin metadata and fails closed for conflicting or malformed flags. See [native discovery evidence and limits](https://github.com/jiangzhongbo/anyfetch/blob/main/docs/tiktok-comments-native-capabilities.md).

Rows within a video follow source traversal order. Concurrent targets can arrive in completion order; use `maxConcurrency: 1` when direct-video input order matters. There is no custom comment sorting, keyword filtering or media download.

### Output: comment text, likes, dates and reply IDs

Each Dataset row is one verified comment or reply. The published fields include `cid`, `text`, `createTime` (Unix seconds), `createTimeISO`, `diggCount` (likes), `replyCommentTotal`, `uid`, `uniqueId`, `avatarThumbnail`, `likedByAuthor`, `pinnedByAuthor`, `mentions`, `detailedMentions`, `repliesToId`, `videoWebUrl`, `submittedVideoUrl` and `input`. The additional `_anyfetch` object contains recovery identity, not cookies or credentials.

`repliesToId` is null for top-level comments. For replies it identifies the directed reply target when available, otherwise the parent; the referenced row can fall outside your sample. Missing values remain null. Pins and mentions reflect verified metadata, with no text-based mention inference; see [verified mention limits](https://github.com/jiangzhongbo/anyfetch/blob/main/docs/tiktok-mentions-evidence.md). Avatar URLs can expire.

#### Representative output

The following is a **field selection from actual public results captured on October 11, 2026**, using the same URL and limits as Quick start. It illustrates one comment and one reply; it is not a promised result for a future run.

```json
[
  {
    "cid": "7694035405498286869",
    "text": "Chicago and Dream being the assistants and the cashiers I’m crying",
    "createTimeISO": "2026-10-07T21:07:14.000Z",
    "diggCount": 5062,
    "replyCommentTotal": 2,
    "repliesToId": null,
    "videoWebUrl": "https://www.tiktok.com/@nike/video/7693986066830839054"
  },
  {
    "cid": "7694171768512348959",
    "text": "And they’re scanning a million things 😂😂",
    "createTimeISO": "2026-10-08T05:57:14.000Z",
    "diggCount": 57,
    "replyCommentTotal": null,
    "repliesToId": "7694035405498286869",
    "videoWebUrl": "https://www.tiktok.com/@nike/video/7693986066830839054"
  }
]
```

The default Dataset view highlights text, likes, reported replies, dates, reply IDs and video links. Open all fields for the full record. `OUTPUT` reports delivered and charged counts, skipped/duplicate inputs, source errors and budget completion. No result cache is used. See [current field comparison](https://github.com/jiangzhongbo/anyfetch/blob/main/docs/tiktok-comments-current-parity.md) for the verified compatibility boundary.

### Pricing

One `comment-delivered` event is one unique comment or reply successfully committed to the Dataset. Verified partial results incur only delivered-row result charges; invalid inputs, duplicates and undelivered failures have none.

| Apify tier | Per 1,000 delivered comments or replies |
| --- | ---: |
| Free | $0.24 |
| Starter | $0.23 |
| Scale | $0.22 |
| Business and higher | $0.20 |

On Free, 20 delivered rows cost $0.0048; 100 cost $0.024; 1,000 cost $0.24 in result-event charges. Comments and replies have the same price. **Apify platform usage is included** in the published customer pricing. Owner-run resource usage is tracked separately from customer event pricing; benchmark owner costs are not customer invoices.

Set a maximum total charge in Apify to bound spending. Delivery stops when the remaining budget cannot cover the next result. A budget-limited run can appear ABORTED; check `OUTPUT.stopReason: "budget"` and the retained Dataset. A Dataset write followed by a billing failure can leave a delivered row uncharged; recovery does not back-charge earlier committed rows.

### Measured comparison with Clockworks

On October 13, 2026, we ran this Actor and Clockworks TikTok Comments Scraper once against the same 16 public video URLs. Both received the same per-video limits: 20 total comments and replies, 10 top-level comments and up to 5 replies per parent. Failed targets were retained in the comparison rather than replaced.

| Observed result | This Actor | Clockworks |
| --- | ---: | ---: |
| Published build | 1.0.12 | 0.0.470 |
| Memory used for the run | 256 MB | 1,024 MB (its published minimum) |
| Concurrency setting | 16 | Not exposed |
| Whole-run elapsed time | **16.606 s** | **112.257 s** |
| Valid unique rows | **200** | **128**, plus 1 error row |
| Top-level comments / replies | **120 / 80** | **121 / 7** |
| Videos with at least one row | **15/16 (93.75%)** | **15/16 (93.75%)** |
| Confirmed completed targets | **14/16** | Unknown; no equivalent run summary was available |
| Peak Actor memory | 53.52 MiB | 359.67 MiB |
| Observed result-event charge | $0.038 | $0.129, including the error row |

This Actor finished the batch about **6.76 times sooner** in this run and returned substantially more replies. This was not a same-memory benchmark: Clockworks required at least 1,024 MB, and its internal concurrency was not observable. Benchmark resource usage is tracked separately from customer event pricing; owner-run charges are not customer invoices. One convenient 16-video batch does not establish sustained 16 QPS, future availability or an all-video accuracy rate.

The two Datasets shared 92 comment IDs. For those shared rows, comment text, timestamps, public author ID and handle, reply target, input and video URL matched. Some live counts, avatar URLs, pin values and mention metadata differed; overlap and field agreement are not proof that either Dataset was complete. One Bella Poarch target returned no comments on either side (`source_schema_failure` here and `POST_NOT_FOUND_OR_PRIVATE` on Clockworks). One MrBeast target retained 11 rows here but ended with `source_cursor_stalled`. This is why a platform status of SUCCEEDED and “video has data” must not be read as “every requested target completed.”

See the [full sanitized methodology, per-video results and field comparison](https://github.com/jiangzhongbo/anyfetch/blob/main/validation/tiktok-comments-256-pair-2026-10-13/README.md), or inspect the official [Meka run](https://console.apify.com/actors/0rontmrJfDm61hhvI/runs/l6q4A10JKceB1qJUM) and [Clockworks run](https://console.apify.com/actors/BDec00yAmCm1QbMEI/runs/ZctH2gIIj0pNrjYlV).

### Reliability and coverage limits

A removed, restricted, blocked or unavailable video can fail. Generic transport or source errors do not prove a video is deleted or private. Confirmed empty pages can complete normally with zero rows; uncertain empty source responses are reported as errors. Requested limits and live reply counts do not guarantee a complete conversation.

**SUCCEEDED means the Actor finished, not that every target completed.** Check `OUTPUT.completed`, `partial`, `errors`, `completedTargets` and `failedTargets`. Targets count requested video/profile units; `videoCounts` reports profile-discovered video outcomes separately. Failed videos and discovery sections are isolated so other confirmed videos can continue, while `partial` remains true. Verified rows remain in the Dataset. If every target fails technically with no retained results, the run is FAILED; fatal authentication or contract errors also fail the run.

Source limits can stop large collections early. Same-run recovery is best effort within the source session's 15-minute validity. Interrupting an in-flight request can leave an unknown outcome that cannot safely be replayed. Export retained rows and inspect the summary; a new run may deliver previous comments again. [Compatibility and recovery reference](https://github.com/jiangzhongbo/anyfetch/blob/main/docs/tiktok-comments-store-contracts.md) covers saved inputs, checkpoints, retries and dated acceptance tests.

### API and automation

Use the Apify **API** tab for generated request and authentication examples, with the same JSON input shown above. Save tasks for recurring runs, use schedules, and connect webhooks or Apify integrations to completed Datasets. Apify's MCP server can expose available Actor tools to an agent. No TikTok login or cookies are required.

### FAQ and troubleshooting

**Can I scrape a profile or short URL?** Use usernames in `profiles`. Short URLs are unsupported; direct videos require full `@username/video/ID` URLs.

**Why are no replies returned?** The default reply limit is zero. Set `maxRepliesPerComment` above zero and leave room under the total cap after top-level comments; the source can still return fewer replies.

**Why are there fewer rows than requested?** Caps limit delivery. Public availability and source or budget limits can reduce results. Check `OUTPUT` for the reason.

**Why did a successful run return partial results?** One or more targets did not finish. Check `OUTPUT.completed`, `partial` and `errors`. Verified rows remain available and are the only billable results; fatal configuration or contract errors can still fail a run after delivery.

**Are replies priced separately?** No. A delivered reply has the same event price as a top-level comment. Platform usage is included in the published customer pricing.

**Can I keep using a saved task?** Current tasks use the latest Actor semantics. The former fixed `apiVersion: 2` remains accepted for old saved inputs; remove it when editing. Legacy v1 checkpoints require their original build. See the [compatibility reference](https://github.com/jiangzhongbo/anyfetch/blob/main/docs/tiktok-comments-store-contracts.md).

**How do I report a problem?** Open an issue on this Actor's Apify page with the run ID and a safe description. Do not post tokens, cookies or credentials.

Use public data responsibly and follow applicable law and platform rules. This Actor is independently developed and is not affiliated with or endorsed by TikTok or Nike. Names describe the source and public example.

# Actor input Schema

## `postURLs` (type: `array`):

Up to 100 full public TikTok video URLs. Use Profile usernames below for profiles; invalid video URLs are skipped independently.

## `commentsPerPost` (type: `integer`):

Maximum total delivered comments and replies for each video.

## `topLevelCommentsPerPost` (type: `integer`):

Maximum top-level comments collected for each video.

## `maxRepliesPerComment` (type: `integer`):

Per-parent reply upper bound, default 0. Delivers main comments first; explicitly set this to collect replies.

## `profiles` (type: `array`):

Up to 100 usernames, optional @. Videos and public reposts supported.

## `resultsPerPage` (type: `integer`):

Default 1. Upper bound on discovered posts per profile, not comment rows.

## `profileSorting` (type: `string`):

Default latest. Native video discovery order: latest, popular or oldest. Reposts retain upstream repost order.

## `profileScrapeSections` (type: `array`):

Default \[videos]. Select videos, reposts or both. Each section uses native upstream pagination; profileSorting applies to videos. resultsPerPage caps unique posts across selected sections.

## `oldestPostDateUnified` (type: `string`):

Inclusive UTC publication lower bound: valid YYYY-MM-DD or integer string 1..36500 (1=today, 2=yesterday). Relative days freeze at each profile unit first request, before discovery.

## `newestPostDate` (type: `string`):

YYYY-MM-DD UTC video publication date; inclusive calendar day. Applies to profile discovery before comment collection.

## `excludePinnedPosts` (type: `boolean`):

Default false. Profile discovery only.

## `maxConcurrency` (type: `integer`):

Process 1–16 video or profile targets at once. Each profile processes its videos sequentially. Output can arrive in completion order; this is not a requests-per-second setting.

## Actor input object example

```json
{
  "postURLs": [
    "https://www.tiktok.com/@nike/video/7693986066830839054"
  ],
  "commentsPerPost": 100,
  "topLevelCommentsPerPost": 100,
  "maxRepliesPerComment": 0,
  "profiles": [],
  "resultsPerPage": 1,
  "profileSorting": "latest",
  "profileScrapeSections": [
    "videos"
  ],
  "excludePinnedPosts": false,
  "maxConcurrency": 16
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "postURLs": [
        "https://www.tiktok.com/@nike/video/7693986066830839054"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("meka.im/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 = { "postURLs": ["https://www.tiktok.com/@nike/video/7693986066830839054"] }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,meka.im/tiktok-comments-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/0rontmrJfDm61hhvI/builds/BtCUeswVSiUodpx2g/openapi.json
