← All guides

How to get YouTube transcripts in Python

Written by the VidWords Team · · Updated · Report a correction

A complete guide to extracting YouTube captions in Python — open-source libraries vs hosted REST API, handling IpBlocked errors, and working with timed cues.

Python is the default language for scraping, data science, and AI pipelines. If you are building a video summarizer, training a model, or indexing video content, you need a reliable way to get timestamped transcripts from YouTube in Python.

There are two main approaches: using the open-source youtube-transcript-api package for local scripts, or using the VidWords REST API for production applications and cloud deployments.

Approach 1: Using youtube-transcript-api (Local Scripts)

For quick local experiments on your own laptop, the community package youtube-transcript-api is popular:

pip install youtube-transcript-api

from youtube_transcript_api import YouTubeTranscriptApi

# 1.x is an INSTANCE api: construct, then fetch()
transcript = YouTubeTranscriptApi().fetch("dQw4w9WgXcQ")
for cue in transcript[:3]:
    print(f"[{cue.start:.1f}s] {cue.text}")

# Need plain dicts (for json.dump, a DataFrame, a database row)?
raw = transcript.to_raw_data()   # [{"text": ..., "start": ..., "duration": ...}, ...]

Version note: release 1.0 replaced the old class methods with this instance API. If you are following a tutorial that calls YouTubeTranscriptApi.get_transcript(...) or .list_transcripts(...), it predates 1.0 and raises AttributeError on any current install — fetch() and list() are the two public methods now, and cues come back as objects with .text, .start and .duration rather than dictionaries.

Why youtube-transcript-api fails in production

While this works on your local machine, deploying this code to cloud servers (AWS Lambda, Google Cloud Run, Render, Heroku, or DigitalOcean) almost always fails with RequestBlocked or IpBlocked errors. YouTube aggressively blocks traffic originating from known datacenter IP ranges and requires bot-verification challenges (PoToken) that open-source scrapers cannot solve without residential proxies.

Approach 2: VidWords REST API in Python (Production & Cloud)

For production servers, backend APIs, and agent pipelines, the VidWords REST API handles caption extraction, proxy rotation, and bot-wall resilience automatically. You only need standard Python libraries (no heavy dependencies):

import requests

API_TOKEN = "your_vidwords_api_token"
URL = "https://vidwords.com/api/transcripts"

response = requests.post(
    URL,
    headers={"Authorization": f"Basic {API_TOKEN}"},
    json={"ids": ["dQw4w9WgXcQ"], "lang": "en"}
)

data = response.json()
video = data["results"][0]
print(f"Title: {video['title']}")
print(f"Transcript: {video['text'][:200]}...")

Tokens are free at vidwords.com/register (25 free transcript requests per month on the free tier, with paid plans scaling to 10,000 requests per month).

Batch Processing Multiple Videos in Python

You can send up to 50 video IDs or URLs in a single API call, reducing network overhead and rate limits:

video_ids = ["dQw4w9WgXcQ", "jNQXAC9IVRw", "9bZkp7q19f0"]

response = requests.post(
    "https://vidwords.com/api/transcripts",
    headers={"Authorization": f"Basic {API_TOKEN}"},
    json={"ids": video_ids}
)

for item in response.json().get("results", []):
    print(f"Fetched {item['id']}: {len(item.get('segments', []))} cues")

Connecting Python AI Agents with MCP

If you are building autonomous AI agents with LangChain, LlamaIndex, or CrewAI, you can connect them directly to the hosted VidWords MCP server at https://vidwords.com/mcp. The server exposes search_transcript and get_transcript tools with citable timestamp links.

FAQ

Does the official YouTube Data API v3 return transcripts?

No. YouTube Data API v3 allows creators to manage captions on their own videos, but does not provide caption download access for third-party public videos without owner credentials.

What response formats does the VidWords API provide?

The API returns structured JSON containing the video title, author, detected language, continuous plain text, and timed cue segments (with start timestamp and duration in seconds).

How do I handle videos in other languages?

Pass the "lang" parameter (e.g., "es", "fr", "de", "ja") in your request body to select a specific language track.

View full API documentation →