To scrape TikTok comments, call the video comments endpoint with the video's link, follow its cursor to the next page until there are no more, and fetch each comment's replies the same way. This guide does all three in Python and saves the result to a CSV, with no TikTok login and no browser automation.
What you get for each comment
| Field | What it is |
|---|---|
id | The comment's id, used to fetch its replies |
text | What it says |
likes | Its likes |
reply_count | How many replies it has (null on a reply) |
created_at | When it was posted |
language | Its language, as a two-letter code |
liked_by_author | Whether the video's creator liked it |
author_handle | Its author's handle, plus author_name and author_avatar |
Set your key and base URL:
export API_KEY="your-api-key"
export API_URL="https://api.socialparse.dev"Get the first page of comments
curl -H "x-api-key: $API_KEY" "$API_URL/v1/tiktok/videos/comments?video_id=7596844935442189598"You can pass the video's link as url instead of video_id. A comment looks like this:
{
"id": "7596851467001119502",
"text": "I did my worst i'm sorry for what I have done.",
"created_at": "2026-01-18T23:44:02Z",
"likes": 48602,
"reply_count": 155,
"language": "en",
"liked_by_author": false,
"author_handle": "example.handle",
"author_name": "Example Name"
}Get every comment
When page.has_more is true, send page.next_cursor as cursor, with the same video_id. The snippets below
share this setup:
import os
import requests
API_URL = os.environ["API_URL"]
HEADERS = {"x-api-key": os.environ["API_KEY"]}def all_comments(video_id, max_pages=20):
comments = []
params = {"video_id": video_id}
for _ in range(max_pages):
body = requests.get(
f"{API_URL}/v1/tiktok/videos/comments", params=params, headers=HEADERS, timeout=120
).json()
comments.extend(body["data"]) # error handling: see the full script below
if not body["page"]["has_more"]:
break
params["cursor"] = body["page"]["next_cursor"]
return commentsmax_pages caps the cost: each page holds up to 50 comments and costs one credit, so a viral video with tens of
thousands of comments doesn't spend more than you meant to. TikTok re-ranks comments as it serves pages, so the same
comment can come twice; the full script below keeps each one once.
Get the replies
A comment's replies come from comment replies, with the comment's id and the
video's id. Only ask for the comments whose reply_count is above zero:
def all_replies(video_id, comment_id, max_pages=5):
replies = []
params = {"video_id": video_id, "comment_id": comment_id}
for _ in range(max_pages):
body = requests.get(
f"{API_URL}/v1/tiktok/videos/comments/replies", params=params, headers=HEADERS, timeout=120
).json()
replies.extend(body["data"])
if not body["page"]["has_more"]:
break
params["cursor"] = body["page"]["next_cursor"]
return repliesThe full script: comments and replies to CSV
import csv
import os
import sys
import requests
API_URL = os.environ["API_URL"]
HEADERS = {"x-api-key": os.environ["API_KEY"]}
FIELDS = ["id", "parent_id", "created_at", "likes", "reply_count", "language", "author_handle", "text"]
def pages(path, params, max_pages):
"""Every item of a paged endpoint, up to max_pages pages."""
items = []
params = dict(params)
for _ in range(max_pages):
response = requests.get(f"{API_URL}{path}", params=params, headers=HEADERS, timeout=120)
body = response.json()
if not response.ok:
print("stopped:", body["error"]["code"], body["error"]["message"], file=sys.stderr)
break
items.extend(body["data"])
if not body["page"]["has_more"]:
break
params["cursor"] = body["page"]["next_cursor"]
return items
def main(video_id):
rows = []
seen = set() # TikTok can serve a comment on two pages
comments = pages("/v1/tiktok/videos/comments", {"video_id": video_id}, max_pages=20)
for comment in comments:
if comment["id"] in seen:
continue
seen.add(comment["id"])
comment["parent_id"] = ""
rows.append(comment)
if comment["reply_count"]:
params = {"video_id": video_id, "comment_id": comment["id"]}
for reply in pages("/v1/tiktok/videos/comments/replies", params, max_pages=5):
reply["parent_id"] = comment["id"]
rows.append(reply)
with open(f"comments-{video_id}.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=FIELDS, extrasaction="ignore")
writer.writeheader()
writer.writerows(rows)
print(f"saved {len(rows)} comments and replies")
if __name__ == "__main__":
main(sys.argv[1])Run it with a video id:
python comments.py 7596844935442189598What it costs
One credit per page, errors free. A video read with 10 pages of comments, plus replies for 30 of them at one page each, costs 40 credits. New accounts get 100 free credits; see pricing for packs.
What to do with TikTok comments
- Product feedback. Read what people say under your brand's videos, and the questions they ask.
- Content research. The most-liked comments under a niche's top videos show what an audience cares about.
- Sentiment analysis. Score the comments; the Reddit sentiment guide shows how with VADER, and works on TikTok comments unchanged.
- Creator vetting. Check whether a creator's comments read like a real audience before a collaboration.
FAQ
Can I scrape comments from any TikTok video?
From any public video. An empty list means the video has no comments, or doesn't exist: check it with the
video endpoint, which answers 404 NOT_FOUND for one that was removed or made private.
Do I need a TikTok account or the Research API?
No. Social Parse reads the public comments a logged-out visitor sees. You only need an API key.
How many comments come back per page?
Up to 50 comments, and up to 50 replies. Follow next_cursor until has_more is false.
Can I get the video's stats and transcript too?
Yes: the video endpoint for views, likes and shares, and the transcript endpoint for what's said. See the TikTok scraper API guide.