# TikTok Transcript Scraper: Captions and Speech to Text

> TikTok transcript scraper: paste video links or a profile name. Get timed text from TikTok captions, or speech to text when a video has none.

URL: https://cliqtomedia.com/actors/tiktok-transcript/

Category: Video, audio & streaming · Status: live on Apify Store · Apify page: https://apify.com/cliqtomedia/tiktok-transcript?fpr=cliqto

Get the text of a public TikTok video. The tool uses TikTok captions, or Whisper speech to text when there are none. You get clean text, timed segments and video data.

## How to use it: 3 steps

1. **Make a free Apify account.** Apify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
2. **Paste your input and press Start.** No code needed: you fill in a form (the input). It already has a working example. For example: `https://www.tiktok.com/@apifytech/video/7398101551744552225` in TikTok video links. Each start is one run.
3. **Download the results.** When the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

## What it does

Get the transcript of any public TikTok video: timestamped text from TikTok captions, or speech-to-text when a video has no captions. No TikTok login, no cookies.

- the full transcript as plain text;
- segments with start and end times in seconds;
- chunks of about 1,000 characters with times, ready for AI tools;
- metadata: author, description, hashtags, date, duration, views, likes, comments, shares, saves and sound;
- a clear status and reason when a video has no text (photo post, library sound only, silence, deleted video and more).

### Good for

- Repurpose TikTok videos into blog posts, captions, newsletters or scripts.
- Feed video text to ChatGPT, Claude or a RAG pipeline for summaries and research.
- Track what creators or competitors say in their newest videos, on a schedule.

## Price

Pay per event. Apify bills you, not us.

| What you pay for | Price | When |
|---|---|---|
| Start fee | $0.0025 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
| Video | $0.0009 (from $0.00063 on paid Apify plans) | One TikTok video found and saved with its metadata and transcript (or the reason there is no text). Not charged for invalid links, videos not found, or videos skipped as already processed. |
| Speech-to-text, 10 seconds | $0.002 (from $0.0014 on paid Apify plans) | Each started 10 seconds of audio run through speech-to-text (also when it finds no speech), only for videos without usable TikTok captions and only when fallbackToSpeechToText or translateToEnglish needs it. |
| Video checked, no paid row | $0.0001 | TikTok was checked but there is no paid row: a video not found, a profile not found, private or without videos, or a profile video skipped by skipProcessed after TikTok listed it. Invalid links and blocked requests are not charged. |

- One result: about $0.0034.
- 1,000 results: about $0.90.
- Every day 100 results, for 30 days: about $2.77 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Prices checked on 8 November 2026. Current price: https://apify.com/cliqtomedia/tiktok-transcript?fpr=cliqto

## Questions

### Do I need a TikTok account or cookies?

No. The tool reads public pages, without login or cookies.

### Can I get the text in another language?

Set language to use TikTok captions in that language. Set translateToEnglish to get English text.

### What if a video has no captions?

The tool listens to the audio and writes the text with Whisper. You can turn this off.

### Why is speech-to-text charged when the result is NO_SPEECH?

Speech-to-text has to process the whole audio to learn that it is only music or noise. That work is charged per 10 seconds. Videos that clearly have no speech (library sound only, silent, photo posts) are not sent to speech-to-text.

### Is the transcript complete and correct?

It is as good as TikTok's captions or the Whisper base model. TikTok's own speech recognition and Whisper can mishear names and words. `confidence` and `captionType` show where the text came from.

## Data fields

- `videoUrl` (string): TikTok link of the video.
- `inputUrl` (string): The link or name as given in the input (or the profile listing link).
- `videoId` (string): TikTok video ID.
- `status` (string): complete (transcript found), partial (video found, no text: see noTranscriptReason), not_found (removed, private or not available) or error (see errorCode).
- `source` (string): Where the text came from: captions (TikTok's own captions), whisper (speech-to-text) or none.
- `captionType` (string): tiktok-creator, tiktok-asr (TikTok's automatic captions), tiktok-translation or whisper-base.
- `confidence` (number): 0–1. TikTok captions have fixed levels (creator 0.95, automatic 0.85, translation 0.75); speech-to-text gets Whisper's own score.
- `language` (string): Language code of the transcript.
- `availableCaptionLanguages` (array): Caption languages TikTok has for this video.
- `transcript` (string): Plain text of the transcript.
- `segments` (array): Transcript lines with start and end in seconds.
- `chunks` (array): Pieces of about chunkCharacters characters with index, start, end and text, for AI tools.
- `wordCount` (integer): Words in the transcript.
- `noTranscriptReason` (string): Why there is no (full) text, in plain words.
- `errorCode` (string): Stable code of the reason: NO_ORIGINAL_AUDIO, NO_CAPTIONS, NO_SPEECH, TOO_LONG, PHOTO_POST, NOT_FOUND, NO_VIDEOS, PRIVATE_ACCOUNT, INVALID_URL, BLOCKED, CHARGE_LIMIT, …
- `description` (string): Video caption text written by the author.
- `hashtags` (array): Hashtags of the video.
- `createTimeISO` (string): When the video was posted (UTC).
- `durationSeconds` (integer): Video length in seconds.
- `descriptionLanguage` (string): Language of the description, as TikTok detects it.
- `isPhotoPost` (boolean): true for photo posts (slideshows).
- `author` (object): username, nickname, id, verified, followerCount (outputFormat nested).
- `stats` (object): playCount, diggCount, commentCount, shareCount, collectCount (outputFormat nested).
- `music` (object): title, author, isOriginal of the sound (outputFormat nested).
- `files` (object): Links to srt, vtt and txt files when saveSubtitleFiles is on (outputFormat nested).
- `speechSecondsCharged` (integer): Seconds of audio charged for speech-to-text (in 10-second steps).
- `profile` (string): Profile the video was listed from.
- `fetchedAt` (string): When the row was made (UTC).

## Input settings

- `videoUrls` (array): Up to 1,000 public TikTok links: video links (tiktok.com/@user/video/…), short links (vm.tiktok.com/…, tiktok.com/t/…), photo posts, video IDs, or profile links (@user — then the newest videos are taken). Duplicates are processed once.
- `profiles` (array): Up to 50 usernames (@name) or profile links. The Actor takes the newest videos of each public profile, up to the number below.
- `maxVideosPerProfile` (integer): How many of the newest videos to take from each profile. One run takes at most 1,000 videos in total (links and profile videos together); profiles after that get a RUN_VIDEO_LIMIT row.
- `language` (string): Two-letter code such as en, es, de. When TikTok has captions in this language (including TikTok's own translations), they are used; otherwise the video's original language. Empty = original language.
- `fallbackToSpeechToText` (boolean): When TikTok has no captions for a video, transcribe its audio with Whisper (charged per 10 seconds of audio). Videos that use only a library sound (no original audio) are not transcribed.
- `translateToEnglish` (boolean): Return English text: TikTok's English captions when they exist, otherwise Whisper translates the speech into English (charged like speech-to-text).
- `maxSpeechMinutesPerVideo` (integer): Longer videos without captions are returned without text (and without the speech charge).
- `chunkCharacters` (integer): The transcript is also split into chunks of about this many characters with start and end times, ready for RAG and LLM tools. 0 = no chunks.
- `saveSubtitleFiles` (boolean): Save subtitle files of each transcript in the run's key-value store; links are in the files field.
- `outputFormat` (string): Nested keeps author, stats and music as groups; flat turns them into columns such as authorUsername and playCount.
- `skipProcessed` (boolean): For scheduled runs: videos returned by earlier runs with the same state name are skipped: no full row, only a $0.0001 check when TikTok listed them.
- `stateName` (string): Name of the key-value store that remembers processed videos. Use different names for different monitoring tasks.
- `proxyConfiguration` (object): Not needed: by default the Actor connects directly and switches to Apify Proxy by itself if TikTok refuses. Set your own proxy only if you need a specific one.
- `deliveryConnector` (string): Your Slack, Notion or other MCP connector. After the run the Actor posts a short summary there. Connect services once in Apify Console → MCP connectors.
- `deliveryTarget` (string): Where to post the summary: a Notion page link (each run is added on top of that page) or a Slack channel ID. Leave empty to let the connector decide.

## Step by step on Apify

1. Open the Input tab. The field TikTok video links already has one example video (box 1 in the picture).
2. Replace it with your own links, one per line. You can also add usernames in Profiles.
3. Keep Transcript options as they are (box 3): captions first, speech-to-text when there are none.
4. Click Start.
5. When the run ends, open the Output tab. The Overview table shows the status, where the text came from and the transcript (box 5).

## Use cases

| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Turn a video into a blog post or script | `videoUrls` | One row per video | `transcript`, `description`, `hashtags` | Copy to a doc, or send to an LLM |
| Give an AI tool clean video text | `videoUrls` | Row with chunks | `chunks` (`text`, `start`, `end`), `videoUrl` | RAG / vector database, MCP agent |
| Make subtitles | `videoUrls` + `saveSubtitleFiles` | SRT / VTT / TXT files | `files.srt`, `files.vtt` | Video editor |
| Watch what creators say | `profiles` + `skipProcessed` | Rows for new videos only | `transcript`, `createTimeISO`, `stats` | Schedule, Slack or Notion summary |
| Research topics or trends | `profiles` or `videoUrls` | Rows with metadata | `transcript`, `hashtags`, `stats.playCount` | CSV / Excel |

## Tips

- Add video links, or a profile name to take its newest videos. One run takes up to 1,000 videos.
- A video with only a library sound has no speech. It gets NO_ORIGINAL_AUDIO and no text.
- Whisper base works best on clear speech. Check the confidence field.

## Limits



- Only public videos and public profiles. Private accounts and private videos return `PRIVATE_ACCOUNT` or `not_found`. No login is used, so the Actor cannot see what only followers see.
- Up to 1,000 links and 50 profiles (up to 500 newest videos each) per run, but at most 1,000 videos in total per run (links and profile videos together). Profiles after that limit get a row with `RUN_VIDEO_LIMIT`; a profile not reached before the run timeout gets `RUN_TIME_LIMIT`. Split bigger jobs into several runs.
- Speech-to-text works on one video at a time: about 1 hour of audio takes about 22 minutes of run time. The default run timeout is 1 hour, which fits about 2.5 hours of audio. For more, raise the timeout or split the input.
- Speech-to-text uses the Whisper base model. It is good for clear speech; songs, strong accents and noise give weaker text (look at `confidence`).
- A video with only a sound from the TikTok library (a song, a popular sound) has no original speech: it gets `NO_ORIGINAL_AUDIO` and no text.
- Short links (`vm.tiktok.com/…`, `tiktok.com/t/…`) are supported; a short link that no longer leads to a video gets `NOT_FOUND`. We checked the expired case live; a working short link was checked only in tests.
- The output fields are our own. They are not the same as other TikTok transcript Actors, so a switch may need small changes in your code.
- Comments, video files and downloads are not part of the output. The video is not stored.

## Sample result

```json
{
  "videoUrl": "https://www.tiktok.com/@apifytech/video/7698373675267001622",
  "videoId": "7698373675267001622",
  "status": "complete",
  "source": "captions",
  "captionType": "tiktok-asr",
  "confidence": 0.85,
  "language": "en",
  "transcript": "If I just makes it super easy to unlock that, because going to try and get a Google Maps API …",
  "segments": [
    {"start": 0.1, "end": 2.78, "text": "If I just makes it super easy to unlock that,"},
    {"start": 2.781, "end": 3.581, "text": "because"}
  ],
  "wordCount": 155,
  "noTranscriptReason": null,
  "errorCode": null,
  "hashtags": ["apify", "aiagents", "vibecoding", "mcp"],
  "createTimeISO": "2026-10-21T14:00:00Z",
  "durationSeconds": 57,
  "author": {"username": "apifytech", "nickname": "Apify", "verified": false, "followerCount": 3589},
  "stats": {"playCount": 783, "diggCount": 5, "commentCount": 0, "shareCount": 1, "collectCount": 4},
  "music": {"title": "original sound - Apify", "author": "Apify", "isOriginal": true},
  "files": null,
  "speechSecondsCharged": 0
}
```

## Use it from code

Actor ID: `cliqtomedia/tiktok-transcript`

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/tiktok-transcript").call(run_input={
    "videoUrls": [
        "https://www.tiktok.com/@apifytech/video/7398101551744552225"
    ],
    "maxVideosPerProfile": 10
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

```bash
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~tiktok-transcript/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"videoUrls": ["https://www.tiktok.com/@apifytech/video/7398101551744552225"], "maxVideosPerProfile": 10}'
```

```python
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/tiktok-transcript")
result = tool.invoke({"run_input": {"videoUrls": ["https://www.tiktok.com/@apifytech/video/7398101551744552225"], "maxVideosPerProfile": 10}})
print(result)
```

run-sync waits up to 300 seconds; for longer runs start a run and use a webhook. LlamaIndex and MCP: https://cliqtomedia.com/actors/ai-agents/

## Similar tools

- [YouTube Transcript Scraper: Subtitles & Timed Text](https://cliqtomedia.com/actors/youtube-transcript-scraper/)
- [Audio & Podcast Transcriber (Speech to Text)](https://cliqtomedia.com/actors/audio-video-transcriber/)
- [Social Video Downloader: TikTok, Instagram, X - No Login](https://cliqtomedia.com/actors/social-video-downloader/)
- [YouTube Comments Scraper: Replies & CSV Export](https://cliqtomedia.com/actors/youtube-comments-scraper/)
- [Apple Podcast Directory Scraper: RSS & Owner Contacts](https://cliqtomedia.com/actors/podcast-directory-rss-contacts-scraper/)
- [Kick Live Streams & Viewer Count (Official API), No Login](https://cliqtomedia.com/actors/kick-channels/)
