TikTok Comments Scraper avatar

TikTok Comments Scraper

Pricing

$0.25 / 1,000 comments

Go to Apify Store
TikTok Comments Scraper

TikTok Comments Scraper

Export TikTok comments and replies to JSON by video URL. Deleted or unavailable videos return success:false, cost $0, and never break the batch. One record per comment with author, likes, replies, and timestamp. $0.25 per 1,000 comments.

Pricing

$0.25 / 1,000 comments

Rating

0.0

(0)

Developer

apihq dev

apihq dev

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Export the public comments and replies of TikTok videos as clean JSON from their video URLs. No TikTok account, no API key, no browser.

The contract is simple: a deleted or unavailable video never fails your run, and you only pay for comments delivered. Paste a removed video or a bad URL, and it comes back as a success: false row while the rest of the batch keeps going. Pay-per-result at $0.25 per 1,000 comments. Failed videos cost $0.

See one run

Input:

{
"postURLs": [
"https://www.tiktok.com/@scout2015/video/6718335390845095173",
"https://www.tiktok.com/@scout2015/video/7000000000000000001"
],
"commentsPerPost": 30,
"maxRepliesPerComment": 2
}

What came back:

  • 30 top-level comments from the good video, plus up to 2 replies under each (49 replies), all success: true and billed. Reply rows carry repliesToId, the cid of the comment they answer
  • 1 success: false row, code: TIKTOK_VIDEO_UNAVAILABLE, for the missing video, not billed
  • Run status: SUCCEEDED
  • Charged: 79 comments = $0.01975

postURLs alone works too. commentsPerPost defaults to 100 and replies are off by default. Good input returns billed rows, bad input returns free error rows in the same dataset, and the run still succeeds, so one bad video never costs you a batch.

Why this Actor

  • A bad video never breaks the batch. A deleted, private, or unreachable video returns a success: false record with a machine-readable code (TIKTOK_VIDEO_UNAVAILABLE, TIKTOK_NO_COMMENTS, VALIDATION_FAILED, TIKTOK_TIMEOUT, ...). Branch on code without parsing English.
  • You pay only for comments. Billing fires on an explicit per-comment event, not on dataset writes, so failure rows sit in your dataset for free. There is no per-run start fee, so a run that returns zero comments costs zero.
  • Drop-in field names. Rows use the field names most TikTok scrapers already use (cid, text, diggCount, replyCommentTotal, createTimeISO, uniqueId, uid, avatarThumbnail, videoWebUrl), so an existing pipeline can switch without a remap.

Best for

Data and AI workflows that turn TikTok discussion into text: sentiment and brand monitoring, influencer and campaign research, audience and product-feedback analysis, moderation review, and building comment datasets for LLM pipelines. The failure-free billing and machine-readable error rows matter most when the extraction runs unattended inside a larger pipeline, where one deleted video should never take down the batch. It works fine for one-off manual pulls too.

Input example

A single video, top-level comments only:

{
"postURLs": ["https://www.tiktok.com/@scout2015/video/6718335390845095173"],
"commentsPerPost": 200
}

A batch of videos, with replies:

{
"postURLs": [
"https://www.tiktok.com/@scout2015/video/6718335390845095173",
"https://www.tiktok.com/@khaby.lame/video/7675410938970901791",
"https://www.tiktok.com/@looooooooch/video/7332342275151760642"
],
"commentsPerPost": 500,
"maxRepliesPerComment": 10
}

A quick sample across many videos (the first 20 comments of each, cheap to run):

{
"postURLs": [
"https://www.tiktok.com/@scout2015/video/6718335390845095173",
"https://www.tiktok.com/@khaby.lame/video/7675410938970901791"
],
"commentsPerPost": 20
}
FieldTypeDefaultWhat it does
postURLsarray of stringsTikTok video URLs, up to 50 unique videos per run. Copies of the same video (with www., m., a query string, or a trailing slash) are run once.
commentsPerPostinteger, 1-10,000100Maximum top-level comments per video. Replies do not count toward it.
maxRepliesPerCommentinteger, 0-1,0000Maximum replies fetched under each top-level comment. 0 skips replies.

Out-of-range numbers are clamped to the nearest allowed value, with a note in the run log.

Output example

One record per comment or reply. The video's canonical URL is copied onto every row so each row stands alone:

{
"success": true,
"cid": "7642984713451356950",
"text": "this never gets old",
"diggCount": 3,
"replyCommentTotal": 2,
"createTimeISO": "2026-05-20T10:11:12.000Z",
"uniqueId": "somehandle",
"uid": "7608207343391097878",
"avatarThumbnail": "https://p16-common-sign.tiktokcdn.com/...",
"videoWebUrl": "https://www.tiktok.com/@scout2015/video/6718335390845095173",
"repliesToId": null
}

A video that cannot be read lands in the same dataset and is not charged:

{
"success": false,
"postURL": "https://www.tiktok.com/@scout2015/video/7000000000000000001",
"code": "TIKTOK_VIDEO_UNAVAILABLE",
"error": "TikTok reports this video does not exist or is not available",
"requestId": "req_c5d69ba0387c4b2ab600df56",
"statusCode": 422,
"commentsDelivered": 0
}

Split hits from misses on the success field. Quote requestId in any support issue and we can trace the exact request.

What you get

Every comment or reply is one record with success: true:

FieldTypeWhat it is
successbooleantrue for a comment (billed), false for a video that could not be read (not billed).
cidstringThe comment's unique ID.
textstringThe comment body.
diggCountintegerLikes on the comment.
replyCommentTotalintegerNumber of replies TikTok reports for the comment.
createTimeISOstringWhen the comment was posted, ISO 8601 UTC.
uniqueIdstringThe author's TikTok handle.
uidstringThe author's numeric user ID.
avatarThumbnailstring or nullThe author's avatar URL, null when TikTok does not return one.
videoWebUrlstringThe canonical URL of the video the comment belongs to.
repliesToIdstring or nullOn a reply: the cid of the comment it answers. null on a top-level comment.

IDs are strings because TikTok's 19-digit IDs do not fit in a JavaScript number.

Videos that could not be read carry success: false, postURL, a machine-readable code, a human-readable error, the service requestId, the HTTP statusCode, and commentsDelivered (rows already delivered for that video before it stopped). They are not charged:

CodeMeaning
TIKTOK_VIDEO_UNAVAILABLEThe video is deleted, private, or otherwise unavailable.
TIKTOK_NO_COMMENTSTikTok reports the video has no comments.
TIKTOK_UNAVAILABLETikTok did not serve the comments for this video.
TIKTOK_BLOCKEDTikTok refused the request after an automatic retry.
TIKTOK_RATE_LIMITEDTikTok rate-limited the request after an automatic retry.
TIKTOK_TIMEOUTTikTok did not answer in time after an automatic retry.
DEADLINE_EXCEEDEDThe page request hit its 30-second deadline.
VALIDATION_FAILEDThe URL is not a supported TikTok video URL (including short links).
NO_INPUTNo usable postURLs were given. The run ends successfully with this single row.

Pricing

Pay-per-result. One charge per comment delivered: $0.00025 each, which is $0.25 per 1,000 comments. Replies bill at the same per-comment rate. The charge fires only after a comment row lands in your dataset.

  • 1,000 delivered comments cost $0.25.
  • 10,000 delivered comments cost $2.50.
  • A run that hits only deleted or unavailable videos costs $0.
  • There is no per-run start fee, so an empty run is genuinely free.

Platform compute is included in the per-comment price. Cap the maximum spend of a single run from Apify's Run Limits panel; the Actor honors the cap and stops cleanly when the budget runs out.

What this Actor does not do

Honest scope, so you know before you run it:

  • Video URLs only. It reads the comments of the videos you give it. It does not find videos from a profile, hashtag, sound, or search query.
  • Full video URLs only. Short share links (vm.tiktok.com/..., vt.tiktok.com/...) come back as a free success: false row with code: VALIDATION_FAILED. Open the short link in a browser and paste the full https://www.tiktok.com/@user/video/<id> URL instead.
  • Replies are opt-in. By default it returns top-level comments only. Set maxRepliesPerComment above 0 to also fetch replies; they add extra requests.
  • Public comments as TikTok serves them. TikTok may hide, filter, or reorder comments, so the number of rows can be lower than the comment or reply counts shown in the app. replyCommentTotal is TikTok's number, not a promise of how many reply rows you get.
  • No login-only content. Private videos and anything that needs a TikTok account return success: false. It does not download videos, images, or audio.

How to use this Actor

  1. Open the Actor in the Apify Console.
  2. Paste one or more TikTok video URLs into postURLs. Up to 50 unique videos run per job.
  3. Set commentsPerPost to cap top-level comments per video, and maxRepliesPerComment if you want replies.
  4. Click Start. Each comment is one success: true record. Videos that cannot be read produce one success: false record and do not stop the run. Only comments are charged.

The Actor is also callable from the Apify API and every official integration (Make, Zapier, n8n, Slack, webhooks). The API tab in the Console has ready-to-paste JavaScript, Python, and curl snippets.

Reliability

A bad video never fails the batch. A deleted video, a bad URL, or a video TikTok will not serve becomes a success: false record with a specific code. The run keeps going and finishes successfully.

You never pay for a failure. Billing fires on an explicit per-comment charge event, not on dataset writes, so success: false records are free. There is no per-run start fee either.

Automatic retry, then a clear answer. A blocked, rate-limited, or slow request is retried automatically once before the video is reported as failed. Each page request runs under a 30-second deadline, so a stalled page returns a success: false record with code: DEADLINE_EXCEEDED instead of hanging your run.

No duplicate charges. A comment TikTok repeats across pages is delivered and charged once per run, even when the same video appears several times in your input.

Genuine faults are not hidden. An outage of our backend, an unexpected response, or a failure to write or bill results fails the run, so a broken run never looks like a clean one with missing data.

FAQ

Do I need a TikTok account or API key?

No. The Actor reads public comments directly. There is nothing to log into and no TikTok developer key to provision. (You run it with your normal Apify account, like any Actor.)

What URL formats are accepted?

Full TikTok video URLs: https://www.tiktok.com/@user/video/<id>, also with m.tiktok.com, without www., with a query string, or with a trailing slash. Short links (vm.tiktok.com, vt.tiktok.com) are not supported yet and return a free success: false row with code: VALIDATION_FAILED.

How do I get replies?

Set maxRepliesPerComment to the number of replies you want under each top-level comment. Reply rows carry repliesToId, the cid of the parent comment, so you can rebuild threads.

Why do I get fewer comments than the app shows?

The count in the app includes comments TikTok later hides, filters, or only shows to some viewers. The Actor returns the public comments TikTok serves at run time, and the comment count is TikTok's own number.

Is the output compatible with other TikTok comment scrapers?

Yes for the common fields: cid, text, diggCount, replyCommentTotal, createTimeISO, uniqueId, uid, avatarThumbnail, videoWebUrl, and repliesToId use the field names most TikTok scrapers already use.

Can I get all comments from a profile or a hashtag?

Not with this Actor. It reads the comments of the video URLs you give it. Collect the video URLs first, then pass them in postURLs.

How much does it cost?

$0.25 per 1,000 comments, replies included. 10,000 comments cost $2.50. Failed videos and empty runs cost $0, and there is no start fee.

What if a video was deleted or is private?

It comes back as a success: false record with code: TIKTOK_VIDEO_UNAVAILABLE. You are not charged, and the other videos in the batch keep running.

Can I also get YouTube comments?

Yes, with the sibling Actor YouTube Comments Scraper, which uses the same failure-free billing.

Can I use this Actor from my own code?

Yes. Use the Apify API or one of the official SDKs (Node.js: apify-client, Python: apify-client). The Console shows ready-to-paste code samples on the API tab.

Found a bug or want a feature?

Open an issue on this Actor's Issues tab and include the requestId from any error record you saw. We respond within one business day.