To use YouTube transcripts for RAG, fetch each transcript with timestamps, cut it into short windows and store every chunk with the video's metadata and a link to the second it starts. With Scavio's YouTube API that is three calls: /api/v1/youtube/channel/videos lists a channel's uploads 30 at a time, /api/v1/youtube/video returns the title, channel and publish date for each, and /api/v1/youtube/transcript with "format": "srt" returns the timed transcript in one synchronous call. A transcript costs 5 credits, the other two 1 credit each.
YouTube's own Data API only downloads captions for videos you have permission to edit, so it cannot feed a knowledge base built from other people's channels. The calls below were made on October 27, 2026, and every response shown is captured, with long fields trimmed.
Step 1: List the videos you want to index
curl -s https://api.scavio.dev/api/v1/youtube/channel/videos \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"channel_id": "@IBMTechnology"}'channel_id takes a channel id, an @handle or a channel URL. For @IBMTechnology this returned channel UCKWaEZ-_VweaEx1j62do_vQ, 30 uploads and has_more: true with a next_cursor for the next page. One row, as captured (thumbnail query string trimmed):
{
"video_id": "615-yWyS1n0",
"title": "What Is LLM Inference? How AI Models Generate Responses",
"url": "https://www.youtube.com/watch?v=615-yWyS1n0",
"thumbnail": "https://i.ytimg.com/vi/615-yWyS1n0/hq720.jpg",
"duration_text": "7:46",
"view_count": 96000,
"published_time": "4 days ago",
"is_live": false
}To index a topic rather than a channel, /api/v1/youtube/search with {"search": "retrieval augmented generation explained", "type": "video"} returned 20 videos a page for 2 credits.
Step 2: Get the metadata you store with each chunk
curl -s https://api.scavio.dev/api/v1/youtube/video \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"video_id": "T-D1OfcDW1M"}'{
"video_id": "T-D1OfcDW1M",
"title": "What is Retrieval-Augmented Generation (RAG)?",
"author": "IBM Technology",
"channel_id": "UCKWaEZ-_VweaEx1j62do_vQ",
"published_at": "2023-08-23T04:00:32-07:00",
"length_seconds": 395,
"view_count": 2075642,
"keywords": ["IBM", "IBM Cloud", "AI", "Artificial Intelligence", "LLM"],
"playability_status": "OK",
"captions": [{ "language_code": "en", "language_name": "English" }]
}published_at lets your retriever prefer recent videos, author and title make citations readable, and captions (each track also has a url; that and the 13-item keywords list are trimmed here) tells you which languages exist before you ask for one.
Step 3: Fetch the transcript with timestamps
curl -s https://api.scavio.dev/api/v1/youtube/transcript \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"video_id": "T-D1OfcDW1M", "format": "srt"}'The response holds video_id, language_code, language_name, format and content. For this 6-minute-36-second video, content was 92 SRT cues, starting:
1
00:00:00,060 --> 00:00:02,632
Large language models. They are everywhere.
2
00:00:02,632 --> 00:00:05,267
They get some things amazingly right
3
00:00:05,267 --> 00:00:07,741
and other things very interestingly wrong.
Leave out format for plain text. Length does not change the call: the 2-hour-33-minute freeCodeCamp course "Learn RAG From Scratch" came back as 27,073 words in 2.6 seconds, and across 19 English videos the median call took 2.1 seconds.
Step 4: Handle videos without your language
Not every video has an English track. Asking for one on a Hindi-only lecture returned:
{
"video_id": "Ty8gcCKuwNI",
"language_code": "en",
"language_name": "English",
"format": null,
"content": null,
"available_languages": ["hi"],
"message": "No English transcript for this video. Available languages: hi."
}Retry with "language": "hi" and the transcript comes back (3,771 words here). The first call is still billed, so if you index many languages, read captions from step 2 first and request a language the video has. In our 20-video sample, 19 had English and 1 did not.
Step 5: Chunk by time and keep the timestamp
Sixty-second windows keep chunks small and give each one a start time you can link to:
def parse_srt(srt):
cues = []
for block in srt.strip().split("\n\n"):
lines = block.splitlines()
if len(lines) < 3:
continue
h, m, s = lines[1].split(" --> ")[0].replace(",", ".").split(":")
cues.append((int(h) * 3600 + int(m) * 60 + float(s), " ".join(lines[2:])))
return cues
def chunk(cues, video_id, window=60):
chunks, cur, t0 = [], [], None
for start, text in cues:
if t0 is None:
t0 = start
if start - t0 >= window and cur:
chunks.append({"start": int(t0), "text": " ".join(cur),
"url": f"https://www.youtube.com/watch?v={video_id}&t={int(t0)}s"})
cur, t0 = [], start
cur.append(text)
if cur:
chunks.append({"start": int(t0), "text": " ".join(cur),
"url": f"https://www.youtube.com/watch?v={video_id}&t={int(t0)}s"})
return chunksRun on the captured SRT above, this gave 7 chunks starting at 0, 60, 123, 185, 248, 310 and 372 seconds, of 199 to 229 tokens each plus a 49-token tail (o200k_base tokenizer). The second chunk starts "and the article said that it was Jupiter and 88 moons" and links to https://www.youtube.com/watch?v=T-D1OfcDW1M&t=60s.
Step 6: Embed, store and cite
Store each chunk with the metadata from step 2: video_id, title, author, published_at, start and url. Embed the text with the model you already use and write it to your vector store. When the retriever returns a chunk, the answer can cite "IBM Technology, What is Retrieval-Augmented Generation (RAG)?, at 1:00" with a link that opens the video at that second.
Plan the size before you embed. In our sample the median was 196 tokens per minute of video, so a 10-minute video is about 2,000 tokens and 7.2 hours of video was 83,000. For new uploads, re-run step 1 on a schedule and fetch transcripts only for video ids you have not stored.
All 17 YouTube endpoints
| Endpoint | What it returns | Credits |
|---|---|---|
/api/v1/youtube/transcript | Transcript as plain text or timed SRT | 5 |
/api/v1/youtube/video | Title, channel, publish date, length, views, keywords, caption tracks | 1 |
/api/v1/youtube/search | Videos, Shorts, channels and playlists for a query | 2 |
/api/v1/youtube/shorts | Shorts search | 2 |
/api/v1/youtube/suggestions | Search autocomplete | 1 |
/api/v1/youtube/comments | Comment threads on a video | 1 |
/api/v1/youtube/comments/replies | Replies under a comment | 1 |
/api/v1/youtube/related | Related videos | 1 |
/api/v1/youtube/channel | Channel profile | 1 |
/api/v1/youtube/channel/videos | A channel's uploads, 30 a page | 1 |
/api/v1/youtube/channel/shorts | A channel's Shorts | 1 |
/api/v1/youtube/channel/community | A channel's community posts | 1 |
/api/v1/youtube/channel/search | Channel search | 1 |
/api/v1/youtube/channel/resolve | @handle or URL to channel id | 1 |
/api/v1/youtube/community/post | One community post | 1 |
/api/v1/youtube/community/post/comments | Comments on a community post | 1 |
/api/v1/youtube/streams | Stream URLs for a video | 3 |
Indexing a 500-video channel is 17 list pages and 500 transcripts: 2,517 credits, about $5 on the Growth plan billed yearly. For a side-by-side of every option, see the best YouTube transcript APIs for RAG.
Getting started
- Sign up at dashboard.scavio.dev/sign-up: 50 free credits, enough for 10 transcripts, no card required.
- Copy your API key from the dashboard.
- Send a POST to
/api/v1/youtube/transcriptwith a video id and your key in theAuthorizationheader.
Try the YouTube API free in the playground first, or give an agent the same calls through the MCP server.
Reference: YouTube API overview · transcript · video · channel videos · search · is there a stable way to pull YouTube transcripts?
Frequently asked questions
How do I convert a YouTube video to text?
Send the video id or URL to a transcript API. With Scavio, POST {"video_id": "T-D1OfcDW1M"} to /api/v1/youtube/transcript and the response's content field holds the full transcript as plain text; add "format": "srt" for timed subtitles. It costs 5 credits a video.
Should I use plain text or SRT transcripts for RAG?
Use SRT if you want to cite where an answer came from. Each SRT cue carries a start and end time, so every chunk can keep the second it starts at and link to the video at that moment. Plain text is fine when you only need the content and will cite the video as a whole.
How big should YouTube transcript chunks be?
Spoken transcripts are dense: our sample of 19 videos averaged a median of 196 tokens per minute of video. Sixty-second windows gave chunks of 199 to 229 tokens on a 6-minute IBM explainer, a common size for embedding. Use longer windows or merge neighbours if your retriever works better with bigger passages.
How much does it cost to index a YouTube channel?
With Scavio, listing uploads costs 1 credit per page of 30 videos and each transcript costs 5 credits. A 500-video channel is 17 list pages and 500 transcripts, 2,517 credits, about $5 on the Growth plan billed yearly. New accounts get 50 free credits, enough for 10 transcripts.
Can an AI agent fetch YouTube transcripts by itself?
Yes, if you give it a tool for it. Scavio's MCP server exposes the YouTube transcript, video, channel and search endpoints as callable tools, so Claude, Cursor or another MCP client can fetch a transcript when a user pastes a link and answer from the text.