# Video Transcript Scraper – YouTube, X, TikTok, Facebook (`insights_data/video-transcript-scraper-youtube-x-facebook-tiktok`) Actor

Get transcripts from YouTube, X, TikTok, Facebook, Vimeo, Loom and more. Paste video, playlist or channel links and get full text, timestamped segments, title, channel, views and languages as clean JSON. Mix platforms, no account or login needed.

- **URL**: https://apify.com/insights_data/video-transcript-scraper-youtube-x-facebook-tiktok.md
- **Developed by:** [Insights Data](https://apify.com/insights_data) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

### Video Transcript Scraper — full text, segments and video data

Video Transcript Scraper takes video, playlist or channel links from YouTube, X, TikTok, Facebook, Vimeo, Dailymotion, Loom, Rumble and similar sites, and returns each video's transcript as plain text and as timestamped segments, together with the title, channel, views, likes, languages and more. You can mix platforms in one run and paste as many links as you like. Every response is structured JSON — ready to pass directly to an LLM, index into a vector store, or feed a RAG pipeline. **No account, login or cookies are needed**, because it reads the captions that videos already publish. Use it to turn video libraries into searchable text.

### Why choose this Video Transcript Scraper?

- **Bulk and mixed links.** One run can take videos, playlists, channels and `@handles` from different platforms.
- **Real-time output.** Every finished video appears in the output table straight away, so you can watch the table fill while the run goes on.
- **Separate tables per section.** Besides the transcript table you get tables for timestamped segments, caption languages, channels, your links and videos without a transcript.
- **Starts light, escalates only if needed.** The run begins without a proxy. If a platform refuses the request, it switches to a datacenter proxy, then to a residential proxy, and keeps that proxy for the rest of the run.
- **Honest about gaps.** Videos with no captions are never invented; they are listed with the reason, or kept with empty text if you turn on best effort.

### Key features

- Full transcript as one string (`text`) plus timestamped `transcript` segments with start, end and a jump link to that moment (YouTube and Vimeo).
- Choose a caption language; if it is not available the closest one is returned and `language_note` says so.
- Manual (human-written) captions are preferred over auto-generated ones, and `transcript_source` tells you which you got.
- Playlist and channel expansion with a total video limit.
- Duplicate links are removed, and `youtu.be/ID` and `watch?v=ID` count as the same video.
- Plain-language reasons for failures: private, removed, age-restricted, login required, region-locked, live, no captions, blocked.

### Supported platforms

| Platform | What to expect |
|---|---|
| YouTube | Videos, Shorts, playlists, channels and `@handles`; manual and auto captions |
| Dailymotion | Videos that carry captions |
| X, TikTok, Loom | Video details are returned; a transcript is returned when the video carries captions |
| Facebook, Vimeo, Rumble | Accepted, but these sites often refuse automated requests or ask for a login, so some videos come back as failed |

Only captions that already exist are used. The Actor does not transcribe audio.

### Input

Example input:

```json
{
    "urls": [
        "https://www.youtube.com/watch?v=vl6jn-DdafM",
        "https://www.youtube.com/@NASA/videos"
    ],
    "maxVideos": 10,
    "language": "auto",
    "bestEffort": false,
    "proxyConfiguration": { "useApifyProxy": false }
}
```

| Field | Type | What it does |
|---|---|---|
| 🎬 `urls` | array, required | Video, playlist or channel links, one per line. Platforms can be mixed. |
| 📊 `maxVideos` | integer, default 10 | Total videos for the whole run. `0` means every video found. Free plan: up to 10 videos per run. |
| 🌍 `language` | string, default `auto` | Caption language code such as `en`, `es`, `fr`. `auto` returns the video's own language. |
| 🧩 `bestEffort` | boolean, default false | Keep videos without captions in the main table, with details and an empty transcript. |
| 🌐 `proxyConfiguration` | object | Optional. Default is no proxy; the run escalates by itself if the platform refuses. |

### Output

Each video is one row in the **Transcripts** table. Example (shortened):

```json
{
    "url": "https://www.youtube.com/watch?v=vl6jn-DdafM",
    "status": "ok",
    "platform": "youtube",
    "video_id": "vl6jn-DdafM",
    "title": "We Are Going",
    "channel": "NASA",
    "channel_id": "UCLA_DiR1FfKNvjuUpBHmylQ",
    "channel_followers": 15100000,
    "published_date": "2019-05-14T20:34:54Z",
    "duration": 227,
    "duration_string": "3:47",
    "view_count": 17934893,
    "like_count": 1337804,
    "selected_language": "en",
    "transcript_source": "manual",
    "word_count": 591,
    "words_per_minute": 156,
    "text": "- [Narrator] 50 years ago we pioneered a path to the moon. The trail we blazed cut through ...",
    "transcript": [
        { "start": 2.36, "end": 5.26, "text": "- [Narrator] 50 years ago we pioneered a path to the moon.", "link": "https://www.youtube.com/watch?v=vl6jn-DdafM&t=2s" }
    ]
}
```

| Table | One row per | Main fields |
|---|---|---|
| Transcripts (default) | video | `title`, `channel`, `view_count`, `like_count`, `selected_language`, `transcript_source`, `word_count`, `text`, `transcript` |
| Transcript segments | caption segment | `segment_number`, `timestamp`, `start`, `end`, `text`, `link` |
| Caption languages | language a video offers | `language`, `type` (manual or auto), `selected` |
| Channels | channel or uploader | `channel`, `channel_url`, `channel_followers` |
| Your links | link you gave | `kind`, `videos_found`, `status`, `note` |
| Videos without a transcript | video that gave none | `status`, `error` |

A run summary (counts, timing) is also saved as `RUN_SUMMARY` in the key-value store. Fields the platform does not show, such as likes on some sites, stay `null`.

### 🚀 How to use (Apify Console)

1. Log in at [console.apify.com](https://console.apify.com) and open **Actors**.
2. Find **Video Transcript Scraper** and open it.
3. Paste your video, playlist or channel links into the first field.
4. Set the maximum number of videos and, if you want, a language.
5. Click **Start**.
6. Watch the live log: each finished video is printed with its title, length, word count and language.
7. Open the **Output** tab, switch between the tables, and export to JSON, CSV or Excel.

### 🤖 Use via API and MCP

Start the Actor from the Apify API, a schedule or an integration such as Make, n8n or Zapier, then read the dataset items. For AI agents, add the Apify MCP server with `claude mcp add --transport http apify "https://mcp.apify.com"`; the agent finds this Actor through the server's search, details and call tools.

### Best use cases

- Build a searchable archive of a channel or playlist.
- Feed transcripts into summarisation, Q\&A or RAG pipelines.
- Quote exact moments using the segment jump links.
- Compare what different creators say about a topic across platforms.
- Collect captions in several languages for translation or research.

### Frequently asked questions

**Is it legal to get transcripts?** The Actor reads public data that any visitor can see. You are responsible for following the rules of each site and the laws that apply to how you use the text.

**Why did a video come back without a transcript?** The video has no captions, is private, removed, age-restricted, region-locked or live, or the platform refused the request. The reason is in the `error` field and in the failed inputs table.

**How do I get another language?** Set `language` to a code such as `es`. If the video offers no captions in that language, the closest available one is returned and `language_note` explains it.

**Can it transcribe audio?** No. It uses captions that already exist on the video.

**What happens when a site blocks the run?** The run moves from no proxy to a datacenter proxy and then a residential proxy, retries on fresh residential IPs, and keeps the residential proxy for the rest of the run.

**Why are likes or channel followers empty?** Some platforms do not show them, so the field stays `null`.

### Support and feedback

Found a link that should work but does not? Open an issue on the Actor page with the link and the run URL.

# Actor input Schema

## `urls` (type: `array`):

One link per line. Mix platforms freely: a single video, a playlist, a channel page or an @handle (YouTube). Playlists and channels are expanded into their videos. Duplicates are removed.

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

Total videos to return for the whole run, across all links (playlists and channels count video by video). Use 0 for every video found. Free plan: up to 10 videos per run; paid plans have no run limit.

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

Caption language code, for example en, es or fr. Leave on auto to get the video's own language. If your language is not available the closest one is returned and a note says so.

## `bestEffort` (type: `boolean`):

When on, videos that have no captions are still returned with their details and an empty transcript. When off, they are listed only in the failed inputs table.

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

Starts without a proxy. If the platform refuses the request, the run switches to a datacenter proxy, then a residential proxy, and stays on it for the rest of the run.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=vl6jn-DdafM"
  ],
  "maxVideos": 10,
  "language": "auto",
  "bestEffort": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per video with the full transcript and video details.

## `fullText` (type: `string`):

Plain transcript text per video with language and word count.

## `segments` (type: `string`):

One row per timestamped caption segment, with a jump link where supported.

## `languages` (type: `string`):

One row per caption language each video offers.

## `channels` (type: `string`):

One row per channel or uploader.

## `inputs` (type: `string`):

One row per link you gave, with how many videos it returned.

## `failedInputs` (type: `string`):

Videos that gave no transcript and the reason.

## `summary` (type: `string`):

Counts and timing of the 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 = {
    "urls": [
        "https://www.youtube.com/watch?v=vl6jn-DdafM"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("insights_data/video-transcript-scraper-youtube-x-facebook-tiktok").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 = {
    "urls": ["https://www.youtube.com/watch?v=vl6jn-DdafM"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("insights_data/video-transcript-scraper-youtube-x-facebook-tiktok").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 '{
  "urls": [
    "https://www.youtube.com/watch?v=vl6jn-DdafM"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call insights_data/video-transcript-scraper-youtube-x-facebook-tiktok --silent --output-dataset

```

## MCP server setup

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

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/RefJRA1carpN3Cwgr/builds/VKzaojfItmsphSTu0/openapi.json
