The short answer
TikTok has no export for the words spoken in an account's videos. Give the account to our TikTok Transcript Scraper: it reads the account's latest videos and returns each one's transcript, from TikTok's own captions when the video has them, by AI speech-to-text when it does not. A short Python script saves a text file and an SRT file per video, with an index in CSV. The 10 latest videos of @nasa took an 83-second call and cost $0.008: 5 transcripts, all from TikTok's captions, and 5 videos without speech, free.
What the scraper reads on an account
Without signing in, TikTok publishes about the 10 latest videos of an account, pinned ones first, in the list it serves for embedding the account on other websites. That is what the scraper reads. TikTok's full list needs signed requests, which we do not make; older videos can be transcribed from their links. TikTok's own APIs do not return speech, outside its Research API for non-profit researchers (details in our guide on the TikTok transcript API).
| Setting | What it does |
|---|---|
urls | Accounts as @nasa or https://www.tiktok.com/@nasa, mixed with video links and short vm.tiktok.com links. |
maxVideosPerAccount | How many videos to take from each account, newest first: 10 by default. Photo slideshows do not count. |
useTikTokCaptions | On by default: TikTok's captions when they match the video's language, billed by transcript only. Off: every video goes through speech-to-text. |
includeSrt, includeVtt | Add the transcript as an SRT or WebVTT subtitle file to each record. |
language | A preference, never a translation: a video in another language comes back in its own, flagged. |
A text and a subtitle file per video, in Python
import csv
import pathlib
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("quarra/tiktok-transcript-scraper").call(run_input={
"urls": ["@nasa"],
"maxVideosPerAccount": 10,
"includeSrt": True,
})
folder = pathlib.Path("nasa")
folder.mkdir(exist_ok=True)
videos = list(client.dataset(run.default_dataset_id).iterate_items())
videos.sort(key=lambda v: v.get("position") or 0) # records arrive as videos finish
with open(folder / "index.csv", "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["videoId", "publishedAt", "durationSeconds", "viewCount", "language", "source", "wordCount", "status"])
for v in videos:
if v["status"] == "ok":
(folder / f"{v['videoId']}.txt").write_text(v["transcript"], encoding="utf-8")
(folder / f"{v['videoId']}.srt").write_text(v["srt"], encoding="utf-8")
w.writerow([v.get("videoId"), v.get("publishedAt"), v.get("durationSeconds"), v.get("viewCount"),
v.get("language"), v.get("transcriptSource"), v.get("wordCount"),
v.get("missingReason") or v["status"]])
print(run.status, len(videos), "videos ->", folder.resolve())
Tested with apify-client 3.3 on October 10, 2026, in an 83-second call. It wrote 5 text files, 5 SRT files and an index with these rows:
| Published | Length | Views | Words | Source |
|---|---|---|---|---|
| Oct 10, 2026 | 122 s | 18,200 | 298 | captions, automatic |
| Oct 10, 2026 | 43 s | 47,000 | 12 | captions, automatic |
| Oct 8, 2026 | 89 s | 392,900 | 259 | captions, by the creator |
| Oct 2, 2026 | 136 s | 224,000 | 368 | captions, by the creator |
| Sep 25, 2026 | 121 s | 197,000 | 326 | captions, automatic |
The other 5 came back as free no_speech records and kept their row, with no file. On four of them, plain Whisper hears nothing or “I'm out!”; the fifth holds a single line over 25 seconds. With apify-client 2.x, write run["defaultDatasetId"] instead of run.default_dataset_id.
Two columns tell you what each transcript is worth. transcriptSource says whether it comes from TikTok's captions or from speech-to-text, and each record's isAutoGenerated whether a person wrote the captions. Captions written by the creator are usually the cleanest; TikTok's automatic ones are returned as TikTok made them, mistakes included.
Keep up with an account
Schedule the Actor on Apify with the same input and keep the videos you have not seen yet: videoId is stable, so a set of the IDs already saved is enough. A video with captions costs $0.001 whatever its length, so a daily run on a busy account stays cheap.
Limits
- About 10 latest videos per account. No hashtags, sounds, search or comments.
- The no-speech check keeps a margin: a single short line over music can come back as
no_speech, free. - TikTok sometimes answers with a bot check instead of a page, about 2 pages in 100 in our tests. We never solve those checks: the page is asked again, and only then the video gets a free record marked
retryable. - Private and age-restricted videos need a signed-in account; we do not use one, so they come back as free error records.
What it costs
$1.00 per 1,000 transcripts on Apify's free plan ($0.75 on Gold and above), plus $0.001 per started minute only when a video is transcribed by AI, and a start fee of $0.003 per run at the default memory. The 10 videos of @nasa above cost $0.008: 5 transcripts from captions and the start fee. A 90-second video without captions costs $0.003. Apify's free plan includes $5 of usage a month.
Run it on the Apify Store
Transcripts cost $1.00 per 1,000 on the Free plan, plus $0.001 per started minute only when a video has no usable TikTok captions, plus $0.003 per run; videos without speech are free. Errors and empty results are not charged, and you can set a maximum cost per run.