# TikTok Video Transcript & Subtitles Scraper (`heyitsgautham/tiktok-transcript-scraper`) Actor

Transcripts of public TikTok videos: full text, timestamps, language, author and stats, from URLs or short links. Videos without captions can be transcribed from their audio with AI speech-to-text. $1.50 per 1,000 caption transcripts, $28 per 1,000 from speech, videos with no speech free.

- **URL**: https://apify.com/heyitsgautham/tiktok-transcript-scraper.md
- **Developed by:** [Gautham Krishna](https://apify.com/heyitsgautham) (community)
- **Categories:** Social media, Videos, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## TikTok Video Transcript & Subtitles Scraper

Get the transcript of any public TikTok video as clean text, for marketers, researchers and developers who need the spoken words of a video.

Use cases, each with a ready-to-run example:

- [Get the transcript of a TikTok from its link](https://apify.com/heyitsgautham/tiktok-transcript-scraper/examples/mrbeast-tiktok-transcript)
- [Turn share links such as vm.tiktok.com into transcripts](https://apify.com/heyitsgautham/tiktok-transcript-scraper/examples/tiktok-share-link-transcripts)
- [Get TikTok subtitles with timestamps](https://apify.com/heyitsgautham/tiktok-transcript-scraper/examples/tiktok-subtitles-with-timestamps)
- [Transcribe several TikTok videos in one run](https://apify.com/heyitsgautham/tiktok-transcript-scraper/examples/bulk-tiktok-transcripts)
- [Get transcripts of Spanish videos, or in any caption language](https://apify.com/heyitsgautham/tiktok-transcript-scraper/examples/spanish-tiktok-transcripts)
- [Study what creators say for marketing research](https://apify.com/heyitsgautham/tiktok-transcript-scraper/examples/tiktok-transcripts-for-marketing-research)

Paste video URLs or short links, pick a language, and get one row per video with the full transcript, timestamps, video details and basic stats.
For videos TikTok never captioned, turn on the optional speech-to-text fallback and get a transcript from the audio.

You pay **$1.50 per 1,000 caption transcripts** ($0.0015 each) and **$28 per 1,000 speech-to-text transcripts** ($0.028 each).
Both cost less on Apify Store discount tiers (Bronze, Silver, Gold), down to $1.20 and $20 per 1,000 on Gold.
Videos with no speech (music or silence), deleted or private videos and failed fetches are **never charged**.

### At a glance

| Topic | Details |
|---|---|
| Input | Many videos per run: TikTok URLs, short links (vm.tiktok.com, vt.tiktok.com, tiktok.com/t/) or video IDs, plus the caption language you want |
| Output | One JSON row per video: transcript text, timestamped segments, language, author, description, upload time, plays, likes, comments, shares and saves |
| Price | $0.0015 per caption transcript ($1.50 per 1,000), or $1.40 per 1,000 on Bronze, $1.30 on Silver and $1.20 on Gold. $0.028 per speech-to-text transcript ($28 per 1,000), or $25, $22 and $20 per 1,000 on Bronze, Silver and Gold. No start fee. Videos with no speech, deleted or private videos are free |
| Speech-to-text | Off by default. When on, videos without captions are transcribed from their audio with Google's Gemini 3.5 Flash-Lite. Music, songs and silent videos come back as free `no_speech` rows |
| Tested | Captions: 172 real public links, all 97 videos that had captions returned a transcript. Speech-to-text: 48 public videos without captions in one run, 13 transcripts, 29 free `no_speech` rows (music, songs, silence or no audio track), 6 items TikTok served with no video file, no errors |

### What it returns

The scraper reads the captions TikTok already publishes for a video.
That covers TikTok's auto-generated captions, captions the creator added, and TikTok's own machine translations.
A video TikTok never captioned comes back as `no_transcript` and costs nothing, unless you turn on speech-to-text.
Every transcript row says where its text came from in `source`.

| Field | What it holds |
|---|---|
| `status` | `ok`, `no_transcript`, `no_speech`, `unavailable`, `invalid_input`, `duplicate` or `error` |
| `source` | `captions` when the text is TikTok's captions, `speech_to_text` when it came from the audio |
| `videoId`, `url`, `input` | The video ID, a clean video URL and the input you passed |
| `author`, `authorName` | The creator's handle and display name |
| `description` | The post caption with hashtags |
| `createTime` | Upload time in UTC |
| `durationSeconds` | Video length |
| `playCount`, `likeCount`, `commentCount`, `shareCount`, `saveCount` | Stats from the same page load, at no extra cost |
| `language`, `languageCode` | Language of the returned transcript, as `en` and as TikTok's own code such as `eng-US` |
| `requestedLanguageFound` | `false` when TikTok has no captions in your language, so you got the original ones |
| `isAutoGenerated` | `true` when the captions came from TikTok's speech recognition or translation, and always on speech-to-text rows |
| `isMachineTranslated` | `true` when TikTok translated the captions from another language |
| `availableLanguages` | Every caption language TikTok has for the video |
| `transcript` | The full transcript as one string |
| `wordCount` | Words in the transcript |
| `segments` | `[{ "start": 0.32, "end": 2.08, "text": "..." }]`, when timestamps are on |
| `audioSeconds`, `audioTruncated` | Speech-to-text rows only. Seconds of audio transcribed, and `true` when the video ran past `maxAudioSeconds` |
| `message` | Why a row has no transcript |

### Input

```json
{
  "videos": [
    "https://www.tiktok.com/@hankgreen1/video/7117085272323443974",
    "https://vm.tiktok.com/ZGdChBJw6/",
    "https://www.tiktok.com/t/ZPLeg4Yrx/",
    "7117085272323443974"
  ],
  "language": "en",
  "includeTimestamps": true,
  "speechToTextFallback": false
}
```

It accepts full video URLs, `vm.tiktok.com`, `vt.tiktok.com` and `tiktok.com/t/` short links, `m.tiktok.com` links, embed links and numeric video IDs.
A video listed twice in one run, for example as a URL and as its ID, is fetched and charged once, for the first input that names it.
Each later copy is a free `duplicate` row whose `duplicateOf` names that input.
A short link counts once TikTok resolves it.

### How language works

1. Captions in your language come first: creator captions, then TikTok's auto captions, then TikTok's machine translation.
2. If TikTok has nothing in your language, you get the video's original captions, and the row shows `requestedLanguageFound: false`.

TikTok only offers machine translations into some languages, most often English.

### Speech-to-text for videos without captions

Set `speechToTextFallback` to `true` to transcribe videos that TikTok never captioned.

1. Videos with captions always use the captions. They cost the caption price as usual ($0.0015 with no discount) and never go to speech-to-text.
2. For a video without captions, the scraper downloads its public audio and sends it to Google's Gemini 3.5 Flash-Lite model on Google Cloud Vertex AI.
3. If someone speaks, you get a row with `source: "speech_to_text"`, the transcript in the spoken language and timestamped segments. It costs $0.028, or $0.020 on Gold.
4. If nobody speaks (music, songs, sound effects or silence), you get a free `no_speech` row. Silent clips and clips with no audio track are caught before any AI call.

Limits, so a run never surprises you:

| Input | Default | What it does |
|---|---|---|
| `maxAudioSeconds` | 300 | Reads at most this many seconds from the start of each video. Longer videos get a partial transcript with `audioTruncated: true`. 300 is also the maximum |
| `maxSpeechToTextMinutes` | 600 | Total audio minutes one run sends to speech-to-text. Videos past it come back as free `no_transcript` rows |

Your maximum charge per run in the run options applies on top of both.

Speech-to-text is a language model listening to the audio, so treat it as a good draft.
Timestamps can be off by about a second, and the text is in the spoken language without translation.
Sung lyrics are dropped, so a video that is only a song comes back as a free `no_speech` row.
The model can still let a sung line through, or miss a word spoken over loud music.
`language` names the main language of the audio, which can be a song's language when the speech is in another.

This is a real speech-to-text row from the test run, with `segments` cut to the first three lines.

```json
{
  "input": "https://www.tiktok.com/@zachking/video/7679074910446030094",
  "videoId": "7679074910446030094",
  "url": "https://www.tiktok.com/@zachking/video/7679074910446030094",
  "status": "ok",
  "source": "speech_to_text",
  "author": "zachking",
  "authorName": "Zach King",
  "description": "Fashion #hack ",
  "createTime": "2026-08-28T13:32:47Z",
  "durationSeconds": 8,
  "playCount": 10000000,
  "likeCount": 729700,
  "commentCount": 8905,
  "shareCount": 11900,
  "saveCount": 37950,
  "language": "en",
  "languageCode": "en",
  "requestedLanguageFound": true,
  "isAutoGenerated": true,
  "isMachineTranslated": false,
  "availableLanguages": [],
  "transcript": "This is the best shopping hack. Huh. That's pretty cool, I need that one. Huh. Guys, get get out of here.",
  "wordCount": 21,
  "audioSeconds": 8.56,
  "audioTruncated": false,
  "segments": [
    {
      "start": 0,
      "end": 1.3,
      "text": "This is the best shopping hack."
    },
    {
      "start": 2.1,
      "end": 2.4,
      "text": "Huh."
    },
    {
      "start": 2.7,
      "end": 4.2,
      "text": "That's pretty cool, I need that one."
    }
  ]
}
```

### Output example

This is real output for the first video in the input above, with `segments` cut to the first three lines.

```json
{
  "input": "https://www.tiktok.com/@hankgreen1/video/7117085272323443974",
  "videoId": "7117085272323443974",
  "url": "https://www.tiktok.com/@hankgreen1/video/7117085272323443974",
  "status": "ok",
  "source": "captions",
  "author": "hankgreen1",
  "authorName": "Hank Green",
  "description": "Thanks to all of these lovely people! @lauraslibraryy @_cassidybrooke_ @entomologyabby @mynameismarines @squish.and.co @reading.reverie @earlgreypls @sineadrobbins @dooweedecimalsystem @bundaddy",
  "createTime": "2022-07-06T02:45:52Z",
  "durationSeconds": 53,
  "playCount": 2400000,
  "likeCount": 99200,
  "commentCount": 1324,
  "shareCount": 713,
  "saveCount": 12707,
  "language": "en",
  "languageCode": "eng-US",
  "requestedLanguageFound": true,
  "isAutoGenerated": false,
  "isMachineTranslated": false,
  "availableLanguages": [
    "eng-US"
  ],
  "transcript": "Here are some book recommendations for my fellow friends with ADD First up, An Absolutely Remarkable Thing by Hank Green I haven't read a book for fun in years I got it this weekend and I started reading it today and I am halfway through this book Truly edge of your seat gripping the entire time This is probably one of my favorite duologies because of how well the stories pair together I'm so glad there's already a sequel out So far, this has been my favorite read of the year It's so fun So fun I'm reading the sequel right now and I'm loving it 5 out of 5 for sure I'm not huge on sequels and series of books I struggle to find the inspiration to keep reading them but I would read these over again 1000 times When I finish the sequel I'm gonna read the first one again I just love the book and I think you all would love it, too I'm really grateful that these books have such wonderful and vocal advocates I've just put the last few hundred hardcovers we have in stock on sale You can get them both in a bundle for $29 There's a link in my bio",
  "wordCount": 208,
  "segments": [
    {
      "start": 0,
      "end": 2.78,
      "text": "Here are some book recommendations for my fellow friends with ADD"
    },
    {
      "start": 2.84,
      "end": 4.879,
      "text": "First up, An Absolutely Remarkable Thing by Hank Green"
    },
    {
      "start": 4.88,
      "end": 7.759,
      "text": "I haven't read a book for fun in years"
    }
  ]
}
```

### How many videos have captions

TikTok does not caption every video.
In a test run on 172 real public TikTok links from October 2026, 97 returned a transcript (100% of the videos that had captions), 61 had no captions and 14 were deleted, private or under review.
So expect roughly 4 in 10 live videos to have no captions.

Music clips, silent videos, photo slideshows and many news clips often have none.
In the speech-to-text test, 13 of the 48 videos without captions had people speaking, and the other 35 were music, songs, silence or items with no video file.
You only pay for the rows that come back with text.

### Use it from AI agents

The scraper works as a tool through the [Apify MCP server](https://mcp.apify.com) in Claude, Cursor, VS Code and other MCP clients.
Agents can pass a list of TikTok links and get back plain text they can summarise, quote or index.
Each call charges only for the transcripts it returns.

You can also call it through the [Apify API](https://docs.apify.com/api/v2) or the Python and JavaScript clients, and schedule it or connect it to Make, Zapier and n8n.

### Pricing

| Event | Price |
|---|---|
| Transcript from TikTok's captions | $0.0015, or $0.0014 on Bronze, $0.0013 on Silver and $0.0012 on Gold |
| Transcript from speech-to-text (only when `speechToTextFallback` is on) | $0.028, or $0.025 on Bronze, $0.022 on Silver and $0.020 on Gold |
| No captions, no speech, deleted or private video, repeated video, invalid input or failed fetch | Free |

Bronze, Silver and Gold are Apify Store discount tiers, and Apify's Pricing tab shows them as Starter, Scale and Business.
Apify decides which tier an account is on.

Set a maximum cost per run in the run options.
The scraper stops once that limit is reached.

### More from heyitsgautham

Other actors from the same account.

- [YouTube Transcript & Subtitles Scraper](https://apify.com/heyitsgautham/youtube-transcript-scraper) for specific videos, or when you want every video on a channel or playlist with channel stats and up to 20,000 videos per source.
- [YouTube & TikTok Transcripts MCP Server for AI Agents](https://apify.com/heyitsgautham/video-transcripts-mcp-server) for giving an AI agent YouTube and TikTok transcripts, YouTube search and comments as MCP tools, with nothing to host.
- [YouTube Channel & Playlist Transcripts](https://apify.com/heyitsgautham/youtube-channel-transcripts) for every video on a channel or playlist, with channel stats and up to 20,000 videos per source.
- [YouTube Video & Shorts Comments Scraper with Replies](https://apify.com/heyitsgautham/youtube-comments-scraper) for the comments and replies on a video or Short, for sentiment analysis and audience research.
- [YouTube Search Results & Rank Tracker Scraper](https://apify.com/heyitsgautham/youtube-search-scraper) for YouTube search results with rank, and channel discovery within a subscriber range.

### FAQ

**Why does a video show `no_transcript`?**
TikTok has no captions for it, and speech-to-text is off.
That happens when the video has no speech, the creator turned captions off, or TikTok has not generated them yet.
That row isn't charged.

**Does it transcribe videos without captions?**
Yes, when you set `speechToTextFallback` to `true`.
Each transcribed video costs $0.028, or $0.020 on Gold, and videos with no speech are free.

**Why does a video show `no_speech`?**
Speech-to-text heard only music, songs, sound effects or silence.
That row isn't charged.

**Where does the audio go?**
To Google's Gemini on Google Cloud Vertex AI, only for videos without captions and only when you turn speech-to-text on.
Nothing else leaves the scraper.

**Can it scrape a whole profile or hashtag?**
No.
Pass the video links you want.
Another scraper can collect links from a profile first.

**Why does a video show `unavailable`?**
TikTok says the video is deleted, private or under review.
The `message` field carries TikTok's own reason.

**Does it need my TikTok login?**
No.
It reads public video pages only, logged out.
Only use transcripts in ways that respect the rights of the video creators.

### Limitations

- Speech-to-text reads the first 5 minutes of a video at most, and skips photo slideshows.
- Speech-to-text does not translate. The transcript is in the language spoken.
- Public videos only. Private and deleted videos come back as `unavailable`.
- The scraper reads TikTok as a US visitor. A video TikTok hides from US viewers is likely to come back as `unavailable`.
- Transcript quality is TikTok's own. Auto captions can mishear words.

# Actor input Schema

## `videos` (type: `array`):

Video URLs, short links (vm.tiktok.com, vt.tiktok.com, tiktok.com/t/) or numeric video IDs. One per line.

## `language` (type: `string`):

ISO 639-1 code such as en, es, pt or fr. Uses captions in this language when TikTok has them, including TikTok's own machine translations. Otherwise returns the video's original captions and sets requestedLanguageFound to false.

## `includeTimestamps` (type: `boolean`):

Adds a segments array with start, end and text for each caption line. The plain transcript is always included.

## `speechToTextFallback` (type: `boolean`):

When TikTok has no captions for a video, transcribe its audio with AI speech-to-text. Each transcribed video costs $0.028, or $0.020 on Gold. Videos with no speech (music, songs, sound effects or silence) come back as no_speech and are free. Off by default.

## `maxAudioSeconds` (type: `integer`):

Speech-to-text reads at most this many seconds from the start of each video. Longer videos get a partial transcript with audioTruncated set to true.

## `maxSpeechToTextMinutes` (type: `integer`):

Total audio minutes one run may send to speech-to-text. Videos past this limit come back as free no_transcript rows. Your maximum charge per run still applies too.

## `maxConcurrency` (type: `integer`):

How many videos to fetch in parallel.

## Actor input object example

```json
{
  "videos": [
    "https://www.tiktok.com/@hankgreen1/video/7117085272323443974"
  ],
  "language": "en",
  "includeTimestamps": true,
  "speechToTextFallback": false,
  "maxAudioSeconds": 300,
  "maxSpeechToTextMinutes": 600,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `transcripts` (type: `string`):

One item per input video with status, author, description, language, the full transcript text, optional timestamped segments and basic stats. Only items with status ok are charged.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videos": [
        "https://www.tiktok.com/@hankgreen1/video/7117085272323443974"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("heyitsgautham/tiktok-transcript-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "videos": ["https://www.tiktok.com/@hankgreen1/video/7117085272323443974"] }

# Run the Actor and wait for it to finish
run = client.actor("heyitsgautham/tiktok-transcript-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videos": [
    "https://www.tiktok.com/@hankgreen1/video/7117085272323443974"
  ]
}' |
apify call heyitsgautham/tiktok-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,heyitsgautham/tiktok-transcript-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CexD9GDswvAFKHSYo/builds/zOOzyUVv01Atw7INR/openapi.json
