Python · youtube-transcript-api · Troubleshooting
'YouTubeTranscriptApi' Has No Attribute 'get_transcript': Cause and Fix
youtube-transcript-api 1.2.0 removed get_transcript, get_transcripts and list_transcripts. The two-line fix, the errors that come right after it, and what to do when the old call is inside LlamaIndex or another library.
· 3 min read · YTAPI
Code that fetched YouTube transcripts fine before mid-2025 now stops on the first call:
AttributeError: type object 'YouTubeTranscriptApi' has no attribute 'get_transcript'The same happens with list_transcripts and get_transcripts. If you created an instance first, the message says 'YouTubeTranscriptApi' object has no attribute 'get_transcript' instead. Your code didn't change: the library did.
We make YTAPI, a hosted transcript API, and ran into this error while testing LlamaIndex's YouTube reader for another post. Everything below was run on October 14, 2026 with youtube-transcript-api 1.2.4, the latest release.
Why it broke
youtube-transcript-api 1.0.0 (March 2025) replaced the static methods with methods on an instance, and kept the old ones as deprecated. 1.2.0 (July 2025) removed them. Any project that pins youtube-transcript-api loosely, or not at all, picks up 1.2.x on its next install and breaks.
The maintainer's reason for removing them: people passed a proxy config to the constructor and then called the static methods, which never saw it, so their proxies were silently ignored.
The fix
| Before 1.2 | Now |
|---|---|
YouTubeTranscriptApi.get_transcript(video_id) | YouTubeTranscriptApi().fetch(video_id).to_raw_data() |
YouTubeTranscriptApi.list_transcripts(video_id) | YouTubeTranscriptApi().list(video_id) |
YouTubeTranscriptApi.get_transcripts(ids) | a loop over fetch() |
In code:
from youtube_transcript_api import YouTubeTranscriptApi
ytt_api = YouTubeTranscriptApi() # pass proxy_config=... here if you use one
transcript = ytt_api.fetch("dQw4w9WgXcQ", languages=["en"])
raw = transcript.to_raw_data() # the list of dicts get_transcript() returned
for track in ytt_api.list("dQw4w9WgXcQ"):
print(track.language_code, track.is_generated)Create the instance once and reuse it: it keeps one HTTP session, and it's where your proxy settings live.
The errors right after the fix
fetch() returns a FetchedTranscript object, not a list of dicts. Code written for the old return value fails in two more places. We ran both:
>>> transcript = ytt_api.fetch("dQw4w9WgXcQ")
>>> transcript[0]
FetchedTranscriptSnippet(text='[♪♪♪]', start=1.36, duration=1.68)
>>> transcript[0]["text"]
TypeError: 'FetchedTranscriptSnippet' object is not subscriptable
>>> json.dumps(transcript)
TypeError: Object of type FetchedTranscript is not JSON serializableEither use attributes (snippet.text, snippet.start, snippet.duration), or call .to_raw_data() once and keep the rest of your code as it was. Indexing, len() and iterating still work on the object itself.
Pinning the old version instead
If you can't change the calling code today, pin the last release that still has the old methods:
pip install "youtube-transcript-api<1.2"That's 1.1.1. Its DeprecationWarning is hidden by default, so nothing will tell you you're on borrowed time. Today it fetches transcripts with exactly the same code as 1.2.4 (we compared the two), but when YouTube changes something, the fix will only land in new releases. Treat the pin as a stopgap.
When the old call is inside a library
Often the call isn't in your code. LlamaIndex's YoutubeTranscriptReader is one: version 0.6.0 of llama-index-readers-youtube-transcript, the latest on PyPI, still calls YouTubeTranscriptApi.get_transcript, and so does the reader on LlamaIndex's main branch as of today. A fresh install fails like this:
File ".../llama_index/readers/youtube_transcript/base.py", line 50, in load_data
transcript_chunks = YouTubeTranscriptApi.get_transcript(
AttributeError: type object 'YouTubeTranscriptApi' has no attribute 'get_transcript'Pinning youtube-transcript-api<1.2 next to it works. So does replacing the reader with a few lines that do the same job on the new API:
from llama_index.core import Document
from youtube_transcript_api import (
NoTranscriptFound,
TranscriptsDisabled,
VideoUnavailable,
YouTubeTranscriptApi,
)
ytt_api = YouTubeTranscriptApi() # pass proxy_config=... here if you use one
def load_youtube(video_ids, languages=("en",)):
"""What YoutubeTranscriptReader.load_data did, on the 1.x API.
Videos without a transcript are skipped; a block (RequestBlocked) still
raises, since every video after it would fail the same way."""
docs = []
for video_id in video_ids:
try:
transcript = ytt_api.fetch(video_id, languages=languages)
except (TranscriptsDisabled, NoTranscriptFound, VideoUnavailable) as e:
print(f"skipped {video_id}: {type(e).__name__}")
continue
text = "\n".join(snippet.text for snippet in transcript)
docs.append(Document(text=text, id_=video_id, metadata={"video_id": video_id}))
return docsWe ran it with llama-index-core 0.14.25 and got one Document per video, as the reader used to return. Unlike the old reader, it skips a video without captions instead of failing the whole list. The same error has been reported against other projects, such as Meta's synthetic-data-kit and Agno's YouTube tools; the fix is the same wherever the call lives.
The next error: RequestBlocked
Once the code runs, the next thing many people hit is YouTube refusing the request. It happened to us while writing this post: after about fifteen requests in ten minutes from one development machine, every fetch started failing with:
youtube_transcript_api._errors.RequestBlocked:
Could not retrieve a transcript for the video https://www.youtube.com/watch?v=...The message lists the usual causes: too many requests from one IP, or an IP that belongs to a cloud provider. On a server it's often there from the first request. We've written up what to do about it:
- youtube-transcript-api blocked on Vercel, Render and Railway
- IP blocked on AWS and on Google Cloud
- What retries_when_blocked does, and the RetryError it can end in
Skipping the blocks
If you'd rather not deal with blocks at all, YTAPI fetches transcripts through our own proxy network and gives them back as JSON, Markdown with timestamps, SRT or plain text. A transcript costs 1 credit, failed requests are free, and new accounts get 200 credits:
# pip install ytapi-sdk
import os
from ytapi import YTAPI
api = YTAPI(api_key=os.environ["YTAPI_KEY"])
transcript = api.get_transcript("dQw4w9WgXcQ") # segments with start timesFAQ
Which version do I have?
Run pip show youtube-transcript-api. Anything from 1.2.0 on has no get_transcript.
Is fetch() slower than get_transcript() was?
No. In 1.1.1, get_transcript() was a shortcut that created an instance and called the same code. Reusing one instance for many videos is a little faster, since it keeps one HTTP session.
Where did get_transcripts() go?
It was removed without a replacement; a loop over fetch() does the job. The old method returned a pair: the transcripts by video ID, and the IDs that failed. If your code used that second list, collect the failures in your loop, and catch errors per video so one video without captions doesn't stop the rest.
Published October 14, 2026. Tested with youtube-transcript-api 1.2.4, llama-index-readers-youtube-transcript 0.6.0 and llama-index-core 0.14.25 on Python 3.10.