TikTok Comments Scraper
Pricing
$0.25 / 1,000 comments
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
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: trueand billed. Reply rows carryrepliesToId, thecidof the comment they answer - 1
success: falserow,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: falserecord with a machine-readablecode(TIKTOK_VIDEO_UNAVAILABLE,TIKTOK_NO_COMMENTS,VALIDATION_FAILED,TIKTOK_TIMEOUT, ...). Branch oncodewithout 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}
| Field | Type | Default | What it does |
|---|---|---|---|
postURLs | array of strings | TikTok 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. | |
commentsPerPost | integer, 1-10,000 | 100 | Maximum top-level comments per video. Replies do not count toward it. |
maxRepliesPerComment | integer, 0-1,000 | 0 | Maximum 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:
| Field | Type | What it is |
|---|---|---|
success | boolean | true for a comment (billed), false for a video that could not be read (not billed). |
cid | string | The comment's unique ID. |
text | string | The comment body. |
diggCount | integer | Likes on the comment. |
replyCommentTotal | integer | Number of replies TikTok reports for the comment. |
createTimeISO | string | When the comment was posted, ISO 8601 UTC. |
uniqueId | string | The author's TikTok handle. |
uid | string | The author's numeric user ID. |
avatarThumbnail | string or null | The author's avatar URL, null when TikTok does not return one. |
videoWebUrl | string | The canonical URL of the video the comment belongs to. |
repliesToId | string or null | On 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:
| Code | Meaning |
|---|---|
TIKTOK_VIDEO_UNAVAILABLE | The video is deleted, private, or otherwise unavailable. |
TIKTOK_NO_COMMENTS | TikTok reports the video has no comments. |
TIKTOK_UNAVAILABLE | TikTok did not serve the comments for this video. |
TIKTOK_BLOCKED | TikTok refused the request after an automatic retry. |
TIKTOK_RATE_LIMITED | TikTok rate-limited the request after an automatic retry. |
TIKTOK_TIMEOUT | TikTok did not answer in time after an automatic retry. |
DEADLINE_EXCEEDED | The page request hit its 30-second deadline. |
VALIDATION_FAILED | The URL is not a supported TikTok video URL (including short links). |
NO_INPUT | No 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 freesuccess: falserow withcode: VALIDATION_FAILED. Open the short link in a browser and paste the fullhttps://www.tiktok.com/@user/video/<id>URL instead. - Replies are opt-in. By default it returns top-level comments only. Set
maxRepliesPerCommentabove0to 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.
replyCommentTotalis 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
- Open the Actor in the Apify Console.
- Paste one or more TikTok video URLs into
postURLs. Up to 50 unique videos run per job. - Set
commentsPerPostto cap top-level comments per video, andmaxRepliesPerCommentif you want replies. - Click Start. Each comment is one
success: truerecord. Videos that cannot be read produce onesuccess: falserecord 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.