# TikTok Transcript Scraper: Captions & Subtitles (`stanvanrooy6/tiktok-transcript-scraper`) Actor

Get TikTok transcripts as plain text and timestamped segments from video URLs, whole profiles or keywords. Uses TikTok's own captions and subtitles. No login, no API key. Pay only for videos that have a transcript.

- **URL**: https://apify.com/stanvanrooy6/tiktok-transcript-scraper.md
- **Developed by:** [Stan Van Rooy](https://apify.com/stanvanrooy6) (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

from $1.20 / 1,000 transcripts

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 Transcript Scraper: Captions, Subtitles & Timestamps 📝

The TikTok Transcript Scraper turns TikTok videos into **clean transcripts: plain text plus timestamped segments**, with **no login, no cookies and no API key**. Paste a video link, a whole profile or a keyword, click Start, and export TikTok transcripts as JSON, CSV or Excel, or pull them from the Apify API.

It reads the captions and subtitles TikTok already publishes for a video, so it is fast and cheap, and **you only pay for videos that actually have a transcript**. Videos without captions still get a row that says why, free of charge.

Built for content research, hook and script analysis, AI and RAG datasets, and searchable archives of what creators said.

### 🚀 How to get TikTok transcripts

1. Add what you want transcribed, in any mix:
   - **Video URLs** (regular links, `vm.tiktok.com` and `vt.tiktok.com` short links, or bare video IDs),
   - **Profiles** (`@handle` or profile URL) to transcribe a creator's videos,
   - **Keywords** to transcribe the videos TikTok search returns.
2. Set how many videos to read per profile and per keyword.
3. Click **Start**.

That is it. No TikTok account, no browser extension, no proxy setup on your side.

### 📊 What data do you get?

**Per video (one row each)**

- Full transcript as plain text
- Timed segments: start and end time in seconds plus the text of every caption line
- Transcript language, whether the captions are TikTok auto captions, creator captions or a translation, and every caption language available for the video
- Video ID, URL, description and upload time
- Creator handle and display name
- Duration, views, likes, comments and shares
- For videos without a transcript: `has_transcript: false` and the reason (photo post, music only, no captions, unavailable)

Every row also carries the input it came from (the URL, profile or keyword you entered), so you can group transcripts by creator or topic in your own pipeline.

### 📥 Input

| Field | Type | Notes |
|---|---|---|
| `videoUrls` | array | TikTok video URLs, short links or bare video IDs. |
| `profiles` | array | Profile URLs or `@handles`. Transcribes the profile's videos, newest first. |
| `keywords` | array | Search terms. Transcribes the videos TikTok search returns. |
| `maxVideosPerProfile` | integer | Videos per profile. `0` for every public video. Default `20`. |
| `maxVideosPerKeyword` | integer | Videos per keyword. `0` for as many as search returns. Default `20`. |
| `language` | string | `original` (default) for the spoken language, or a code such as `en`, `es` or `pt-BR` to prefer that language when TikTok has a track for it. |
| `includeSegments` | boolean | Add the timed segments array. Default `true`. |
| `proxyConfiguration` | object | Advanced. Apify residential proxies by default. |

Use any combination of the first three fields. Minimal input:

```json
{
  "videoUrls": ["https://www.tiktok.com/@tiktok/video/7681309378095353118"]
}
```

### 📤 Output

One row per video.

```json
{
  "video_id": "7681309378095353118",
  "url": "https://www.tiktok.com/@tiktok/video/7681309378095353118",
  "author_username": "tiktok",
  "author_nickname": "TikTok",
  "description": "You showed us what it means to be a Pop Girl this summer...",
  "create_time": "2026-09-03T14:03:39Z",
  "duration_sec": 67,
  "views": 258200,
  "likes": 10200,
  "comments": 1191,
  "shares": 1305,
  "has_transcript": true,
  "transcript_language": "en",
  "transcript_source": "auto",
  "transcript_text": "Hey, it's Nicole. This summer, you were the main character. You made it sound iconic...",
  "segments": [
    { "start_sec": 0.1, "end_sec": 1.3, "text": "Hey, it's Nicole." },
    { "start_sec": 1.301, "end_sec": 3.301, "text": "This summer, you were the main character." }
  ],
  "available_languages": ["en"],
  "no_transcript_reason": null,
  "input_source": "https://www.tiktok.com/@tiktok/video/7681309378095353118",
  "input_type": "video"
}
```

A video without captions looks the same with `has_transcript: false`, empty transcript fields and a `no_transcript_reason` such as "No spoken audio: the video only uses music or a sound, so TikTok has no captions for it."

#### Field descriptions

- `video_id`, `url`: The TikTok video.
- `author_username`, `author_nickname`: The creator's handle and display name.
- `description`: The creator's caption text with hashtags.
- `create_time`: Upload time in ISO 8601 (UTC).
- `duration_sec`: Video length in seconds.
- `views`, `likes`, `comments`, `shares`: Engagement counts at scrape time.
- `has_transcript`: True when a transcript was found. Only these rows are charged.
- `transcript_language`: Language code of the transcript, for example `en`.
- `transcript_source`: `auto` for TikTok auto captions, `creator` for captions the creator added, `translation` for TikTok's translation of the captions.
- `transcript_text`: The full transcript as one plain text string.
- `segments`: Timed caption lines with `start_sec`, `end_sec` and `text`.
- `available_languages`: Every caption language TikTok has for the video.
- `no_transcript_reason`: Why there is no transcript, when there is none.
- `input_source`, `input_type`: The URL, profile or keyword that led to this video, and which kind it was.

### ✨ Why this TikTok transcript scraper

- **Bulk in, transcripts out.** A single video, a creator's whole profile or every result for a keyword, all in one run.
- **Pay only for transcripts.** Videos without captions are listed with a reason and are never charged.
- **Text and timestamps.** Plain text for reading and search, timed segments for clips, subtitles and quotes.
- **No login, no cookies, no API key.** The scraper runs fully anonymous. You never hand over a TikTok account.
- **Fast.** It reads TikTok's own caption files instead of transcribing audio: 40 video URLs finish in under 10 seconds, and 120 videos from profiles and keywords in under a minute.
- **Clean exports.** JSON, CSV or Excel from the Apify Console, or fetch results from the Apify API.

### 💡 Use cases

- **Content research:** Collect every script from a creator to study hooks, structure and calls to action.
- **Marketing and brand monitoring:** What is actually said in the videos about a product, brand or keyword.
- **AI and RAG datasets:** Feed timestamped TikTok text into summarisation, sentiment, topic modelling or a vector database.
- **Journalism and compliance:** A searchable, timestamped record of claims made in videos.
- **Repurposing:** Turn TikTok videos into blog posts, captions, threads and newsletters.

### 🔌 TikTok transcript API: run it from code

Every Apify Actor is also an API. Call this scraper with the Apify client:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("stanvanrooy6/tiktok-transcript-scraper").call(run_input={
    "profiles": ["@tiktok"],
    "maxVideosPerProfile": 50,
    "includeSegments": True,
})
for video in client.dataset(run["defaultDatasetId"]).iterate_items():
    if video["has_transcript"]:
        print(video["url"], video["transcript_text"][:80])
```

The same works from JavaScript, cURL or any HTTP client. See the **API** tab above for ready-made snippets and the dataset endpoints.

### ⚠️ Limits and good to know

- Transcripts come from the captions TikTok publishes. Videos that only use music or a sound, photo posts, and some videos where TikTok did not generate captions have no transcript. In September 2026 tests on about 400 videos from creator profiles and keyword searches, 79% had one. Talking content (reviews, news, advice, tutorials) was at 90% or more; silent comedy and music only content was much lower.
- Photo posts found through profiles and keywords are skipped, so the video limits count real videos. A photo post you enter as a URL gets a row with the reason.
- Most transcripts are TikTok auto captions: accurate for clear speech, but names and slang can be misheard.
- `language` picks a caption track TikTok already has. When the video has no track in that language, you get the original transcript.
- Profiles and keywords take about 10 seconds longer to start than video URLs.
- Transient network errors are retried automatically.

### 💰 Pricing

This Actor uses **pay per event**, so there is no monthly subscription and you only pay for what you get.

- **Transcripts:** $1.50 per 1,000 videos with a transcript ($0.0015 each). $1.35 on a Silver plan, $1.20 on Gold and above.
- **Videos without captions:** free.
- **Run start:** $0.002 per GB of memory, under one cent for a default run.

Transcribing 1,000 TikTok videos costs about $1.50, and less when some of them have no captions. New Apify accounts include monthly free usage credit, which is enough to try the scraper at no cost.

### 🎯 Example inputs

**All transcripts from a creator:**

```json
{
  "profiles": ["https://www.tiktok.com/@garyvee"],
  "maxVideosPerProfile": 0
}
```

**Transcripts for a keyword, text only:**

```json
{
  "keywords": ["iphone review"],
  "maxVideosPerKeyword": 100,
  "includeSegments": false
}
```

**A batch of single videos, English when available:**

```json
{
  "videoUrls": [
    "https://www.tiktok.com/@tiktok/video/7681309378095353118",
    "https://vm.tiktok.com/ZMabcdefg/",
    "7669681716176456980"
  ],
  "language": "en"
}
```

### ❓ FAQ

#### How do I get the transcript of a TikTok video?

Paste the video URL into Video URLs and click Start. The transcript appears in the dataset as plain text and as timed segments, ready to copy or export.

#### Is there a free TikTok transcript generator?

You can run this one for free within the monthly free usage credit that comes with every new Apify account. After that it is $1.50 per 1,000 transcripts with no subscription, and videos without captions are free.

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

No. The scraper runs fully anonymous and cookie free. You never share credentials.

#### What happens if a video has no captions?

You get a row with `has_transcript: false` and the reason, for example a video that only uses music. That row is not charged.

#### Which languages are supported?

Any language TikTok captions. By default you get the transcript in the language spoken in the video. Set `language` to a code such as `en` to prefer a TikTok caption track in that language when one exists.

#### Can I get subtitles with timestamps?

Yes. Every row includes `segments` with the start and end time of each caption line in seconds, which you can turn into SRT or VTT subtitles.

#### How many videos can I transcribe from one profile?

Set `maxVideosPerProfile` to any number, or `0` for every public video. Large profiles with thousands of videos work; the scraper keeps reading until the feed ends.

#### How do I download or export TikTok transcripts?

Run the scraper, then download the dataset as JSON, CSV or Excel from the Apify Console, or read it from the Apify API and dataset endpoints.

#### Is it legal to scrape TikTok transcripts?

The scraper only collects publicly visible data that any anonymous viewer can see, and it does not log in or bypass access controls. Transcripts and descriptions can contain personal data, so handle the data in line with GDPR, CCPA and your own use case. If you are unsure, consult a lawyer.

#### Can you add a field or an option I need?

Yes. Open an issue on the Issues tab and describe what you need. I actively maintain this Actor and add requested fields and options.

### 🤝 Feedback and feature requests

I actively maintain this Actor. Found a bug or need a field? Open an issue on the Issues tab.

### 🔗 Related TikTok scrapers

All of them share the same no-login engine and output conventions.

- **[TikTok Search Scraper](https://apify.com/stanvanrooy6/tiktok-search-scraper)**: search TikTok videos by keyword in any region, with views, likes, hashtags and author data.
- **[TikTok Profile Scraper](https://apify.com/stanvanrooy6/tiktok-profile-scraper)**: follower counts, bio, links and the full post history of any TikTok user.
- **[TikTok Comments Scraper](https://apify.com/stanvanrooy6/tiktok-comments-scraper)**: export every comment and reply thread from any TikTok video, no login.
- **[TikTok Shop Scraper](https://apify.com/stanvanrooy6/tiktok-shop-scraper)**: TikTok Shop reviews, star ratings and product data from any product URL.

Typical workflow: find videos with the TikTok Search Scraper, read what was said with the TikTok Transcript Scraper, pull the audience reaction with the TikTok Comments Scraper, and profile the creators behind them with the TikTok Profile Scraper.

***

Built with ❤️ for the Apify community

# Actor input Schema

## `videoUrls` (type: `array`):

TikTok video links in any form: tiktok.com/@user/video/<id>, vm.tiktok.com or vt.tiktok.com short links, tiktok.com/t/... links, or bare numeric video IDs. One row per video.

## `profiles` (type: `array`):

TikTok profile URLs (https://www.tiktok.com/@handle) or @handles. The scraper collects the transcripts of the profile's videos, newest first.

## `keywords` (type: `array`):

Search terms. The scraper collects transcripts of the videos TikTok search returns for each keyword.

## `maxVideosPerProfile` (type: `integer`):

How many videos to read from each profile, newest first (pinned videos come first). Set to 0 for every public video.

## `maxVideosPerKeyword` (type: `integer`):

How many search results to read for each keyword. Set to 0 for as many as TikTok search returns.

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

original (default) returns the transcript in the language spoken in the video. Enter a language code such as en, es or pt-BR to prefer that language when TikTok has a caption track for it; otherwise the original transcript is returned.

## `includeSegments` (type: `boolean`):

Add the segments array with a start and end time (in seconds) for every caption line. Turn off if you only need the plain text.

## `proxyConfiguration` (type: `object`):

Proxy used for TikTok pages when a direct request is not answered. Apify residential proxies work best.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.tiktok.com/@tiktok/video/7681309378095353118"
  ],
  "profiles": [
    "@tiktok"
  ],
  "maxVideosPerProfile": 20,
  "maxVideosPerKeyword": 20,
  "language": "original",
  "includeSegments": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

All rows as JSON. Use format=csv or format=xlsx for other exports.

## `transcriptsCsv` (type: `string`):

The same rows as a CSV download.

## `dataset` (type: `string`):

The default dataset of this run.

# 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 = {
    "videoUrls": [
        "https://www.tiktok.com/@tiktok/video/7681309378095353118"
    ],
    "profiles": [
        "@tiktok"
    ],
    "maxVideosPerProfile": 20,
    "maxVideosPerKeyword": 20,
    "language": "original",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("stanvanrooy6/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 = {
    "videoUrls": ["https://www.tiktok.com/@tiktok/video/7681309378095353118"],
    "profiles": ["@tiktok"],
    "maxVideosPerProfile": 20,
    "maxVideosPerKeyword": 20,
    "language": "original",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("stanvanrooy6/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 '{
  "videoUrls": [
    "https://www.tiktok.com/@tiktok/video/7681309378095353118"
  ],
  "profiles": [
    "@tiktok"
  ],
  "maxVideosPerProfile": 20,
  "maxVideosPerKeyword": 20,
  "language": "original",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call stanvanrooy6/tiktok-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stanvanrooy6/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/4suDigqcHBjpP8sbB/builds/2fDNnhNTown2hcEsQ/openapi.json
