NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #907 most downloaded on PyPI
This is a python API which allows you to get the transcripts/subtitles for a given YouTube video. It also works for automatically generated subtitles, supports translating subtitles and it does not require a headless browser, like other selenium based solutions do!
Last release 8 months ago
29 Jan 2026
Release timing varies
gaps range from 2 weeks to 11 months
Nearly every release is documented
notes for 32 of 35 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
35 releases · first in 2018
When a WebshareProxyConfig is created with a proxy username containing the "-rotate" suffix, the suffix will no longer be appended twice by @cjkangme
WebshareProxyConfig is created with a proxy username containing the "-rotate" suffix, the suffix will no longer be appended twice by @cjkangme in #566Full Changelog: v1.2.3...v1.2.4
One column per quarter.
What's Changed Added support for python 3.14 Full Changelog : v1.2.2...v1.2.3
Add --version option to CLI by @sderev in #496
Added the property filter_ip_locations to WebshareProxyConfig . This allows for limiting the pool of IPs that Webshare will be rotating through to tho
filter_ip_locations to WebshareProxyConfig. This allows for limiting the pool of IPs that Webshare will be rotating through to those located in specific countries. By choosing locations that are close to the machine that is doing the requests, latency can be reduced. Also, this can be used to work around location-based restrictions.
ytt_api = YouTubeTranscriptApi(
proxy_config=WebshareProxyConfig(
proxy_username="<proxy-username>",
proxy_password="<proxy-password>",
filter_ip_locations=["de", "us"],
)
)
# Webshare will now only rotate through IPs located in Germany or the United States!
ytt_api.fetch(video_id)__all__ to __init__.py to support mypy --strict usage by @Jer-Pha in #486Full Changelog: v1.2.0...v1.2.1
[BREAKING] Removed the deprecated methods get_transcript , get_transcripts and list_transcripts . They have already been deprecated in v1.0.0 , but I'…
get_transcript, get_transcripts and list_transcripts. They have already been deprecated in v1.0.0, but I've kept them around to allow for an easier migration to v1.0.0. However, these methods have led to a lot of issues being created due to people initializing a YouTubeTranscriptApi object and passing a proxy config into the constructor, but then calling the deprecated static methods on that object. As these methods are static they don't/can't access the state set in the constructor, therefore, the proxy config is ignored.If you're still using get_transcript, get_transcripts you have to change your code as follows:
# old API
transcript = YouTubeTranscriptApi.get_transcript("abc")
# new API
ytt_api = YouTubeTranscriptApi()
transcript = ytt_api.fetch("abc").to_raw_data()If you're still using list_transcripts you have to change your code as follows:
# old API
transcript_list = YouTubeTranscriptApi.list_transcripts("abc")
# new API
ytt_api = YouTubeTranscriptApi()
transcript_list = ytt_api.list("abc")Full Changelog: v1.1.1...v1.2.0
IpBlocked exception is now raised when the timedtext endpoint returns a status code 429 #468
Refactored the way the captions json is retrieved from scraping it from the /watch html to fetching it from the innertube API
/watch html to fetching it from the innertube APIPoTokenRequired, which will be raised if timedtext urls are encountered that require a PO token, such that we get feedback from users ASAP if this happens againFull Changelog: v1.0.3...v1.1.0
Refactored parsing of the JS var containing the transcript data, to make it more robust to changes in the formatting of the returned HTML
Full Changelog: v1.0.2...v1.0.3
Added retry mechanism, which will retry requests when Webshare proxies are used and RequestBlocked is raised, to trigger an IP rotation in case a user
RequestBlocked is raised, to trigger an IP rotation in case a user encounters a blocked residential IPRequestBlocked is raised despite proxies being used, to assist users in figuring out what the issue isFull Changelog: v1.0.1...v1.0.2
Adds a feature to allow proxy configs to prevent the HTTP client from keeping TCP connections open, as keeping TCP connections alive can prevent proxy
prevent_keeping_connections_alive() -> bool method to ProxyConfig objectsConnection: close header will be added to the HTTP client, if a proxy config with prevent_keeping_connections_alive() == True is usedFull Changelog: v1.0.0...v1.0.1
You'll find more details on the updated API in the README. The old static methods can still be used, but have been deprecated and will be removed in a…
get_transcript, get_transcripts and list_transcripts
YouTubeTranscriptApi.get_transcript(video_id) is replaced with YouTubeTranscriptsApi().fetch(video_id)YouTubeTranscriptApi.list_transcripts(video_id) is replaced with YouTubeTranscriptsApi().list(video_id)YouTubeTranscriptApi.get_transcripts in the new interface, as this doesn't provide any meaningful utility over just running [ytt_api.fetch(video_id) for video_id in video_ids].fetch and .list on a YouTubeTranscript instance, we can share a HTTP session between all requests, which allows us to share cookies and reduces redundant requests, thereby saving bandwidth and proxy costs.transcript.fetch() now returns a FetchedTranscript object instead of a list of dictionaries. This allows for adding metadata and utility methods to the returned object. You can still convert a FetchedTranscript object to the previously used format by calling fetched_transcript.to_raw_data().RequestBlocked is now raised if the request has been blocked by YouTube due to a blacklisted IP (which would previously raise TranscriptDisabled #303)AgeRestricted is raised if the video is age restricted and requires cookie authentication (#111)VideoUnplayable is raised if the video is unplayable for an unknown reason. When this happens the error message that YouTube would display on the WebPlayer is returned by the exception, which should make unknown errors more useful. (#219)YouTubeTranscriptApi. All proxy configs are located in the new module youtube_transcript_api.proxies.
GenericProxyConfig class (similarly to how it was done before using the requests dict)WebshareProxyConfigYouTubeTranscriptApi constructor
YouTubeTranscriptApiDue to the rewrite of some interfaces I wasn't able to merge their PRs directly, but special thanks to the work done by @crhowell in #219 and by @andre-c-andersen in #337, as their PRs have been very useful in implementing the new exceptions types! 😊🙏
Full Changelog: https://github.com/jdepoix/youtube-transcript-api/compare/v0.6.3...v1.0.0
Fix grammatical mistakes in README by @Jai0401 in https://github.com/jdepoix/youtube-transcript-api/pull/287
Full Changelog: https://github.com/jdepoix/youtube-transcript-api/compare/v0.6.2...v0.6.3
YouTube has made some changes which caused the translationLanguages key to sometimes be missing from the captions json. This release adjusts the fetch
translationLanguages key to sometimes be missing from the captions json. This release adjusts the fetching process to initialize translation_languages with an empty list in case that happens.Fixed transcript list not showing display names for languages in English
The optional parameter preserve_formatting has been added to YouTubeTranscriptApi.get_transcript, YouTubeTranscriptApi.get_transcripts, and Transcript
preserve_formatting has been added to YouTubeTranscriptApi.get_transcript, YouTubeTranscriptApi.get_transcripts, and Transcript.fetch. If this is set to True, formatting elements such as <i> (italics) and <b> (bold) are no longer removed from the transcript. (thanks to @eseiver!)InvalidVideoId exception.Added support for formatting .srt files using the SRTFormatter (thanks to @liamrs222!)
.srt files using the SRTFormatter (thanks to @liamrs222!)get_transcript and get_transcripts now assert that their input type is correct, as users commonly passed a video id (string) into get_transcripts although it expects a list. Since a string is an iterable the module tried to find a video for each character of that string, which failed with a not-so-helpful error message. (thanks to @majamil16!)Transcript language list is now properly escaped, thereby fixing a decoding error which would occur on transcripts for languages containing " in their
" in their name (like Estnisch - "Raev")Fixed bug where TranscriptsDisabled wasn't raised properly (thanks to @xenova!)
TranscriptsDisabled wasn't raised properly (thanks to @xenova!)FormatterLoader, which was preventing the WebVTTFormatter from being loaded properly (thanks to @MAJA-Lin!)Timestamp formatting in WebVTTFormatter has been fixed
WebVTTFormatter has been fixedYouTubeRequestFailed exception is raised, wrapping the status code and error messageAs of lately YouTube will occasionally return a page which requires the user to give consent to cookies being saved. Whenever this page was returned t
As of lately YouTube will occasionally return a page which requires the user to give consent to cookies being saved. Whenever this page was returned this this module was not able to process the response. Now it is able to recognise this case and create a consent cookie if needed.
Added support for different formatters, including support for WebVVT (thanks @crhowell!)
# Changes: - Typos in Documentation fixed.
added support for using cookies, to be able to retrieve age restricted videos
YouTubeTranscriptApi.get_transcript(video_id, cookies='/path/to/your/cookies.txt')youtube_transcript_api <first_video_id> <second_video_id> --cookies /path/to/your/cookies.txt Thanks to @danielcliu for the contribution!
fixed a bug in the CLI where no videos could be retrieved if no language was specified
added list_transcripts(video_id) to YouTubeTranscriptApi, which returns a TranscriptList object, representing all available transcripts
list_transcripts(video_id) to YouTubeTranscriptApi, which returns a TranscriptList object, representing all available transcripts
TranscriptList objects provide the methods find_transcript(languages), find_generated_transcript(languages) and find_manually_created_transcript(languages), which return Transcript objects
Transcript objects represent a transcripts and provide metadata propertiestranscript.fetch() the actual transcript is fetchedtranscript.translate('de') on a Transcript object YouTubes translation feature can be accessedTranscriptsDisabled, NoTranscriptFound, VideoUnavailable, NotTranslatable, TranslationLanguageNotAvailable, NoTranscriptAvailableCouldNotRetrieveTranscriptyoutube_transcript_api.YouTubeTranscriptApi.CouldNotRetrieveTranscript has been move to youtube_transcript_api.CouldNotRetrieveTranscriptSpecial thanks to @danielcliu for his contributions and time in the reviewing process!
It turned out that the the changes in v0.1.8 were still missing some details, which only occurred under certain circumstances. This has been fixed in
It turned out that the the changes in v0.1.8 were still missing some details, which only occurred under certain circumstances. This has been fixed in this version.
A change in the YouTube webclient did completely break this module. This is fixed as of this version.
A change in the YouTube webclient did completely break this module. This is fixed as of this version.
A Bug was fixed which caused the API to crash on empty subtitles boxes.
A Bug was fixed which caused the API to crash on empty subtitles boxes.
The YouTubeTranscriptApi no longer logs errors in the get_transcript method. This way the user of the API can control wether an error should be logged
The YouTubeTranscriptApi no longer logs errors in the get_transcript method. This way the user of the API can control wether an error should be logged or not.
The error message which is shown when an CouldNotRetrieveTranscript Exception is raised, now is more specific on what the cause could be.
The error message which is shown when an CouldNotRetrieveTranscript Exception is raised, now is more specific on what the cause could be.
Specific HTTP/HTTPS proxies can be provided using the API/CLI, which will be used during the YouTube requests.
Specific HTTP/HTTPS proxies can be provided using the API/CLI, which will be used during the YouTube requests.
Thanks to @DannyAziz for the contribution!
The way arguments are parsed when using the CLI has been improved. This includes better descriptions, support for a --help argument and support for sp
The way arguments are parsed when using the CLI has been improved. This includes better descriptions, support for a --help argument and support for specifying preferred languages.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →