← ArchiveTutorial

How to Get YouTube Transcripts for RAG and LLM Apps (2026 Guide)

Neon Innovation Lab AI

Architect

Neon Innovation Lab AI

Deployed

2026-10-15

Latency

4 min read

How to Get YouTube Transcripts for RAG and LLM Apps (2026 Guide)

YouTube is one of the largest sources of spoken knowledge on the internet, and transcripts turn it into text that language models can search, summarize and cite. Getting those transcripts reliably is harder than it looks. This guide covers the options, a working approach for videos, playlists and entire channels, how to chunk transcripts for retrieval-augmented generation (RAG), and what it costs.

Why YouTube transcripts are harder than they look

  • The official YouTube Data API does not hand out other people's captions. Downloading a caption track requires OAuth permission from the video owner, so it only works for your own channel.
  • Open-source caption libraries work from your laptop and fail in the cloud. YouTube answers requests from data-center IP addresses with a "sign in to confirm you're not a bot" check, so a script that works locally often returns nothing once deployed.
  • Caption availability varies. Some videos have manually written captions, many only have auto-generated ones, and some have none. Your pipeline needs to treat "no captions" as a normal outcome, not an error.

What a reliable pipeline needs

  1. Residential or mobile IPs, rotated, so requests look like ordinary viewers.
  2. The same IP for the player request and the caption download. In our own testing, caption downloads from a different IP than the one that fetched the player data were rejected with HTTP 429.
  3. Retries with a fresh IP, plus a slower second pass for videos that were throttled.
  4. A clear per-video status: delivered, no captions, unavailable, or error.

Option: the YouTube Transcript Scraper on Apify

We built the YouTube Transcript Scraper to do exactly that. You give it video links, playlists, channel URLs or @handles; it returns one row per video with the transcript text, optional timestamped segments, metadata (title, channel, publish date, views, length), and optional RAG chunks. You are charged only for transcripts actually delivered.

In our own test of 150 videos across six channels, it delivered 145 transcripts, correctly reported 5 videos as having no captions, and returned no errors, in about two and a half minutes. (Your results depend on the videos you choose.)

Python

from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("neon_innovation_lab/youtube-transcript-scraper").call(run_input={
    "urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ", "@fireship"],
    "languages": ["en"],
    "maxVideosPerSource": 20,
    "chunkSeconds": 60,        # also return ~60 second chunks for embeddings
    "includeSegments": False,  # skip per-line timestamps to keep rows small
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["status"] == "ok":
        print(row["title"], row["wordCount"], "words")

Node.js

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('neon_innovation_lab/youtube-transcript-scraper').call({
  urls: ['https://www.youtube.com/playlist?list=PLFgquLnL59alCl_2TQvOiD5Vgm1hCaGSI'],
  maxVideosPerSource: 10,
  chunkSeconds: 60,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter(i => i.status === 'ok').length, 'transcripts');

Chunking transcripts for RAG

Embedding a whole hour-long transcript as one vector loses detail. Splitting it into 45 to 90 second chunks, each keeping its start time, lets retrieval point the user to the exact moment in the video. Set chunkSeconds and each row includes a chunks array of { start, end, text }:

Advertisement
docs = []
for row in rows:
    for ch in row.get("chunks", []):
        docs.append({
            "text": ch["text"],
            "metadata": {
                "video": row["title"],
                "url": f'{row["url"]}&t={int(ch["start"])}s',  # deep link to the moment
                "channel": row["channelName"],
            },
        })

Store docs in your vector database of choice. Because each chunk carries a time-stamped link, answers can cite the exact point in the video.

Languages and translation

Pass languages in order of preference, for example ["en", "es"]. The scraper prefers manually written captions over auto-generated ones. If the video does not offer your language but allows translation, captions are auto-translated into your first language and flagged with isTranslation: true, so you can treat machine translations with appropriate caution.

What it costs

The Actor is pay per event: $0.006 per transcript delivered (about $6 per 1,000). Videos without captions, private videos and failures are not charged. A run of 100 videos costs roughly $0.60 when all have captions. You can set a maximum cost per run in the Apify console.

Limits worth knowing

  • Only videos that have captions can return a transcript, and auto-generated captions contain errors, especially for names, jargon and music.
  • Private, deleted, age-restricted and members-only videos are reported as unavailable.
  • Respect YouTube's terms of service and the rights of content owners when you store or republish transcripts.

Next step: the video metadata

If you also want titles, view counts, likes, publish dates and subscriber counts for search results or entire channels, see the companion YouTube Channel & Video Scraper. Together they give you what was said and how the video performed.

Advertisement
Active Directory

2026 Reference
Hardware Audit

Access the definitive directory of verified AI hardware, edge compute, and agentic tools.

Lab Intelligence Feed

Unlock the 2026 Tech Audit Report

Get our exclusive 42-page PDF report analyzing the best screenless cameras, productivity gear, and AI tools for 2026. Enter your email to receive it instantly.

No spam. Unsubscribe anytime.

Powered by GetResponse