TikTok Transcript Scraper - Video to Text, SRT & Bulk
Pricing
from $1.70 / 1,000 transcript from native captions
TikTok Transcript Scraper - Video to Text, SRT & Bulk
Transcribe public TikTok videos to text, timestamped segments, SRT and VTT. Uses TikTok's own captions when they exist and falls back to Whisper speech-to-text when they don't, so caption-less videos still return a transcript. Bulk-friendly, no API key, no cookies.
Pricing
from $1.70 / 1,000 transcript from native captions
Rating
0.0
(0)
Developer
Saulius Saulenas
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
TikTok Transcript Scraper — TikTok video to text, SRT & bulk
Turn public TikTok videos into transcripts, timestamps, SRT and VTT — including the ones TikTok never captioned.
Paste TikTok links, get the words back. Every video returns plain text, timestamped segments, a
ready-to-use .srt subtitle file, a .vtt file, and the source metadata: creator, caption,
hashtags, duration, language, view count.
Most TikTok transcript tools only read TikTok's own caption track, so they hand back nothing for the majority of TikToks — the ones where the creator turned captions off, or TikTok never generated them. This Actor falls back to Whisper speech-to-text and transcribes the audio instead.
- No API key, no login, no cookies. Public videos only.
- 90+ languages. The transcript comes back in the video's own language by default.
- Bulk-safe. One dead link never breaks the rest of the run.
- You only pay for delivered transcripts. Failures, private videos and over-length videos are free.
What it handles
| Input | Supported |
|---|---|
tiktok.com/@user/video/1234567890123456789 | ✅ |
vm.tiktok.com/… and tiktok.com/t/… share links | ✅ (followed to the real video) |
tiktok.com/embed/v2/… embed URLs | ✅ |
m.tiktok.com/… mobile links | ✅ |
| Photo-mode posts | ✅ when they carry audio |
| Profile, hashtag or search URLs | ❌ — these are not single videos and return INVALID_URL |
| Private, friends-only, deleted or region-locked videos | ❌ — returned as an error row, uncharged |
Other platforms return a clear error pointing you at Short Video Transcriber, which handles TikTok, YouTube Shorts and Instagram Reels in one run.
Captions vs Whisper — the part that matters
TikTok publishes caption tracks for only some videos, and it says why when it does not: the creator disabled them, TikTok's own speech recognition never ran, or it ran and found no speech in a supported language.
- Native captions first. When TikTok has a usable track, the words come from it. Fast, and priced at $0.002.
- Whisper when there are none. The audio is downloaded and transcribed locally with faster-whisper. Priced at $0.040, because it costs roughly a second of CPU per 1.5 seconds of audio.
Where TikTok offers several tracks — its speech recognition of the original audio plus machine
translations of that into other languages — the original language is chosen, because a
translation of what was said is not a transcript of it. Ask for a specific language and you get
that track instead, translation or not.
Exactly one of those two events is charged per video, after the row is written. Never both, never before. A video that fails is not charged at all.
What you get
One dataset row per input URL:
{"url": "https://www.tiktok.com/@shanehryhorec/video/7674894968963534100","platform": "tiktok","videoId": "7674894968963534100","author": "shanehryhorec","authorName": "Shane Hryhorec","title": "Kicked off a Virgin Australia plane today. ✈️♿️","hashtags": ["accessibility", "wheelchair", "travel"],"durationSeconds": 179.0,"language": "en","source": "native_captions","sourceDetail": "tiktok_auto_captions","isAutoGenerated": true,"text": "I was kicked off a Virgin Australia flight today…","segments": [{ "start": 0.08, "end": 2.14, "text": "I was kicked off a Virgin Australia" },{ "start": 2.14, "end": 4.46, "text": "flight today, and here is what happened" }],"srt": "1\n00:00:00,080 --> 00:00:02,140\nI was kicked off a Virgin Australia\n\n2\n…","vtt": "WEBVTT\n\n00:00:00.080 --> 00:00:02.140\nI was kicked off a Virgin Australia\n\n…","wordCount": 695,"segmentCount": 118,"viewCount": 1840231,"publishedAt": "2026-08-14T10:03:11+00:00","status": "ok","error": null}
source is always exactly one of:
native_captions— the words came from TikTok's own caption track.whisper_asr— the video had no usable captions, so the audio was transcribed with Whisper.
The srt and vtt fields are complete, valid subtitle files. Overlapping cues from
auto-generated tracks are trimmed, so subtitles do not double up on screen.
Pricing
| Event | Price | When it fires |
|---|---|---|
caption_transcript | $0.002 | A transcript came from TikTok's native captions. |
asr_transcript | $0.040 | A transcript came from Whisper because there were no captions. |
apify-actor-start | $0.00005 | Apify's standard start event, charged once per gigabyte of the run's memory. This Actor runs at 2 GB, so $0.0001 per run. |
Those are the Free-plan prices. Apify's paid plans get the standard Store discount off every
event — Bronze 5 %, Silver 10 %, Gold and above 15 % — so asr_transcript costs $0.038, $0.036 or
$0.034 on those plans and caption_transcript costs $0.0019, $0.0018 or $0.0017.
What a run actually costs
Caption availability is what moves the bill, and on TikTok it is lower than on YouTube: dance, music, meme and lifestyle content is mostly caption-less, while talking-head, storytime, educational and news content is largely captioned.
| 1,000 TikToks | Cost |
|---|---|
| All have captions | $2.00 |
| 50 % captions / 50 % Whisper | $21.00 |
| 25 % captions / 75 % Whisper | $30.50 |
| None have captions | $40.00 |
(Free-plan prices; a Gold plan pays 15 % less than each of these.)
Turn "Transcribe with Whisper when a TikTok has no captions" off to cap the price at $0.002 per
video: caption-less videos then return a CAPTIONS_UNAVAILABLE error, free of charge, and you
decide what to do with them.
Nothing else is charged. In particular you are not charged for:
- videos that are deleted, private, friends-only or region-locked;
- videos longer than your
maxDurationSecondscap; - caption-less videos longer than
maxAsrDurationSeconds(they returnASR_DURATION_EXCEEDED); - videos where Whisper finds no speech at all (music-only clips);
- profile URLs, malformed URLs or links from other platforms;
- any run that fails.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
videoUrls | array | — | Required. TikTok video URLs, one per line. Share links work. |
language | string | (blank) | Two-letter code (en, es, pt, ru…). Blank keeps the video's own language — usually what you want. Setting it selects that language's caption track when TikTok offers one (which may be a machine translation) and tells Whisper what to expect. |
allowWhisperFallback | boolean | true | Off = captions only, and caption-less videos cost nothing. |
maxDurationSeconds | integer | 600 | Videos longer than this are skipped, free. Max 1200. |
maxAsrDurationSeconds | integer | 180 | Length limit for the Whisper path only. Caption-less videos longer than this return ASR_DURATION_EXCEEDED, free. Captioned videos are unaffected. |
maxVideos | integer | 1000 | Safety cap on the number of URLs processed. |
forceWhisper | boolean | false | Advanced. Transcribe with Whisper even when TikTok has captions. Charged at the asr_transcript rate — 20× the caption price. |
whisperModel | string | base | tiny, base or small. Only affects the Whisper fallback. |
beamSize | integer | 1 | Whisper decoding beam width. |
concurrency | integer | 5 | Videos resolved in parallel. Whisper always runs one at a time. |
includeFailedItems | boolean | true | Keep a row (with an error code) for every failure, so inputs reconcile to outputs. |
useResidentialFallback | boolean | true | Retries a request through a residential IP when TikTok answers the normal proxy with a bot check. Rarely used — TikTok serves datacenter IPs fine. |
proxyConfiguration | object | Apify Proxy | Recommended. The run pins one proxy session, which is what TikTok's media CDN requires. |
Minimal input
{"videoUrls": ["https://www.tiktok.com/@shanehryhorec/video/7674894968963534100","https://vm.tiktok.com/ZMabcdefg/"]}
Run it
In the Apify Console
Open the Actor, paste your links into TikTok video URLs, one per line, and click Start.
Results appear in the dataset and export as JSON, CSV, XLSX or Excel — or download the srt
column straight into subtitle files.
API
curl -X POST "https://api.apify.com/v2/acts/sauliusautomatesit~tiktok-transcript-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"videoUrls": ["https://www.tiktok.com/@shanehryhorec/video/7674894968963534100"],"allowWhisperFallback": true}'
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("sauliusautomatesit/tiktok-transcript-scraper").call(input={"videoUrls": ["https://www.tiktok.com/@shanehryhorec/video/7674894968963534100","https://www.tiktok.com/@pabloescabor.08/video/7675011438385057040",],"allowWhisperFallback": True,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():if item["status"] != "ok":print(f"{item['inputUrl']}: {item['error']} — {item['errorMessage']}")continueprint(item["author"], item["language"], item["wordCount"], "words", f"({item['source']})")with open(f"{item['videoId']}.srt", "w", encoding="utf-8") as handle:handle.write(item["srt"])
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('sauliusautomatesit/tiktok-transcript-scraper').call({videoUrls: ['https://www.tiktok.com/@shanehryhorec/video/7674894968963534100',],});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const item of items) {if (item.status !== 'ok') {console.warn(`${item.inputUrl}: ${item.error}`);continue;}console.log(`@${item.author} (${item.source}): ${item.text}`);// await fs.writeFile(`${item.videoId}.srt`, item.srt);}
n8n, Make and Zapier
Works with the standard Apify → Run Actor node in n8n and the Apify → Run an Actor module
in Make. Point the node at this Actor, pass videoUrls as the input JSON, then read the dataset
items in the next step — text for the transcript, srt for a subtitle file, error to branch on
failures.
A common shape: a sheet or webhook supplies TikTok links → this Actor returns transcripts → an LLM
node summarises, tags or repurposes them → the result is written back. Because failures come back
as rows with an error field rather than as a broken run, a filter on status == "ok" is all the
error handling most workflows need.
Errors
Failed videos get a dataset row with status: "error", an error code and a plain-English
errorMessage. They are never charged.
| Code | Meaning |
|---|---|
VIDEO_UNAVAILABLE | Deleted, never existed, or region-locked. |
VIDEO_PRIVATE | Private, friends-only or followers-only. |
DURATION_EXCEEDED | Longer than maxDurationSeconds. |
ASR_DURATION_EXCEEDED | No captions, and longer than maxAsrDurationSeconds. Raise that limit to transcribe it anyway. |
CAPTIONS_UNAVAILABLE | No native captions and the Whisper fallback is turned off. |
NO_SPEECH_DETECTED | Whisper found no speech — a music-only or silent video. |
INVALID_URL | Not a link to a single TikTok video — a profile, hashtag or search URL, for example. |
PLATFORM_NOT_ENABLED | A YouTube or other non-TikTok URL. Use Short Video Transcriber for those. |
MEDIA_UNAVAILABLE | The audio could not be downloaded for transcription. |
BLOCKED / RATE_LIMITED | TikTok refused the request. Try again, ideally with a proxy. |
MEMORY_LIMIT | The video does not fit in the run's memory for the chosen model. Raise the memory or pick a smaller model. |
Limits and good to know
- Public videos only. No login, no cookies, no private or followers-only content, and no way to add any — that is a deliberate design choice, not a missing feature.
- Not every video can be transcribed. A deleted, private or region-locked video fails, and a
video that is pure music with no speech legitimately returns
NO_SPEECH_DETECTED. You are not charged for either. - Memory. Run with at least 2 GB. That covers the whole duration range with the
basemodel; the Actor refuses an impossible combination up front instead of being killed mid-run. - TikTok's auto-captions are auto-captions. When a transcript comes from TikTok's own ASR
track (
isAutoGenerated: true), it carries that track's mistakes, and on music-heavy videos it can be very sparse. For maximum accuracy on a specific video, switchforceWhisperon — and accept theasr_transcriptprice — or raisewhisperModeltosmall. - Caption availability changes. TikTok backfills captions hours after upload, so the same video can take the Whisper path today and the caption path tomorrow.
- Whisper is length-limited; captions are not. A caption-less video is transcribed up to
maxAsrDurationSeconds(180 s by default, which covers the overwhelming majority of TikToks). Past that, Whisper's cost outgrows a per-video price, so the video returnsASR_DURATION_EXCEEDEDand costs you nothing. Raise the limit if you want those anyway. Videos with captions run to the fullmaxDurationSecondsat the $0.002 rate, whatever their length. - One URL per video. This Actor does not crawl profiles or hashtags to find videos for you.
What this Actor does not do
It transcribes videos. It does not scrape comments, followers or profile analytics, does not monitor accounts, and does not summarise, translate or score sentiment — pipe the transcript into an LLM step for that.
Related searches
TikTok transcript · TikTok to text · transcribe TikTok · TikTok subtitles · TikTok SRT · TikTok caption extractor · TikTok video to text · download TikTok subtitles · TikTok speech to text · bulk TikTok transcripts · TikTok VTT · TikTok transcript API