# YouTube Transcript & Subtitles API – AI, Channels, Shorts (`tubetext/youtube-transcript-fast`) Actor

Get YouTube transcripts, subtitles and captions from any video, Short, playlist or channel as clean text, timestamps or SRT. Whisper AI for videos without captions. $0.004 per transcript, failed videos are free. Built for ChatGPT, Claude, RAG and n8n.

- **URL**: https://apify.com/tubetext/youtube-transcript-fast.md
- **Developed by:** [TubeText Labs](https://apify.com/tubetext) (community)
- **Categories:** Videos, AI, Developer tools
- **Stats:** 3 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.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.
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

## YouTube Transcript & Subtitles API – AI, Channels, Shorts

> By **TubeText Labs** – see all our tools at the end of this page.

Turn YouTube videos, **whole playlists or entire channels** into clean transcripts ready for ChatGPT, Claude, RAG pipelines, content repurposing and research.

### Why this one

- 💸 **You only pay for transcripts delivered.** Videos without captions and failed videos are free.
- ⚡ **Fast and reliable** – lightweight requests with automatic retries through rotating proxies.
- 📺 **Bulk input** – paste video links, playlist links or channel links (`@handle`, `/channel/…`). Use `…/@handle/shorts` for a creator's Shorts only or `…/@handle/streams` for live replays. `youtu.be` links work too.
- 🌍 **Language choice** – pick preferred languages in order; falls back to the original auto-generated track.
- 🤖 **AI transcription for videos without captions** (optional) – turn on *AI transcription* and videos that have no captions are transcribed with Whisper AI. Billed per started minute, only when a transcript is delivered.
- 🔁 **Only new videos** – turn on *Only new videos* and scheduled runs skip everything you already got. Never pay twice for the same video.
- 🧩 **RAG chunks** – optional ~N-word chunks with start/end timestamps, ready for vector databases.
- 🧠 **AI-ready output** – plain text, timestamped text, SRT subtitles and raw segments.
- 📊 **Rich metadata** – title, channel, publish date, views, likes, category, description, thumbnail and duration.

### Input example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=aircAruvnKk",
    "https://www.youtube.com/@3blue1brown"
  ],
  "maxVideosPerSource": 20,
  "languages": ["en"]
}
```

If you leave out `maxVideosPerSource` (for example when calling the API), up to **50 videos per channel or playlist** are transcribed.

### Output example

```json
{
  "status": "ok",
  "videoId": "aircAruvnKk",
  "url": "https://www.youtube.com/watch?v=aircAruvnKk",
  "title": "But what is a neural network? | Deep learning chapter 1",
  "channelName": "3Blue1Brown",
  "durationSeconds": 1120,
  "viewCount": 24662699,
  "likeCount": 564664,
  "publishDate": "2017-10-05T08:11:25-07:00",
  "category": "Education",
  "description": "What are the neurons, why are there layers, and what is the math underlying it? ...",
  "thumbnailUrl": "https://i.ytimg.com/vi_webp/aircAruvnKk/sddefault.webp",
  "language": "en",
  "isAutoGenerated": false,
  "availableLanguages": ["ar", "en", "es", "zh"],
  "transcript": "This is a 3. It's sloppily written and rendered at an extremely low resolution of 28x28 pixels, ...",
  "timestampedText": "[00:04] This is a 3.\n[00:06] It's sloppily written ...",
  "wordCount": 3720
}
```

Turn on **Include SRT subtitles** to also get an `srt` field you can save as a `.srt` file.

Videos without captions return `"status": "no_transcript"` and are **not charged** – unless you enable AI transcription, in which case they come back with `"source": "ai"` and `aiMinutes`.

### Pricing examples

| What you run | What you pay |
|---|---|
| 1,000 videos that have captions | $4.00 (less on paid Apify plans) |
| A channel with 200 videos, 20 of them without captions, AI off | 180 × $0.004 = $0.72 |
| Same channel with AI on, the 20 caption-less videos average 3 minutes | $0.72 + 60 min × $0.006 = $1.08 |
| Videos that fail, are private/age-restricted, or have no speech | $0 |

You are charged **per transcript delivered**, never per run attempt. Set **Maximum cost per run** in the run options to cap spend.

### Use it from n8n, Make, Zapier or your code

**Easiest: one HTTP request that runs the Actor and returns the transcripts** (works in n8n *HTTP Request*, Make *HTTP*, Zapier *Webhooks*):

```
POST https://api.apify.com/v2/acts/tubetext~youtube-transcript-fast/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN
Content-Type: application/json

{ "urls": ["https://www.youtube.com/watch?v=aircAruvnKk"] }
```

The response body is the JSON array of transcripts. Put YouTube links in the `urls` array – nothing else is required.

- **n8n**: use the official *Apify* node → *Run Actor and get dataset*, Actor `tubetext/youtube-transcript-fast`, input `{"urls": ["{{ $json.videoUrl }}"]}`.
- **Make / Zapier**: use the Apify app → *Run an Actor* (wait for finish) → *Get dataset items*.
- **Google Sheets**: in Make, map `title`, `url` and `transcript` from the dataset items to a *Add a row* module.
- **Python**: `pip install apify-client`, then `client.actor("tubetext/youtube-transcript-fast").call(run_input={"urls": [...]})`.

### Transcribe videos without collecting links

Point the Actor at a source and it picks the videos for you:

- **Keyword search** – `searchQueries` (e.g. `["how to invest for beginners"]`) with `searchPublishedWithin` (hour / today / week / month / year / any) and `searchSortBy` (views / relevance / date; "views" re-sorts by actual view count).
- **Today's trending by country** – `trendingCountries` (e.g. `["us","jp","gb"]`), from daily YouTube trending lists (via kworb.net).
- **A channel's most viewed videos** – a channel link plus `channelSort: "popular"` (default `"newest"`).
- **YouTube links from another Actor's results** – `datasetId` (plus `datasetSortBy`: views or original order).

Each source is capped by `maxVideosPerSource` (default 50). Finding videos is free; each transcript is billed as usual.

### Ready-made examples

- [YouTube Channel to Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/youtube-channel-to-transcripts)
- [YouTube Playlist Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/youtube-playlist-transcripts)
- [YouTube Transcript to SRT Subtitles](https://apify.com/tubetext/youtube-transcript-fast/examples/youtube-transcript-to-srt-subtitles)
- [YouTube Shorts Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/youtube-shorts-transcripts)
- [YouTube Transcripts for ChatGPT and Claude](https://apify.com/tubetext/youtube-transcript-fast/examples/youtube-transcripts-for-chatgpt-and-claude)
- [Transcribe YouTube Videos Without Captions (AI)](https://apify.com/tubetext/youtube-transcript-fast/examples/transcribe-youtube-videos-without-captions-ai)
- [Huberman Lab Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/huberman-lab-podcast-transcripts)
- [Lex Fridman Podcast Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/lex-fridman-podcast-transcripts)
- [TED Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/ted-talks-transcripts)
- [Y Combinator Transcripts](https://apify.com/tubetext/youtube-transcript-fast/examples/y-combinator-video-transcripts)

### TubeText Labs tools

**TubeText Labs** builds 9 pay-per-result Apify Actors for video, social and e-commerce data – no login, JSON/CSV/Excel output, and ready for ChatGPT and Claude (Apify MCP), n8n, Make and Zapier. All tools: [apify.com/tubetext](https://apify.com/tubetext)

**Transcripts**

- [YouTube Transcript Scraper](https://apify.com/tubetext/youtube-transcript-fast) *(this tool)* – videos, Shorts, playlists and whole channels to text; Whisper AI when there are no captions
- [TikTok Transcript Scraper](https://apify.com/tubetext/tiktok-transcript) – TikTok captions plus Whisper AI, SRT and timestamps
- [Instagram Reels Transcript](https://apify.com/tubetext/instagram-reels-transcript) – reel links or @usernames to text with Whisper AI

**Video & ad analysis**

- [Video Breakdown AI](https://apify.com/tubetext/video-breakdown-ai) – hook analysis, shot list, cut pacing, products shown and script of any TikTok, Reel or YouTube video
- [Video Ad Analyzer](https://apify.com/tubetext/video-ad-analyzer) – competitors' YouTube video ads by brand or domain (Google Ads Transparency), torn down by AI

**Channel analytics**

- [YouTube Channel Analytics](https://apify.com/tubetext/youtube-channel-analytics) – subscribers, recent video performance, Social Blade grade, ranks and estimated earnings

**E-commerce & travel**

- [TikTok Shop Product Scraper](https://apify.com/tubetext/tiktok-shop-product-scraper) – US TikTok Shop prices, items sold, stock per SKU and shop stats
- [AliExpress Search Scraper](https://apify.com/tubetext/aliexpress-search-scraper) – AliExpress search results by keyword: price, items sold, rating, shipping, badges
- [Google Hotels Scraper](https://apify.com/tubetext/google-hotels-scraper) – hotel prices for any destination and dates, per booking site and as a 90-day price calendar

### FAQ

**Does "1,000 results" mean 1,000 transcripts?** Yes – one charge per delivered transcript (one video = one result).

**Why do some videos return `no_transcript`?** The video has no captions (common for kids' content and short clips), is private/members-only/age-restricted, or is a live replay with protected captions. You are not charged. Turn on AI transcription to transcribe caption-less videos.

**Which language do I get?** The first language in your *Preferred languages* list that the video has. If none match, the original auto-generated track is returned. `availableLanguages` lists every caption track on the video. If the track you get is a translation (e.g. you asked for `ja` on an English video), the row has `isTranslation: true` and `spokenLanguage` tells you the original language (`en`).

**Can I monitor a channel every day?** Yes – create a schedule with *Only new videos* turned on; each run only returns (and charges) new uploads. The run's status message tells you how many videos were skipped as already delivered (free).

**What if a link is wrong?** Bare @handles work (`@mkbhd`). A channel or playlist that doesn't exist returns `channel_not_found` / `playlist_not_found` right away, free. Anything that isn't a YouTube link (e.g. Vimeo) returns an `error` row instead of being skipped silently, and every transcript row includes the `input` it came from.

**Can I cap what a run costs?** Yes – set *Maximum cost per run* in the run options. The run stops cleanly when the next item would go over it: you are never charged more, and you get a clear "stopped at your limit" status message.

**What happens if a big run hits the time limit?** It stops cleanly shortly before the limit: everything finished so far is delivered, the run ends as succeeded, and the status message says how many items weren't started. Raise the run timeout, or run again with *Only new* turned on to continue where it stopped.

**Can I download just the text for many videos?** Yes – in the run's Storage tab export the dataset as CSV or JSON, or call the API with `?format=csv&fields=title,url,publishDate,transcript` to get one row per video with only those columns.

**How accurate are the transcripts?** When a video has captions, you get YouTube's own caption track word for word – in our checks the output matched YouTube's subtitles exactly, for both creator-uploaded and auto-generated tracks. Auto-generated captions can of course contain YouTube's own recognition errors.

### Use cases

- Feed transcripts into LLMs for summaries, Q\&A and knowledge bases
- Repurpose videos into blog posts, newsletters and social threads
- Research what creators and competitors say across a whole channel
- Build datasets for NLP and market research

### YouTube to text

Turn any YouTube video, Short, playlist or whole channel into plain text, timestamped segments or SRT. Videos without captions are transcribed with Whisper AI (`aiFallback`).

### YouTube Shorts transcripts

Paste Shorts links (`youtube.com/shorts/...`) or a channel's Shorts tab (`youtube.com/@handle/shorts`) and get transcripts for every Short in bulk.

### Summaries and RAG

Use `chunkWords` to get ~N-word chunks with timestamps, ready for embeddings, a vector store or an LLM summary step (n8n, Make, LangChain).

### Pricing

Pay per transcript delivered. Optional AI transcription of caption-less videos is billed per started minute of audio. Set **Maximum cost per run** to control spend – the run stops cleanly when the limit is reached.

### Notes

- Only publicly available captions are returned (creator-uploaded or YouTube auto-generated). Private, members-only and age-restricted videos are returned with `status: no_transcript` and are not charged.
- Language order matters: with `["ja", "en"]`, an English video that also has Japanese captions returns the Japanese track. Put the language you want first.
- Use the data in line with YouTube's Terms of Service and applicable laws.

# Actor input Schema

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

Video URLs or IDs, playlist URLs, or channel URLs (e.g. https://www.youtube.com/@mkbhd). Shorts and youtu.be links work too. Optional if you use search, trending or a dataset below.

## `searchQueries` (type: `array`):

YouTube search terms, e.g. 'skincare routine'. Each search takes the top videos for the time range and sort below (up to 'Max videos per source').

## `searchPublishedWithin` (type: `string`):

Only videos uploaded within this time range (YouTube's own upload-date filter).

## `searchSortBy` (type: `string`):

'Most viewed' re-sorts the results by their actual view count.

## `trendingCountries` (type: `array`):

Two-letter country codes, e.g. us, jp, de, br, in, kr, fr, gb. Takes the top of each country's daily trending list (source: kworb.net; YouTube retired its own trending page).

## `datasetId` (type: `string`):

A dataset from another Actor run that contains YouTube video links (pick it, or paste its ID via API). With 'Sort dataset by views' the most viewed come first; 'Max videos per source' limits how many are taken. Read-only access to this one dataset is requested.

## `datasetSortBy` (type: `string`):

How to pick videos from the dataset when it has more than 'Max videos per source'.

## `maxVideosPerSource` (type: `integer`):

For channel, playlist, search, trending and dataset inputs: how many videos to take from each (each transcript is billed as usual).

## `channelSort` (type: `string`):

For channel links (including /shorts and /streams tabs): take the newest videos, or the channel's most viewed ones.

## `skipAlreadyScraped` (type: `boolean`):

Remember delivered videos in your account (key-value store 'tubetext-seen-videos') and skip them on later runs. Perfect for scheduled channel monitoring – you never pay twice for the same video.

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

Language codes in order of preference (e.g. en, es, ja). For each video the first listed language that has captions is used, so put the language you want most first. If none is available, the video's original auto-generated transcript is returned.

## `preferManualCaptions` (type: `boolean`):

Use creator-uploaded captions over YouTube auto-generated ones when both exist.

## `includeTimestampedText` (type: `boolean`):

Adds a 'timestampedText' field with one \[mm:ss] line per caption.

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

Adds an 'srt' field with the transcript in SubRip (.srt) subtitle format.

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

Adds a 'segments' array with start, duration and text for each caption.

## `chunkWords` (type: `integer`):

Set e.g. 300 to add a 'chunks' array: transcript split into ~N-word blocks with start/end timestamps, never cutting a caption in half. Ready for vector databases. 0 = off.

## `aiFallback` (type: `boolean`):

When a video has no captions, download its audio and transcribe it with Whisper AI. Charged per started minute of audio, only when a transcript is delivered.

## `maxAiMinutesPerVideo` (type: `integer`):

Videos longer than this are skipped by AI transcription to keep costs predictable.

## `maxConcurrency` (type: `integer`):

How many videos to process in parallel.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=aircAruvnKk",
    "https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi"
  ],
  "searchQueries": [],
  "searchPublishedWithin": "week",
  "searchSortBy": "views",
  "trendingCountries": [],
  "datasetSortBy": "views",
  "maxVideosPerSource": 50,
  "channelSort": "newest",
  "skipAlreadyScraped": false,
  "languages": [
    "en"
  ],
  "preferManualCaptions": true,
  "includeTimestampedText": true,
  "includeSrt": false,
  "includeSegments": false,
  "chunkWords": 0,
  "aiFallback": false,
  "maxAiMinutesPerVideo": 60,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `transcripts` (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 = {
    "urls": [
        "https://www.youtube.com/watch?v=aircAruvnKk",
        "https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi"
    ],
    "searchQueries": [],
    "trendingCountries": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("tubetext/youtube-transcript-fast").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=aircAruvnKk",
        "https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi",
    ],
    "searchQueries": [],
    "trendingCountries": [],
}

# Run the Actor and wait for it to finish
run = client.actor("tubetext/youtube-transcript-fast").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=aircAruvnKk",
    "https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi"
  ],
  "searchQueries": [],
  "trendingCountries": []
}' |
apify call tubetext/youtube-transcript-fast --silent --output-dataset

```

## MCP server setup

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

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/XCn0lwrjUfsSfh1Op/builds/QilvA87FuA2hDObpW/openapi.json
