QuickTube

YouTube Transcript API: A Developer’s Guide

How to get YouTube transcripts in code: the official Data API, open-source libraries and hosted APIs compared, with Python examples and tips.

Updated by QuickTube.ai

Transcripts are the most useful thing you can pull out of a YouTube video in code. They feed search indexes, RAG pipelines, research datasets, subtitle tools and summarizers. Getting them reliably is harder than it looks, though. This guide covers the three ways to do it, what a transcript response looks like, and the practical problems (languages, missing captions, caching, chunking) you will hit once you run it at scale.

Option 1: the official YouTube Data API

The YouTube Data API v3 has a captions resource. captions.list tells you which caption tracks a video has, which is useful on its own. captions.download returns the track content, but it requires OAuth authorization, and in practice it works for videos on channels you own or manage. You can’t use it to download the captions of an arbitrary public video.

Use it when you are building tools for your own channel or for creators who sign in with their Google account. Skip it when you need transcripts of other people’s videos.

Option 2: open-source libraries

Libraries such as the Python package youtube-transcript-api read the same caption data the YouTube player uses, for any public video with captions. They need no API key and cost nothing, and on your own machine they work well.

The catch is production. YouTube limits and blocks automated requests, and requests from cloud provider IP ranges are blocked far more often than requests from home connections. Running a library on a server usually means adding rotating proxies, retries with backoff, and a cache so you don’t fetch the same video twice. The library is also only as stable as YouTube’s internal formats, so expect occasional breakage after YouTube changes something.

Use it when you are prototyping, running locally, or are happy to own the proxy and retry layer. Skip it when you want transcripts to just work from a server.

Option 3: a hosted transcript API

A hosted API runs the fetching, blocking workarounds and caching for you and exposes a single endpoint. The QuickTube transcript API is one: you send the video URL with an API key and get JSON back. It costs 1 credit per transcript, and a free account includes 400 credits once you verify your email.

Use it when you want reliability without running infrastructure, or you also need AI on top (summaries, quizzes, fact checks) from the same key. Skip it when you need millions of transcripts and have the engineering time to run your own fetching more cheaply.

Fetching a transcript in Python

Create a free account, then an API key under Settings → API Keys (new keys include the transcript scope). Store it in an environment variable and call POST /api/transcript:

transcript.py
import os
import requests

API = "https://quicktube.ai/api/transcript"
HEADERS = {"X-API-Key": os.environ["QUICKTUBE_API_KEY"]}


def get_transcript(video_url: str, languages: list[str] | None = None) -> dict:
    body = {"video_url": video_url}
    if languages:
        body["languages"] = languages
    response = requests.post(API, headers=HEADERS, json=body, timeout=60)
    if response.status_code == 404:
        raise LookupError(response.json()["detail"])  # no captions, or video unavailable
    response.raise_for_status()
    return response.json()


data = get_transcript("https://youtu.be/VIDEO_ID", languages=["en", "de"])
print(data["video_id"], data["language_code"], len(data["transcript"]), "segments")

The response carries both shapes you are likely to need:

Response (shortened)
{
  "video_id": "VIDEO_ID",
  "language": "English (auto-generated)",
  "language_code": "en",
  "is_generated": true,
  "transcript": [
    { "text": "first caption line", "start": 0.0, "duration": 3.5 },
    { "text": "second caption line", "start": 3.5, "duration": 2.8 }
  ],
  "text": "first caption line\nsecond caption line"
}
  • transcript is a list of segments with text, start and duration in seconds. Use it for subtitles, deep links and anything time-aware.
  • text is the whole transcript as one string, one caption line per line. Use it when you just want to hand the content to a model.
  • language_code and is_generated tell you which track you got and whether YouTube generated it automatically. Store them: auto-generated text deserves more caution downstream.

Practical problems and how to handle them

Languages

Many videos have several caption tracks. Pass languages as an ordered preference list, such as ["en", "es"]; a base code like en also matches regional variants such as en-US. If you pass nothing, QuickTube prefers English and otherwise falls back to whatever language the video has, so always read language_code instead of assuming.

Videos without captions

Some videos have no captions at all, and some are private, deleted or region-locked. Expect a 404 for these (a 403 for age-restricted videos) and treat it as a normal outcome, not an error to retry. A 503 is different: YouTube refused the request for now, so retry it later. Any caption-based method has the same gap; the only way around it is to download the audio and run your own speech-to-text, which is a different cost and legal question.

Rate limits and retries

Respect 429 responses with exponential backoff, and run batches with modest concurrency rather than hundreds of parallel requests. A 402 means you are out of credits; stop and alert rather than retrying.

Caching

Captions rarely change after upload, so cache transcripts by video ID and language on your side as well. Fetching the same video twice costs you twice, even if the provider served it from its own cache.

Chunking for language models

For retrieval or long-video summarization, split the segments into time-based chunks rather than cutting the plain text at arbitrary lengths. Keeping each chunk’s start time lets you link answers back to the exact moment in the video:

Group segments into five-minute chunks
def chunks(segments: list[dict], max_seconds: float = 300) -> list[dict]:
    """Group transcript segments into ~5-minute chunks that keep their start time."""
    out, current, start = [], [], None
    for seg in segments:
        if start is None:
            start = seg["start"]
        current.append(seg["text"])
        if seg["start"] + seg["duration"] - start >= max_seconds:
            out.append({"start": start, "text": " ".join(current)})
            current, start = [], None
    if current:
        out.append({"start": start, "text": " ".join(current)})
    return out

Going further: AI endpoints and agents

The same API key can call QuickTube’s AI endpoints, such as /api/summarize, /api/best-sections, /api/quiz and /api/fact-check, which fetch the transcript for you and return structured results. They need the ai scope and cost the same credits as in the web app. The API reference lists every endpoint.

If the consumer of the transcript is an AI assistant rather than your own code, skip the glue entirely: the QuickTube MCP server exposes the same features as tools that Claude Code, Claude Desktop and Cursor can call directly.

Summary

  • Your own channel: the official YouTube Data API.
  • Prototypes and local scripts: an open-source library.
  • Production without running proxies: a hosted API.
  • AI assistants: an MCP server.

Frequently asked questions

How much does the YouTube transcript API cost?

Each transcript fetched with an API key costs 1 credit, including transcripts served from cache. AI endpoints cost the same as in the web app, for example 5 credits for a summary. A free account comes with 400 credits once your email is verified, and more are sold as one-time packs with no subscription.

Does it work with videos in other languages?

Yes. QuickTube uses the captions in whatever language the video has them, preferring English when an English track exists. It does not translate them. Quizzes are written in the language of the transcript. Through the API you can ask for specific languages in order of preference.

What if a video has no captions?

QuickTube reads the captions YouTube already has, either uploaded by the creator or generated automatically. It does not transcribe audio itself, so a video with captions turned off can't be transcribed or analyzed.

Which AI tools can use the QuickTube MCP server?

Any client that supports local (stdio) MCP servers, including Claude Code, Claude Desktop and Cursor. The server is a Python package, quicktube-mcp, that you run with "uvx quicktube-mcp" or install with "pip install quicktube-mcp". It authenticates with your QuickTube API key.