# YouTube Subtitles & Transcript Scraper API (`cliqtomedia/youtube-transcript-scraper`) Actor

Get public YouTube subtitles and full transcripts with timestamps from up to 5 video links.

- **URL**: https://apify.com/cliqtomedia/youtube-transcript-scraper.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Categories:** Videos, Developer tools, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$8.00 / 1,000 complete 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/actors/running/actors-in-store.md#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

Get public YouTube subtitles and transcripts as full text and timestamped segments.

Add up to 5 video IDs or links. The Actor gets one public subtitle track for each video. A
successful result contains the full transcript and every subtitle time segment. You pay only when
the Actor saves a complete result.

Use the Actor in Apify Console or call it through the Apify API. The same JSON result works in
apps, scripts, AI tools, search indexes, and data pipelines.

### What you get

Each successful video gives you one result with:

- the full subtitle transcript in the `text` field;
- all subtitle parts in `segments`, with start time and duration;
- the selected language and subtitle type;
- the available public subtitle tracks;
- a clear note about how the Actor chose the track;
- `complete: true` when the whole selected transcript was saved.

The Actor never cuts a successful transcript. If the full result is too large, it returns an
error instead. This error is not charged as a complete transcript.

### How to use it

1. Add 1 to 5 YouTube video IDs or links.
2. Choose the languages to try, such as `en`, `es`, or `de`.
3. Choose manual or auto-generated subtitles.
4. Start the Actor.
5. Open **Subtitle and transcript results** to get the text and time segments.

The Actor accepts normal video links, `youtu.be` links, Shorts links, live links, and raw
11-character video IDs. It does not accept channel, playlist, or search links.

#### Use it as an API

Send the same input JSON through the Apify API. After the run, read the subtitle and transcript
rows from the default Dataset. Each row has a stable status, video ID, text, and time segments.

#### Example input

```json
{
  "videoUrls": [
    "M7lc1UVf-VE",
    "https://youtu.be/dQw4w9WgXcQ"
  ],
  "preferredLanguages": ["en", "de"],
  "languageFallback": "FIRST_AVAILABLE",
  "captionPreference": "MANUAL_FIRST"
}
```

### Language settings

`preferredLanguages` is the list of languages to try. The Actor checks the list from left to
right. The default is English (`en`).

`languageFallback` tells the Actor what to do when an exact language is missing:

- `NONE`: return an error;
- `BASE_LANGUAGE`: try a close language code, such as `en` for `en-US`;
- `FIRST_AVAILABLE`: use the first allowed subtitle track.

`captionPreference` chooses manual or auto-generated subtitles. The default is
`MANUAL_FIRST`. You can also allow only one subtitle type.

`translateTo` asks YouTube for a translation that the selected track offers. This is not AI
translation. Leave the field out when you do not need translation.

### Example output

This short synthetic example shows the main fields:

```json
{
  "status": "SUCCEEDED",
  "complete": true,
  "videoId": "abcdefghijk",
  "track": {
    "effectiveLanguageCode": "en",
    "sourceIsGenerated": false,
    "isTranslated": false
  },
  "segments": [
    {
      "sequence": 0,
      "text": "Synthetic first caption.",
      "startSeconds": 0,
      "durationSeconds": 1.5
    },
    {
      "sequence": 1,
      "text": "Synthetic second caption.",
      "startSeconds": 1.5,
      "durationSeconds": 2
    }
  ],
  "text": "Synthetic first caption. Synthetic second caption."
}
```

The JSON export keeps every field and every segment. The table view shows the main fields for a
quick check.

### Pricing

You pay for each video that ends with a complete saved transcript. The event name is
`transcript_succeeded`. Videos with no available subtitles and other error results do not use this
event. Check the price box on the Actor page for the current price.

The Actor uses Apify Residential proxy for public YouTube requests. There is no separate Actor
event for proxy traffic. Long transcripts can use more proxy data and take more time, but one
complete video still counts as one result.

Use the run charge limit if you need a hard spending limit. When the limit is reached, the Actor
stops new work and lists videos it did not process in the run summary.

### Limits

- You can add up to 5 videos in one run.
- The Actor returns one selected subtitle track for each unique video.
- A transcript can contain up to 20,000 segments and 2,000,000 text characters.
- One saved JSON result must be smaller than 4 MiB.
- A run can take up to 10 minutes.
- Repeated video IDs are processed once and keep their input positions.

Not every YouTube video has public subtitles. The Actor does not create subtitles from audio. It
cannot get private, paid, members-only, age-restricted, or geo-restricted content. A finished live
video works only after YouTube shows a normal public subtitle track.

### Complete results and errors

A successful result always has `status: SUCCEEDED` and `complete: true`. It contains all subtitle
segments returned for the selected track. A successful result is never cut or saved as a partial
transcript.

When the Actor cannot save a complete transcript, it returns a clear error row. Common codes are:

| What happened | Code |
| --- | --- |
| YouTube has no public subtitle track | `CAPTIONS_NOT_AVAILABLE` |
| The video is not available | `VIDEO_UNAVAILABLE` |
| The selected language is missing | `LANGUAGE_NOT_AVAILABLE` |
| The requested translation is missing | `TRANSLATION_NOT_AVAILABLE` |
| YouTube blocked the request | `REQUEST_BLOCKED` |
| The proxy connection failed | `PROXY_ERROR` |
| YouTube changed the transcript format | `SOURCE_CHANGED` |
| The full result is too large | `TRANSCRIPT_OVERSIZE` |

Open **Run summary** to see how many videos succeeded, failed, or were not processed. The run can
finish on Apify even when one video returns an error, so always check the result rows.

### Privacy and safe use

Inputs and outputs stay in your Apify run storage. The Actor does not send a copy to the creator
or to an analytics service. It does not use your YouTube account, cookies, OAuth, or API key.

Delete the run data in Apify when you no longer need it. Do not send passwords, cookies, proxy
links, signed URLs, or full transcripts in a support request.

Use the Actor only for content you may access and use. Public access does not give you copyright
or reuse rights. Do not use the Actor to bypass access controls, watch people, infer sensitive
traits, or share content unlawfully.

### Troubleshooting

#### The input is not accepted

Check that each value is a video ID or a supported YouTube video link. Remove playlist, channel,
search, embed, and non-YouTube links. A run can contain no more than 5 values.

#### The result says subtitles are not available

Open the video on YouTube and check whether a public subtitle track exists. Some public videos have
no subtitles. The Actor does not create new text from audio.

#### The requested language is not available

Try another code in `preferredLanguages`. You can also use `FIRST_AVAILABLE`. Check
`availableTracks` in the error result to see the languages YouTube offered.

#### The result shows a proxy or block error

Try the run one more time later. YouTube can block or challenge public requests. If the problem
continues, send the run ID and the error code to support.

#### The result is too large

The Actor does not cut the transcript. It returns `TRANSCRIPT_OVERSIZE` and does not charge the
complete-transcript event. Use a shorter video or contact support with the run ID.

### FAQ

#### Does this work with every YouTube video?

No. YouTube must offer a public subtitle track for the video.

#### Does a successful result contain the full transcript?

Yes. It contains every segment returned for the selected track. If the full result cannot be
saved, the Actor returns an error instead of a cut transcript.

#### Can I add a playlist or channel?

No. Add up to 5 direct video IDs or links.

#### Can the Actor make subtitles from audio?

No. It gets subtitles that YouTube already makes public. It does not download audio or use speech
recognition.

#### Why does the Actor use Residential proxy?

Direct cloud requests are often blocked by YouTube. Residential proxy worked in repeated cloud
tests for this Actor. It is used only to request public subtitles.

#### What do I pay for?

You pay for each complete transcript saved to the results. Error rows are not charged as complete
transcripts. The Actor does not charge per segment or per proxy byte.

### Need help?

Send the Apify run ID and the error code. You can also include the counts from **Run summary**.
Never send cookies, passwords, proxy links, signed URLs, raw page data, or a full transcript.

### Important notice

This is an independent Actor. It is not made, approved, or supported by YouTube or Google. It
uses public YouTube pages, not an official transcript API. YouTube may limit automated access.

You are responsible for your inputs and use of the results. Follow the law, YouTube's terms,
copyright rules, privacy rules, and access limits. This notice is not legal advice.

# Actor input Schema

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

Add 1 to 5 video IDs or links to get available public subtitles and transcripts. Normal videos, youtu.be links, Shorts, and live links are accepted.

## `preferredLanguages` (type: `array`):

Add language codes such as en, es, or de. The Actor tries them from top to bottom.

## `languageFallback` (type: `string`):

Stop, try a close base language, or use the first allowed subtitle track.

## `captionPreference` (type: `string`):

Choose manual subtitles, auto-generated subtitles, or the type to try first.

## `translateTo` (type: `string`):

Optional language code for translated subtitles offered by YouTube. Leave this field empty for no translation. This is not AI translation.

## Actor input object example

```json
{
  "videoUrls": [
    "M7lc1UVf-VE"
  ],
  "preferredLanguages": [
    "en"
  ],
  "languageFallback": "FIRST_AVAILABLE",
  "captionPreference": "MANUAL_FIRST"
}
```

# Actor output Schema

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

One complete subtitle transcript or clear error for each unique video. Invalid inputs also have an error row.

## `runSummary` (type: `string`):

See how many videos succeeded, failed, or were not processed. It also shows request and charge totals.

# 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": [
        "M7lc1UVf-VE"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/youtube-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": ["M7lc1UVf-VE"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/youtube-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": [
    "M7lc1UVf-VE"
  ]
}' |
apify call cliqtomedia/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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