# TikTok Transcript Scraper: Captions and Subtitles to Text (`oski/tiktok-transcript-scraper`) Actor

Extract transcripts from TikTok videos. Paste video links, short links or profiles and get the spoken text with timestamps, the language, and whether it is the original or a translation. Videos without captions are free. No login, no API key. Pay per transcript, $3 per 1,000.

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

## Pricing

from $2.91 / 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

Transcripts from TikTok videos: the full spoken text, timestamped segments and an SRT file in your preferred language, plus the video's caption, creator, posting date, duration and view, like, comment and share counts. Paste video links or short links, or name profiles to get their latest videos. Pay only for transcripts found: videos without speech, private or removed videos cost nothing. No login, no browser, no API key.

Other TikTok transcript actors charge for every video whether or not it had captions, or stop working when TikTok changes its page. This one reads TikTok's own caption tracks, bills only rows with text, and ends every run with a plain status line that says what came back and why.

### What you get

One row per video:

| Field | Example |
|---|---|
| `video_id`, `url` | 7691463425599261955, the video link |
| `author`, `author_name`, `author_url` | bbcnews, BBC News, profile link |
| `description`, `hashtags` | the video caption and its tags |
| `created_at`, `duration_seconds` | 2026-09-30T23:05:00Z, 64 |
| `view_count`, `like_count`, `comment_count`, `share_count` | 33200, 1414, 30, 29 |
| `status`, `message` | ok, or why there is no transcript |
| `language`, `caption_type`, `available_languages` | eng-US, auto (or manual, or translated for a machine translation), \["eng-US (auto)"] |
| `message` | why a row is free, or that a track is a machine translation of another language |
| `text`, `word_count`, `segment_count` | the transcript as one paragraph |
| `segments` | \[{start, duration, text}, ...] (on by default) |
| `srt` | subtitle file (optional) |
| `charged` | true only for rows with text |

### Use cases

- **Content research:** read what the top creators in a niche say, without watching 200 videos.
- **Repurposing:** turn a creator's latest videos into blog posts, newsletters or captions.
- **Brand and PR monitoring:** search transcripts for a product or company name.
- **Ad intelligence:** what hooks and claims competitors use in their videos.
- **Accessibility and archiving:** SRT files for every video in a campaign.
- **Datasets:** spoken text plus engagement counts for analysis.

### How to use it

1. Paste video links (or short links) one per line, or name profiles such as @bbcnews.
2. Pick your preferred languages (default English).
3. Start the run. Download as JSON, CSV or Excel, or read the dataset through the API.

### What TikTok lets us read

| Input | What you get |
|---|---|
| Video link or short link | that video, with captions when TikTok generated them |
| Profile | the latest 10 to 13 videos TikTok shows without a login |

Caption coverage depends on the content: talking-head creators, news and education are high; music, sport and visual gags often have no speech track and come back as `no_transcript` for free. In a 122-video test, 69% had an English track; for talking creators it was 85 to 100%.

### Cost

| Transcripts | Cost |
|---|---|
| 100 | about $0.30 |
| 1,000 | about $3.00 |
| 10,000 | about $30 |

A small fee per run plus a fee per transcript (the table assumes $0.003). Videos with no captions, private or removed videos, and videos TikTok refused are never charged.

### Scheduling and API

```bash
curl -X POST "https://api.apify.com/v2/acts/oski~tiktok-transcript-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"profiles": ["@hubermanlab", "@garyvee"], "languages": ["en"], "includeSrt": true}'
```

Schedule it in the Apify console to keep a running transcript archive of the accounts you follow.

### If something looks wrong

| Status line says | What it means | What to do |
|---|---|---|
| Input problem: Add at least one TikTok video link | Nothing usable in the inputs | Paste a video link or a profile such as @bbcnews |
| Skipped '...': not a TikTok video link, short link or profile | A line was not TikTok | Remove it, or put a bare creator name under Profiles |
| N videos had no captions; they were not charged | TikTok generated no speech track for them | Nothing to do; music and visual videos have none |
| TikTok shows only the latest 13 videos of @x without a login | Profile listing is limited by TikTok | Paste links for older videos |
| N videos were refused by TikTok | Both proxy tiers were refused | Run again later |
| No en captions; this is the video's deu-DE track | The video speaks another language | Add that language to Preferred languages, or keep it |

### Frequently asked questions

**Does it use speech recognition?** No. It reads the caption tracks TikTok already generated (TikTok's own ASR, or the creator's manual captions). That is why videos without a track come back empty and free.

**Can I get all videos of a profile?** Not without a login: TikTok lists the latest 10 to 13. Paste video links for the rest.

**Which languages?** Whatever tracks TikTok has for the video: usually its own automatic captions, sometimes machine translations. Codes such as en, es, pt, de, ja and zh are matched to TikTok's eng-US, spa-ES, por-PT, deu-DE, jpn-JP and cmn-Hans-CN. A translated track always says so in `caption_type` and `message`. `available_languages` lists what exists per row.

**Does it download videos?** Never. It reads the page and the caption file only.

### Related actors by the same developer

- YouTube Transcript Scraper
- Google Jobs Scraper
- Eventbrite Scraper (plus Meetup and Luma)

# Actor input Schema

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

One video per line: full links, short links (vm.tiktok.com, tiktok.com/t/...) or bare video ids. Several on one line separated by spaces or commas also work.

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

Creators whose latest videos to transcribe. TikTok lists only the latest 10 to 13 videos of a profile without a login, so this is for keeping up with accounts, not for back catalogues; paste video links for older videos.

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

In order of preference, as codes (en, de, es, pt) or TikTok codes (eng-US). When none is present the video's own caption track is returned and the row says so.

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

Cap per profile. TikTok shows at most 10 to 13 without a login; the status line says how many were listed.

## `maxVideos` (type: `integer`):

Stop after this many videos in total (0 or empty = no limit). Videos without captions are processed but never charged.

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

Adds a segments list (start, duration, text) to every transcript row.

## `includeSrt` (type: `boolean`):

Adds an srt field with the transcript as a subtitle file.

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

Apify datacenter proxy is enough (100% of pages in testing). Residential is used automatically as a fallback when a page is refused.

## `residentialFallback` (type: `boolean`):

Retry a refused video on a residential IP (about 0.1 MB a video). Turn off to never use residential proxy.

## `concurrency` (type: `integer`):

Parallel video fetches.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.tiktok.com/@hubermanlab/video/7367817160468729120",
    "https://vm.tiktok.com/ZMabc123/"
  ],
  "profiles": [
    "@bbcnews",
    "https://www.tiktok.com/@garyvee",
    "hubermanlab"
  ],
  "languages": [
    "en"
  ],
  "maxVideosPerProfile": 13,
  "includeTimestamps": true,
  "includeSrt": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "concurrency": 4
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per video: creator, caption, language, original or translated, word count, status and the transcript text.

## `allFields` (type: `string`):

Every field for each video, including timestamped segments and SRT subtitles when chosen.

# 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/@bbcnews/video/7691463425599261955",
        "https://www.tiktok.com/@bbcnews/video/7691451702133722390",
        "https://www.tiktok.com/@bbcnews/video/7691447689858321666",
        "https://www.tiktok.com/@bbcnews/video/7691443846886018326"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("oski/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/@bbcnews/video/7691463425599261955",
        "https://www.tiktok.com/@bbcnews/video/7691451702133722390",
        "https://www.tiktok.com/@bbcnews/video/7691447689858321666",
        "https://www.tiktok.com/@bbcnews/video/7691443846886018326",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("oski/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/@bbcnews/video/7691463425599261955",
    "https://www.tiktok.com/@bbcnews/video/7691451702133722390",
    "https://www.tiktok.com/@bbcnews/video/7691447689858321666",
    "https://www.tiktok.com/@bbcnews/video/7691443846886018326"
  ]
}' |
apify call oski/tiktok-transcript-scraper --silent --output-dataset

```

## MCP server setup

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