TikTok Transcript Scraper - Spoken Text, SRT and WebVTT avatar

TikTok Transcript Scraper - Spoken Text, SRT and WebVTT

Pricing

from $0.38 / 1,000 transcripts

Go to Apify Store
TikTok Transcript Scraper - Spoken Text, SRT and WebVTT

TikTok Transcript Scraper - Spoken Text, SRT and WebVTT

Get the spoken text from TikTok videos: send links, get the full transcript, timed segments, SRT and WebVTT files and the track's language, plus the video id, author, caption and play count. A video with no caption track has nothing to read and is not charged. $0.40 per 1,000 transcripts.

Pricing

from $0.38 / 1,000 transcripts

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

2

Monthly active users

6 days ago

Last modified

Share

Get the spoken words out of TikTok videos as a transcript: paste links and get the full text, the same text as timed segments, and ready-made SRT and WebVTT files. Each row also carries the video id, author, caption, hashtags, duration, play count and the language the track is in.

The thing to know before you plan a run: this reads the caption track TikTok already holds for a video. It does not listen to audio. A video with no caption track has nothing to give, and you get an uncharged row saying so. In a 120-video sample pulled from TikTok's own topic pages, 85 had a caption track and 35 did not.

InputVideo links, vm./vt. share links, or bare video ids
OutputOne row per transcript: full text, timed segments, SRT, WebVTT, language flags, and the video's id, author, caption, hashtags, length and counts
Ceiling1,000 links in, 5,000 transcripts per run
Account neededNone
Price$0.40 per 1,000 transcripts on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 12,500

🔍 What TikTok Transcript Scraper does

It reads each video's caption track and turns it into four shapes of the same thing: one block of text, an array of segments with start and end times, an srt string and a vtt string. Drop the SRT straight into an editor, or work off the segments.

TikTok makes a caption track itself when it hears speech, and creators can upload their own. Where TikTok also holds a translated track you can ask for it with language, and the row comes back marked isTranslated: true. When there is no translation you get the original rather than an error.

📋 What data you get from each TikTok transcript

What you getField
Video id, the canonical link and what you pastedvideoId, url, inputUrl
Author handle, name and profile linkauthorUsername, authorName, authorUrl
Caption, hashtags, length and post datecaption, hashtags, durationSeconds, createdAt
The whole transcript as one block, with word and character countstext, wordCount, characterCount
Timed segmentssegments, segmentCount
Subtitle files, ready to savesrt, vtt
Which track it is: language, made by TikTok or uploaded, translated or notlanguage, languageCode, languageName, isAutoGenerated, isTranslated, captionSource
Every caption track the video offeredavailableLanguages
Plays, likes, comments and sharesplayCount, likeCount, commentCount, shareCount
Sound title and cover imagemusicTitle, coverUrl

▶️ How to scrape TikTok transcripts

  1. Open TikTok Transcript Scraper and click Try for free.
  2. Paste your links into TikTok videos, one per line, replacing the two examples.
  3. Leave Preferred language empty for the original words, or put a code like es in it.
  4. Set Maximum transcripts low for the first run, then click Start.
  5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.

Start it with the input empty and you get one labelled sample row and nothing else.

💰 How much does it cost to scrape TikTok transcripts?

$0.40 per 1,000 transcripts on the Free plan. Paid plans pay a little less: $0.395 on Starter, $0.39 on Scale and $0.385 on Business. On the free plan, the $5 Apify gives you each month covers about 12,500 transcripts.

You are charged per transcript delivered. A video with no caption track, a deleted or private one, a line that was not a link, and the sample row are all uncharged. Links past your maxItems are never opened.

One thing to watch: the same video pasted twice, once as a share link and once as a full link, is read twice and counts twice. Paste one form per video.

📥 What you give it

{
"videoUrls": [
"https://www.tiktok.com/@studywithlizzz/video/7657803613355412766",
"7516208601434819862"
],
"maxItems": 10,
"language": ""
}
FieldDefaultWhat it is
videoUrlsnone (the box holds two example links)Full links, vm./vt. share links or bare numeric ids, mixed freely. Up to 1,000 per run.
maxItemsnone (the box holds 10)How many transcripts to return, up to 5,000. The list is read in order and the run stops when it has enough, so links past that point cost nothing.
languageemptyA code like es, fr, de or ja. You get the translated track where TikTok has one, the original where it does not.
concurrency6How many videos are read at once, up to 12. Lower it for a very long list.
sessionCookiesnoneOptional. Your own TikTok sessionid. Anyone holding that value can act as your account, so treat it like a password. The field is stored encrypted.
proxyUrlsnoneOptional. Your own servers, as http://user:pass@host:port, used exactly as given.

📤 What you get back

A real row from a recent run. The long fields and one name carrying emoji are cut short here:

{
"ok": true,
"charged": true,
"recordType": "transcript",
"videoId": "7657803613355412766",
"url": "https://www.tiktok.com/@studywithlizzz/video/7657803613355412766",
"authorUsername": "studywithlizzz",
"authorName": "liz | studytok ...",
"caption": "sometimes studying longer doesnt always mean higher grades... #studytok #studytips",
"hashtags": ["studytok", "studytips", "studyhacks", "studymotivation", "examtips"],
"durationSeconds": 63,
"createdAt": "2026-07-02T05:49:24.000Z",
"language": "eng-US",
"languageCode": "en",
"languageName": "English",
"isAutoGenerated": true,
"isTranslated": false,
"captionSource": "ASR",
"text": "You scored at the top of your class because you studied for three hours the night before your exam, or so you thought...",
"wordCount": 238,
"characterCount": 1292,
"segmentCount": 31,
"segments": [{"start": 0, "end": 1.58, "startTime": "00:00:00.000", "endTime": "00:00:01.580", "text": "You scored at the top of your class"}],
"srt": "1\n00:00:00,000 --> 00:00:01,580\nYou scored at the top of your class\n\n...",
"vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:01.580\nYou scored at the top of your class\n\n...",
"availableLanguages": ["eng-US"],
"playCount": 3600000,
"likeCount": 455300,
"commentCount": 1285,
"shareCount": 21000,
"musicTitle": "original sound",
"scrapedAt": "2026-09-21T01:29:19.131Z"
}
FieldHow to read it
textEvery cue joined into one block, which is what you want for search or a model.
segmentsCue-level timings. start and end are seconds, startTime and endTime the timecode form.
isAutoGenerated, captionSourceWhether TikTok's own speech recognition made the track, or a person uploaded it.
availableLanguagesEvery caption track that video exposed on that request, so you can see what else you could ask for.
playCount, likeCount, commentCount, shareCountCounts at read time. A genuine zero comes back as null.
coverUrlThe video's cover image. The link carries an expiry.

🧾 Reading the output

Three kinds of row can land in your dataset.

RowHow to spot itBilled
A transcriptok: true and recordType: "transcript"yes
The sample row_sample: true, written only when the input was emptyno
A diagnosticok: false, _diagnostic: true and an errorCodeno

Filter on recordType == "transcript" and you have your data. charged: true marks a real transcript row and false marks a sample or diagnostic one. Read it as the row type: it is stamped as the row is built, so it is not a receipt. Your run's own event count in Apify is the billing record.

CodeWhat it means
NO_TRANSCRIPTThe video has no caption track. Photo slideshows land here too.
NOT_FOUNDDeleted, private, region-locked, or shown only to a signed-in visitor.
BAD_INPUTThat line is not a TikTok video link or id.
NOT_SERVEDThis transcript was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED.
NETWORKThe page was unreachable or answered badly. A share link whose redirect fails lands here.
NO_RESULTSToo many videos in a row had no caption track, so the run stopped early instead of working through the list.
TIME_BUDGETThe run ran out of time before reaching that video. The run ends as failed only when the time limit stopped it before any transcript came back.
PROXY_INPUT_ADJUSTEDSomething you put in proxyUrls was unusable, so the run carried on without it.
CHARGE_ERRORA charge could not be recorded. A couple in a row stops the run.

💡 What people use it for

  • Turning a set of videos into text you can search, quote or feed to a model.
  • Making subtitle files for your own uploads, straight from srt or vtt.
  • Finding which videos in a niche actually say a phrase, rather than just tagging it.
  • Pulling the hook out of high-performing videos: the first few segments are the first few seconds.

From a hashtag to the hooks that work, in two runs:

  1. Run TikTok Hashtag Scraper on a tag in your niche and copy the webVideoUrl column.
  2. Paste those links into TikTok videos here and keep the rows where recordType is transcript.
  3. Sort by playCount and read the first two or three segments of the top videos.

🚧 What it does not do

  • It does not listen to audio. No caption track means no transcript, and about one video in three has none.
  • Timings are cue-level, not word-level. Each segment covers a phrase.
  • On-screen text is not included. Stickers, overlays and burned-in captions are pictures, not a caption track.
  • Translations only exist where TikTok made one. Asking for a language it does not hold gives you the original track, marked isTranslated: false.
  • No live videos or stories.
  • Age-restricted and private videos come back as uncharged NOT_FOUND rows.
  • A zero count reads as null. A video with genuinely no comments shows commentCount: null.
  • If every line you paste is unusable, you get the sample row rather than a message per line. Check your list if a run comes back with one row.
  • Counts are a snapshot, and a popular video's play count moves while you read it.
  • It is not an official TikTok tool. Dami's Studio is independent and is not affiliated with or endorsed by TikTok, or by any other company named on this page.

🧭 Which TikTok scraper do you need?

If you wantUse
The spoken words of a video, as text, SRT and VTTThis one
Speech from a video file that has no caption track, with your own OpenAI keyVideo & Audio Transcriber
Comments under a videoTikTok Comments Scraper
Videos posted under a hashtagTikTok Hashtag Scraper
A profile plus its newest videos, or a keyword searchTikTok Scraper
The same job on YouTubeYouTube Transcript Scraper

❓ Questions people ask

Do I need a TikTok account or an API key?

No. Videos are read with nothing signed in. The cookie field is optional.

Why did some TikTok videos come back with no transcript?

They have no caption track. TikTok makes one when it hears speech, so silent, music-only and some slideshow posts have nothing to read.

Can I get a Spanish transcript of an English video?

Only if TikTok already holds a Spanish track for it. Nothing is translated here.

Can I feed it a whole profile or hashtag?

Not directly. Collect the video links first with one of the scrapers in the table above, then paste them in.

Can I call it from code or connect it to an AI assistant?

Yes. The API tab has ready-made code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/tiktok-transcript-scraper. Either way the run happens on your Apify account at the same price.

The captions are published with the public video. Copyright in the words belongs to whoever said them. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the video link and the run ID. The errorCode on the diagnostic row usually names the problem on its own.