# TikTok Transcript Scraper - Captions, Views & Likes (`scrapewise/tiktok-transcript`) Actor

Get the transcript of any TikTok video from its link or id: TikTok's own captions as plain text, timestamped segments, SRT or VTT, in any available language. Views, likes, comments, shares, saves, date, music, hashtags and author in the same row. No captions = free. US$ 0.80 per 1,000.

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

## Pricing

from $0.68 / 1,000 transcript delivereds

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 as text, SRT or VTT, with views, likes and author

Get the **transcript of any public TikTok video** from its link or id: the captions TikTok itself generated
(speech-to-text) or machine-translated, as **plain text**, **timestamped segments**, **SRT** or **WebVTT**, in the
language you ask for or in every language available. **No account, no cookies, no browser.**

Each row also carries the video's **views, likes, comments, shares, saves, publish date, duration, caption,
hashtags, music and public author data** (handle, display name, verified badge, followers), at no extra cost.

Built for AI and RAG pipelines, content repurposing, trend and competitor research, subtitle workflows and
social listening on TikTok.

**US$ 0.80 per 1,000 transcripts. No start fee, no monthly fee. Videos without captions, deleted or private
videos, invalid links and duplicates are free.**

### At a glance

- **Price per 1,000 videos, Free plan:** US$ 0.80
- **Charged when the video has no captions:** No
- **Transcript as plain text:** Yes
- **Timestamped segments, SRT, VTT:** All three
- **Choose the language / every language:** Yes / Yes
- **Short links (vt.tiktok.com, vm.tiktok.com) and bare ids:** Yes
- **Views, likes, comments, shares, saves in the same row:** Yes
- **Music, hashtags, duration, author:** Yes
- **Transcribes videos that have no TikTok captions:** No (see Limitations)

### One real row

From a cloud test run on 2026-09-28 (empty input, which uses a National Geographic video). `coverUrl` and the
long transcript are shortened here:

```json
{
  "id": "7549930445127896333",
  "url": "https://www.tiktok.com/@natgeo/video/7549930445127896333",
  "language": "en",
  "languageCode": "eng-US",
  "source": "ASR",
  "isAutoGenerated": true,
  "isMachineTranslated": false,
  "transcript": "Digging a hole to the other side of the world. Let me show you where you'll end up. [...] Where's your antipode? Let us know.",
  "wordCount": 251,
  "requestedLanguageFound": null,
  "availableLanguages": [{"language": "en", "languageCode": "eng-US", "source": "ASR"}],
  "caption": "Ever wondered where you'd end up if you started digging a hole through the Earth? [...]",
  "hashtags": [],
  "createTime": "2025-09-14T13:07:07Z",
  "timestamp": 1757855227,
  "durationSeconds": 74,
  "playCount": 1400000,
  "likeCount": 98900,
  "commentCount": 710,
  "shareCount": 2353,
  "saveCount": 13661,
  "repostCount": 0,
  "textLanguage": "en",
  "locationCreated": "BO",
  "isAd": false,
  "coverUrl": "https://p16-common-sign.tiktokcdn-us.com/...",
  "musicMeta": {"id": "7549930669510609677", "title": "original sound", "author": "National Geographic",
                "album": null, "isOriginalSound": true},
  "authorMeta": {"uniqueId": "natgeo", "nickname": "National Geographic", "verified": true,
                 "url": "https://www.tiktok.com/@natgeo", "followers": 9600000, "following": 62,
                 "totalLikes": 54800000, "videoCount": 1516},
  "sourceUrl": "https://www.tiktok.com/@natgeo/video/7549930445127896333",
  "scrapedAt": "2026-09-29T00:16:29Z",
  "error": null,
  "errorCode": null
}
```

With `includeSegments` each row adds `segments`: `[{"start": 0.46, "end": 2.3, "duration": 1.84, "text":
"Digging a hole to the other side of the world."}, ...]` (seconds). With `subtitleFormats` it adds `srt` and/or
`vtt` with the whole file. `source` is `ASR` (TikTok's speech-to-text in the spoken language) or `MT` (TikTok's
machine translation of it). `locationCreated` is the country code TikTok records for the post.

### Input

Every field is optional. An empty input returns the transcripts of two public videos from the National Geographic
and BBC News accounts.

```json
{
  "videos": [
    "https://www.tiktok.com/@natgeo/video/7549930445127896333",
    "https://vt.tiktok.com/XXXXXXXXX/",
    "7652791912868482326"
  ],
  "language": "en",
  "includeSegments": true,
  "subtitleFormats": ["srt"]
}
```

| Field | What it does |
|---|---|
| `videos` | Video links (`tiktok.com/@handle/video/<id>`, also with `?lang=` and other parameters), photo post links, short share links (`vt.tiktok.com/...`, `vm.tiktok.com/...`, `tiktok.com/t/...`) or numeric video ids. |
| `language` | Preferred language: `en`, `es`, `pt`, `pt-BR`, `fr`, `eng-US`... If the video has no caption in it, you get the original-language caption, then the first one available; `requestedLanguageFound` says which case happened. |
| `includeAllLanguages` | Adds `transcripts`: every caption TikTok has for the video (original and its translations), each with text and the segments or files you chose. |
| `includeSegments` | Adds `segments` with `start`, `end`, `duration` and `text`. |
| `subtitleFormats` | `srt` and/or `vtt`: adds ready-to-use subtitle files as text fields. |
| `maxItems` | Stop after this many transcripts (empty or 0 = no limit). |
| `postURLs`, `startUrls` | Same as `videos`, with the field names other TikTok transcript scrapers use, so you can switch without changing your integration. `languages` and `targetLanguage` are also read as the preferred language. |

### Price

- **US$ 0.80 per 1,000 transcripts** (US$ 0.0008 each). One charge per video, whatever the number of languages,
  segments or files you ask for. No fee per run.
- Never charged: videos without captions, deleted, private or ad-only videos, invalid links, blocked requests and
  duplicates.
- Examples: 100 videos with captions = US$ 0.08. 10,000 = US$ 8.00.

You can set a maximum cost per run in Apify: the Actor stops when the limit is reached and keeps what it saved.

### Errors you may see

Every error is a row with `id`, `url`, `sourceUrl`, `error` and `errorCode`, and is never charged:

| errorCode | Meaning |
|---|---|
| `NO_CAPTIONS` | TikTok has no captions for this video: no speech (music-only clips are common), captions turned off, or a photo post. |
| `VIDEO_NOT_FOUND` | The video does not exist, was deleted, is an ad-only post, or the short link expired. |
| `PRIVATE_VIDEO` | The video is private. |
| `INVALID_URL` | Not a TikTok video link or id (profile and search links are not supported). |
| `INVALID_INPUT` | A field has a wrong value (the message says which). |
| `BLOCKED` | TikTok did not answer after several attempts; run again. |
| `NOT_REACHED` | The run timeout arrived before this video. |

### Good to know

- In our tests 23 of 39 existing videos from brand and news accounts had captions (59%). Talking videos almost
  always have them; music, dance and silent clips usually do not. You pay only for the ones that do.
- 41 videos took 53 seconds in one cloud run. Each video is one page request plus one small subtitle file.
- The Actor uses Apify's datacenter proxy with a fresh IP per video and, only if TikTok refuses it several times,
  a residential IP for that request. You pay only the per-transcript price above.
- Public author data only: handle, display name, verified badge, followers, following, total likes and video
  count. The author's bio, email, phone and links to other networks are **never** collected, and any email
  address, phone number or WhatsApp/Telegram link written in a caption or spoken in a transcript is replaced by
  `[contact removed]`.

### Limitations

- **Only captions TikTok generated.** The Actor returns the captions TikTok itself created (auto-generated
  speech-to-text and its machine translations). It does not run its own speech recognition, so videos without
  TikTok captions come back as `NO_CAPTIONS` (free).
- **No search, no profiles, no hashtags.** Give it video links or ids; it does not list the videos of a profile,
  a hashtag or a keyword search.
- Auto-generated captions can misspell names and brands, exactly as they appear in the TikTok app.
- No video download (MP4) and no comments.

### FAQ

**Do I need a TikTok account or cookies?** No. Everything comes from TikTok's public video pages.

**Which language will I get?** With `language` empty, the original spoken language. With `language` set, that
language if TikTok has it (often as a machine translation, `source: "MT"`), otherwise the original. Turn on
`includeAllLanguages` to get all of them in one row.

**Can I use it from n8n, Make, Zapier or my own code?** Yes, like any Apify Actor: call it through the API with a
list of links and read the dataset in JSON, CSV or Excel. Field names follow other TikTok transcript scrapers
(`videos`, `postURLs`, `transcript`), so switching is usually a one-line change.

**How do I get the transcripts of all videos of a creator?** Collect the video links first (for example with a
TikTok profile scraper) and pass them in `videos`.

**Something broke or a field is missing?** Open an issue on the Actor page. Issues are answered within a day.

### Changelog

- **0.1 (28 Sep 2026):** first version. Video links, short links and ids; preferred language or all languages;
  plain text, segments, SRT and VTT; views, likes, comments, shares, saves, date, duration, music, hashtags and
  public author data in the same row; videos without captions are free.

# Actor input Schema

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

One per line: video link (https://www.tiktok.com/@natgeo/video/7549930445127896333), short share link (https://vt.tiktok.com/..., https://vm.tiktok.com/..., https://www.tiktok.com/t/...) or the numeric video id. Photo posts and links with ?lang= or other parameters also work. Profile and search links are not supported.

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

Language code of the transcript to return (en, es, pt, pt-BR, fr, eng-US...). If the video has no caption in this language, you get the original-language caption (auto-generated by TikTok), then the first one available; 'requestedLanguageFound' tells you which case happened. Empty = original language.

## `includeAllLanguages` (type: `boolean`):

Adds a 'transcripts' array with every caption TikTok has for the video (original plus its machine translations), each with language, source, text and the segments or files chosen below. Same price per video.

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

Adds a 'segments' array with start, end, duration (seconds) and text for each caption line.

## `subtitleFormats` (type: `array`):

Adds ready-to-use 'srt' and/or 'vtt' fields with the full subtitle file. Same price.

## `maxItems` (type: `integer`):

Stop after this many transcripts are delivered. Empty or 0 = no limit. You pay only per transcript delivered; videos without captions do not count.

## `postURLs` (type: `array`):

Same as 'TikTok videos'. Field name used by other TikTok transcript scrapers, so you can switch without changing your integration. Merged with the list above.

## `startUrls` (type: `array`):

Same as 'TikTok videos', in the Apify start URLs format. Merged with the list above.

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

Apify datacenter proxy is the default and works for TikTok video pages. Each video uses a fresh IP; failed requests are retried on a new one.

## Actor input object example

```json
{
  "videos": [
    "https://www.tiktok.com/@natgeo/video/7549930445127896333",
    "https://www.tiktok.com/@bbcnews/video/7652791912868482326"
  ],
  "includeSegments": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (type: `string`):

No description

# 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/@natgeo/video/7549930445127896333",
        "https://www.tiktok.com/@bbcnews/video/7652791912868482326"
    ],
    "includeSegments": true,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/tiktok-transcript").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/@natgeo/video/7549930445127896333",
        "https://www.tiktok.com/@bbcnews/video/7652791912868482326",
    ],
    "includeSegments": True,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/tiktok-transcript").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/@natgeo/video/7549930445127896333",
    "https://www.tiktok.com/@bbcnews/video/7652791912868482326"
  ],
  "includeSegments": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/tiktok-transcript --silent --output-dataset

```

## MCP server setup

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

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/MzyQVwH8M2SXN7n1h/builds/YwtJ8hhaJ3bCgsoPu/openapi.json
