# TikTok Transcript Scraper — Subtitles in Every Language (`memo23/tiktok-transcript-scraper`) Actor

Extract full transcripts and subtitles from TikTok videos in every available language — auto-generated (ASR), machine-translated, and creator captions. Get plain text, timestamped segments, and video metadata. No login or cookies. Works with URLs, short links, or IDs. JSON, CSV, Excel.

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

## Pricing

from $2.00 / 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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## TikTok Transcript Scraper

Extract the **full transcript of any public TikTok video — in every language TikTok has**. One video link in, clean text out: auto-generated speech-recognition captions (ASR), TikTok's machine translations (MT), and creator-uploaded subtitles, each as its own row with a plain-text transcript, timestamped segments, and the video's engagement stats. No login, no cookies, no browser.

![How it works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-tiktok-transcript.png)

### Why Use This Scraper?

- **Every language, not just one** — a video with six caption tracks returns six rows: the original ASR plus every translation TikTok generated. Filter to just the languages you need.
- **Timestamped segments included** — each row carries a `segments` array (`start`, `end`, `text`) precise to the millisecond, ready for subtitling, clipping, or search indexing.
- **Know what you're reading** — every row is flagged `ASR`, `MT`, or `creator`, so you can separate spoken-word originals from machine translations.
- **Video metadata for free** — author, caption, publish date, duration, plays, likes, comments, shares, and saves ride along on every row at no extra charge.
- **Raw WebVTT on demand** — switch on `includeVtt` and get the original subtitle file text, ready for any video editor or player.
- **Bulk-friendly and honest** — mix URLs, share links, and bare IDs in one run. Private, deleted, and caption-less videos yield a clear error item instead of a failed run.

### Overview

This Actor takes a list of TikTok videos and returns their subtitle tracks as structured transcripts. One dataset row = one video-language combination. It works with public videos only and requires no TikTok account.

### Supported Inputs

| Input form | Example |
|---|---|
| Full video URL | `https://www.tiktok.com/@nasa/video/723987198712345678` |
| Share link | `https://vm.tiktok.com/ZMabc123/`, `https://vt.tiktok.com/xyz/` |
| Bare video ID | `723987198712345678` |

All three forms can be mixed freely in the `videos` list.

### Use Cases

- **Content repurposing** — turn spoken TikTok videos into blog posts, newsletters, or captions for other platforms.
- **AI & LLM pipelines** — feed clean video text into summarizers, RAG systems, and agents instead of transcribing audio yourself.
- **Trend & competitor research** — analyze what creators in your niche actually *say*, at scale, across languages.
- **Brand safety & compliance** — audit influencer scripts and sponsored-content disclosures in written form.
- **Accessibility & localization** — pull existing translations to bootstrap subtitles for your own edits.
- **Search & discovery** — index transcripts to make a video library searchable by spoken content.

### How It Works

1. **Resolve** — every input is normalized to a numeric video ID. Share links are followed for free before any paid lookup happens.
2. **Extract** — the video's caption tracks are collected: ASR originals, machine translations, and creator uploads, with an optional language filter.
3. **Deliver** — each track's subtitle file is downloaded and parsed into a plain-text transcript plus timestamped segments, and written as one dataset row.

### Input Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `videos` | array | — (required) | TikTok video URLs, share links, or bare numeric IDs. |
| `languages` | array | all | Optional filter, prefix-matched — `["eng"]` matches `eng-US`. One row per matching language. |
| `includeVtt` | boolean | `false` | Include the raw WebVTT subtitle text in each row (`vtt` field). |

Example input:

```json
{
    "videos": [
        "https://www.tiktok.com/@easyenglishwithfun/video/7607978879944379670",
        "https://vm.tiktok.com/ZMabc123/",
        "7673836093183151363"
    ],
    "languages": ["eng"],
    "includeVtt": false
}
```

### Output Overview

One row per video per language. A 3-language video produces 3 rows, each carrying the full video metadata plus that language's transcript. Videos that cannot be delivered (private, deleted, no captions) produce a single error item with a `message` explaining why — the run itself still succeeds.

### Output Samples

Transcript row (trimmed):

```json
{
    "videoId": "7607978879944379670",
    "videoUrl": "https://www.tiktok.com/@easyenglishwithfun/video/7607978879944379670",
    "authorUsername": "easyenglishwithfun",
    "authorNickname": "Easy English with fun",
    "authorVerified": false,
    "caption": "Simple English Conversation 💬 | A Friendly Market Dialogue for Beginners 🇺🇸 #LearnEnglish #EnglishConversation …",
    "createdAt": "2026-02-17T23:23:48.000Z",
    "durationSeconds": 72,
    "playCount": 2100000,
    "likeCount": 116800,
    "commentCount": 857,
    "shareCount": 11000,
    "saveCount": 21282,
    "originalLanguage": "eng-US",
    "language": "eng-US",
    "languageId": "2",
    "source": "ASR",
    "isAutoGenerated": true,
    "isOriginalCaption": true,
    "subtitleFormat": "webvtt",
    "subtitleUrl": "https://v16-webapp.tiktokcdn-us.com/…",
    "subtitleUrlExpiresAt": "2026-08-18T14:02:35.000Z",
    "segmentCount": 24,
    "segments": [
        { "start": 0, "end": 4.6, "text": "Are you busy right now? No, I have time." },
        { "start": 4.6, "end": 7.2, "text": "Why? Could you please help me?" },
        { "start": 7.2, "end": 9.8, "text": "Yes, of course. What do you need?" }
    ],
    "transcript": "Are you busy right now? No, I have time. Why? Could you please help me? Yes, of course. What do you need? I'm very thirsty. I need some water. …",
    "transcriptDurationSeconds": 57.819,
    "scrapedAt": "2026-08-16T14:02:41.000Z"
}
```

Error item (video without captions):

```json
{
    "video": "7582320231775816981",
    "error": "no_captions",
    "message": "No transcript available for video 7582320231775816981 — the video has no caption track…"
}
```

### Key Output Fields

| Field | Meaning |
|---|---|
| `language` / `languageId` | BCP-47-style language code (`eng-US`, `hun-HU`) and TikTok's internal ID for this track. |
| `source` | `ASR` = auto speech recognition of the original audio, `MT` = TikTok's machine translation, `creator` = uploaded by the creator. |
| `isOriginalCaption` | `true` on the track in the video's original spoken language. |
| `originalLanguage` | The video's detected original language — even on translated rows. |
| `transcript` | The full plain-text transcript for this language. |
| `segments` | Timestamped cues: `start` / `end` in seconds (millisecond precision) + `text`. |
| `transcriptDurationSeconds` | Seconds of the video actually covered by captions. |
| `subtitleUrl` / `subtitleUrlExpiresAt` | Direct WebVTT file URL and when it expires (typically ~48 h). |
| `playCount` … `saveCount` | The video's engagement stats at scrape time. |

### FAQ

**Do I need to log in or provide cookies?**
No. The Actor never touches your TikTok account and only reads public videos.

**Which videos have transcripts?**
Any video where the creator added captions or TikTok's automatic speech recognition produced them — that covers most spoken-word content. Music-only videos and photo posts have no caption track and return a clear `no_captions` error item.

**Can I get just English?**
Yes — set `"languages": ["eng"]`. The filter is prefix-matched, so `eng` catches `eng-US` and `eng-GB`. Without a filter you get every available language as separate rows.

**Is this transcription AI? How accurate is it?**
The Actor returns TikTok's own caption tracks — the same subtitles viewers see in the app. Original-language tracks (`source: "ASR"` or `"creator"`) are typically very accurate; machine translations (`"MT"`) are TikTok's automatic translations, delivered as-is and flagged so you can tell them apart.

**What happens with a private or deleted video?**
It returns an error item explaining why, and the run continues with your other videos.

**What does it cost?**
Pay per result: one charge per transcript row delivered, plus a small per-run start fee. Error items are the only rows a failed target ever costs you. No subscription.

### Support

Found a bug or need a field added? Open an issue on the Actor's **Issues** tab in Apify Console, or email <muhamed.didovic@gmail.com>.

### Additional Services

Need a custom TikTok or social-media scraper, enrichment pipeline, or a private version of this Actor? Custom builds available — reach out at <muhamed.didovic@gmail.com>.

### Explore More Scrapers

- **[YouTube Transcript Scraper](https://apify.com/memo23/youtube-transcript-scraper)** — the same clean transcripts for YouTube videos, with Whisper AI fallback
- **[Instagram Transcript Scraper](https://apify.com/memo23/instagram-transcript-scraper)** — transcripts for Instagram Reels and videos
- **[Video Transcripts MCP Server](https://apify.com/memo23/transcripts-mcp-server)** — YouTube & TikTok transcripts as an MCP tool for AI agents
- **[TikTok Comments Scraper](https://apify.com/memo23/tiktok-comments-scraper)** — every comment on any video, deduplicated, with commenter profiles
- **[TikTok Followers & Following Scraper](https://apify.com/memo23/tiktok-followers-scraper)** — followers, following, and suggested accounts with per-account stats

Browse the full portfolio: [muhamed-didovic.github.io](https://muhamed-didovic.github.io/)

### 🤖 For AI Agents & LLM Apps

**Purpose:** Return the transcript(s) of public TikTok videos in every available language, with timestamped segments.

**Minimal tested input:**

```json
{ "videos": ["https://www.tiktok.com/@easyenglishwithfun/video/7607978879944379670"], "languages": ["eng"] }
```

**Output:** array of flat objects, one per video-language. Fields: `videoId`, `videoUrl`, `authorUsername`, `authorNickname`, `authorId`, `authorVerified`, `caption`, `createdAt`, `durationSeconds`, `playCount`, `likeCount`, `commentCount`, `shareCount`, `saveCount`, `originalLanguage`, `language`, `languageId`, `source` (`ASR`|`MT`|`creator`), `isAutoGenerated`, `isOriginalCaption`, `subtitleFormat`, `variant`, `subtitleUrl`, `subtitleUrlExpiresAt`, `segmentCount`, `segments[{start,end,text}]`, `transcript`, `transcriptDurationSeconds`, `scrapedAt` (+ `vtt` when `includeVtt: true`).

**Behavior & billing:** Pay-per-event — one charge per transcript row. For LLM context economy, set `"languages"` to one language so each video returns exactly one row, and read the `transcript` field. Private/deleted/caption-less videos and unresolvable links yield one error item each (`error`, `message`) instead of failing the run. No login/cookies required.

### ⚠️ Disclaimer

This Actor accesses publicly available data on TikTok for legitimate research, accessibility, market-intelligence, and business-analysis purposes. It does not log in, bypass authentication, or access private content. Use of this Actor must comply with TikTok's Terms of Service and all applicable laws, including data-protection regulations (GDPR, CCPA, etc.). The authors are not responsible for any misuse. Users must:

- Respect rate limits and avoid overloading TikTok's infrastructure
- Not use scraped data to violate user privacy or platform terms
- Process any personal data only with a lawful basis and in compliance with their jurisdiction
- Not republish scraped content in violation of copyright

We do not store scraped data; the Actor returns it directly to your Apify dataset for your authorized use. TikTok is a trademark of ByteDance Ltd.; this Actor is not affiliated with or endorsed by TikTok or ByteDance.

### SEO Keywords

tiktok transcript scraper, tiktok transcript extractor, get tiktok transcript, tiktok video to text, tiktok subtitles download, tiktok captions scraper, tiktok subtitle extractor, tiktok speech to text, tiktok asr captions, tiktok transcript api, tiktok video transcript generator, extract tiktok captions, tiktok webvtt download, tiktok transcript multiple languages, tiktok translation captions, tiktok video text export, tiktok transcript for ai, tiktok content analysis, tiktok transcript csv, tiktok accessibility captions, video transcript scraper, apify tiktok transcript

# Actor input Schema

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

TikTok videos to extract transcripts from. Accepts full video URLs (`https://www.tiktok.com/@user/video/123…`), share links (`vm.tiktok.com/…`, `vt.tiktok.com/…`), or bare numeric video IDs — mix them freely.

## `languages` (type: `array`):

Optional language filter. Only return transcripts whose language code starts with one of these values — e.g. `eng` or `eng-US` for English, `spa` for Spanish. Leave empty to get every available language (one dataset row per language).

## `includeVtt` (type: `boolean`):

Also include the raw WebVTT subtitle file text in each row (`vtt` field) — useful if you want to feed subtitles straight into a video editor or player.

## Actor input object example

```json
{
  "videos": [
    "https://www.tiktok.com/@easyenglishwithfun/video/7607978879944379670"
  ],
  "languages": [],
  "includeVtt": false
}
```

# Actor output Schema

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

All transcript rows (one per video per language) in the default dataset.

# 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/@easyenglishwithfun/video/7607978879944379670"
    ],
    "languages": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/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/@easyenglishwithfun/video/7607978879944379670"],
    "languages": [],
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/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/@easyenglishwithfun/video/7607978879944379670"
  ],
  "languages": []
}' |
apify call memo23/tiktok-transcript-scraper --silent --output-dataset

```

## MCP server setup

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