YouTube Transcript (Apify)
YouTube transcripts as text, timestamps, SRT or VTT in 70+ languages, with translation. Works from cloud servers where YouTube blocks direct requests.
Documentation
youtube-transcript-apify
A YouTube transcript API for Python that keeps working on AWS, Google Cloud, Azure, Vercel, Render and other cloud servers: a drop-in fix for youtube-transcript-api when it gets IP-blocked.
If your code works on your laptop but fails in production with RequestBlocked, IpBlocked, TooManyRequests or HTTP 429, YouTube is blocking your server's IP address. Most cloud IP ranges are blocked. This package sends the request to a hosted scraper on Apify that handles proxies and retries, and gives you back plain Python data.
- Same shape as the classic
youtube-transcript-apicall: a list of{"text", "start", "duration"}. - Plain text, timestamped text, SRT and VTT subtitles, in the video's own language, any caption language you ask for, or translated.
- Videos without captions are reported, not charged.
- The client uses only the standard library. Includes a CLI and an MCP server for Claude, Cursor and other AI agents.
Disclosure: this package is a thin client for the YouTube Transcript Scraper Actor, which is made by the same author (nokia2k). Runs are billed by Apify: $2.99 per 1,000 transcripts on Apify's Free plan, down to $1.49 on paid plans, at the time of writing. The Free plan includes $5 of credit every month, no card needed.
Install
pip install youtube-transcript-apify # client, CLI and MCP server
Get a free API token at https://console.apify.com/settings/integrations and set it:
export APIFY_TOKEN=apify_api_...
Use the YouTube transcript API in Python
Replace the call that gets blocked:
# before
# from youtube_transcript_api import YouTubeTranscriptApi
# segments = YouTubeTranscriptApi.get_transcript("arj7oStGLkU", languages=["en"])
# after
from yt_transcript_apify import get_transcript
segments = get_transcript("arj7oStGLkU", languages=["en"])
print(segments[0]) # {'text': 'So in college,', 'start': 1.2, 'duration': 2.16}
More control:
from yt_transcript_apify import ApifyTranscriptClient
client = ApifyTranscriptClient() # reads APIFY_TOKEN
t = client.fetch("https://youtu.be/arj7oStGLkU", formats=["text", "srt"])
print(t.title, t.language, t.is_generated)
print(t.text[:200])
open("talk.srt", "w").write(t.srt)
rows = client.fetch_many(["arj7oStGLkU", "iG9CE55wbtY"], translate_to="es")
for row in rows:
print(row["status"], row.get("title")) # failed videos keep a plain message
fetch raises TranscriptError (with .status, e.g. no_captions, video_unplayable, video_unavailable) when a video has no transcript. fetch_many never raises for single videos: each row carries its own status and message.
LangChain document loader
pip install "youtube-transcript-apify[langchain]"
from yt_transcript_apify.langchain import YouTubeTranscriptApifyLoader
docs = YouTubeTranscriptApifyLoader(
["https://youtu.be/arj7oStGLkU", "iG9CE55wbtY"], languages=["en"]
).load()
print(docs[0].metadata["title"], len(docs[0].page_content))
One Document per video, with title, channelName, language, durationSeconds and source in the metadata. Videos without captions are skipped. Works the same on AWS, GCP or Vercel, where the classic loader gets IP-blocked.
Command line
yt-transcript-apify arj7oStGLkU # plain text
yt-transcript-apify https://youtu.be/arj7oStGLkU --format srt > talk.srt
yt-transcript-apify arj7oStGLkU --lang es --translate en
YouTube transcript MCP server (Claude Desktop, Claude Code, Cursor)
Add this to your MCP client configuration:
{
"mcpServers": {
"youtube-transcript": {
"command": "uvx",
"args": ["youtube-transcript-apify"],
"env": { "APIFY_TOKEN": "apify_api_..." }
}
}
}
Tools:
| Tool | What it does |
|---|---|
get_youtube_transcript | One video or Short: text, timestamps, srt or vtt, optional language and translation |
get_youtube_transcripts | Up to 50 videos at once, plain text, one section per video |
Then ask: "Summarize this video: https://www.youtube.com/watch?v=arj7oStGLkU".
Other ways to call the same scraper
- No code: run it from the Apify Store page and download JSON, CSV or Excel.
- n8n, Make, Zapier: use the Apify integration and pick
nokia2k/youtube-transcript-scraper. - Thousands of videos as plain text: YouTube Video to Text is cheaper per video.
- Whole channels, playlists, search results, likes and comments: YouTube Scraper.
FAQ
Why does youtube-transcript-api work locally but not on my server? YouTube blocks most requests from cloud provider IP ranges. Rotating residential proxies fix it; this package uses a hosted service that already has them, so you do not manage proxies yourself.
Is it free? The package is free and open source (MIT). The Apify runs it calls are paid per transcript: $2.99 per 1,000 on the Free plan, whose $5 monthly credit covers roughly 1,600 transcripts.
How do I fix RequestBlocked or IpBlocked from youtube-transcript-api? Replace YouTubeTranscriptApi.get_transcript with yt_transcript_apify.get_transcript (see above). The request then goes out from Apify's proxies instead of your server's blocked IP, and the result has the same shape.
Can I download YouTube subtitles as SRT or VTT? Yes: client.fetch(video, formats=["srt", "vtt"]) returns both, or use --format srt on the command line.
Which data does it return? Only what YouTube shows publicly: captions, title, channel, language. It does not download video or audio.
License
MIT