Use case · RAG · Python

RAG over YouTube videos

Let users ask questions about a channel, a course or a conference, and answer with a link to the exact second where it was said. The hard part is getting clean, timestamped transcripts at scale; the rest is a standard RAG pipeline.

The pipeline

  1. List the videos of a channel or playlist with /v1/videos.
  2. Fetch transcripts 50 at a time with /v1/batch.
  3. Chunk the timestamped segments into passages of a few hundred words, keeping each passage's start time.
  4. Embed the passages and store them with video_id and start.
  5. Retrieve and answer, citing https://youtu.be/VIDEO_ID?t=START.

1-2. Get the transcripts

import os, requests

API = "https://api.transkrio.com/v1"
H = {"x-api-key": os.environ["TRANSKRIO_API_KEY"]}

videos = requests.get(f"{API}/videos", headers=H,
                      params={"url": "@lexfridman", "limit": 100}).json()["videos"]
urls = [v["url"] for v in videos]

transcripts = []
for i in range(0, len(urls), 50):
    res = requests.post(f"{API}/batch", headers=H, timeout=300,
                        json={"urls": urls[i:i + 50]}).json()
    transcripts += [t for t in res["results"] if t["ok"]]

Videos without captions come back with ok: false and cost nothing.

3. Chunk with timestamps

def chunks(t, max_words=400):
    buf, start = [], None
    for s in t["segments"]:
        start = s["start"] if start is None else start
        buf.append(s["text"])
        if sum(len(x.split()) for x in buf) >= max_words:
            yield {"video_id": t["video_id"], "start": int(start), "text": " ".join(buf)}
            buf, start = [], None
    if buf:
        yield {"video_id": t["video_id"], "start": int(start), "text": " ".join(buf)}

passages = [c for t in transcripts for c in chunks(t)]

4-5. Embed, retrieve, cite

Use any embedding model and vector store (pgvector, Qdrant, Chroma, a NumPy array for a prototype). At query time, retrieve the top passages and put them in the prompt with their link:

context = "\n\n".join(
    f"[https://youtu.be/{p['video_id']}?t={p['start']}]\n{p['text']}" for p in top_passages
)
prompt = f"Answer using only these excerpts and cite the links.\n\n{context}\n\nQuestion: {question}"

Tips

No-code version: the n8n node plus n8n's vector store nodes. Agent version: give your model the MCP server. More code in YouTube transcripts in Python.

Try it with 100 free credits No card needed. Failed requests are free and unused credits roll over.
Get free API key

FAQ

How big should the chunks be?

Around 300 to 500 words with a small overlap works well for talks and tutorials. Group segments until you reach the size, so each chunk keeps its start time.

What about videos without captions?

Most YouTube videos have auto-generated captions. Those without captions return no_transcript at no cost; skip them.

How do I keep the index up to date?

Call /v1/videos on a schedule, and only fetch transcripts for video IDs you haven't indexed yet.