A hosted youtube-transcript-api alternative
youtube-transcript-api worked on your laptop for months. Then you deployed it and the log filled with RequestBlocked, IpBlocked and Could not retrieve a transcript for the video. This page is for the developer who wants the same segments back without running a proxy pool.
What breaks with the library in the cloud
The library itself is fine. It is a small, well-kept Python package that reads the caption track the YouTube player uses. What breaks is the network it runs from, and it breaks in four distinct ways.
- Datacenter IPs are blocked. YouTube refuses caption requests from address ranges it knows belong to AWS, GCP, Azure, Hetzner, Fly, Railway and the rest. The library raises
RequestBlocked, orIpBlockedonce you have added a proxy that also got flagged. The README says as much: "you will most likely run intoRequestBlockedorIpBlockedexceptions when deploying your code to any cloud solutions." - Consent and cookie walls.Exit nodes in the EU get YouTube's cookie-consent page instead of the watch page, which surfaces as a redirect the library cannot follow. It is intermittent, so it looks like flakiness rather than a bug.
- Format changes. YouTube changes the player response shape a few times a year. Every change is an outage until a new library release ships and you deploy it.
- Proxy cost.The fix the README recommends is rotating residential proxies, billed per gigabyte. Each fetch pulls the full watch page through the proxy, and every blocked retry pays for that page again. With the library's default retry count, one bad video can burn 10 to 15 MB.
None of these are things you can fix in application code. They are properties of where the code runs and who runs it, which is why the usual answer is to move the fetch somewhere else.
What a hosted alternative changes
TranscriptAPI runs the same class of fetch on our side, through a residential proxy pool pinned to one region, with the retry ceiling, the consent-wall handling and the parser upkeep already done. You send a video ID over HTTPS and get segments back.
- No proxy vendor, no rotation code, no bandwidth line item.
- Transcripts are cached indefinitely, so a second request for the same video costs nothing.
- A video that cannot be read (captions off, private, deleted, age-restricted) returns a
404withretryable: false, a plain-languagehint, and the credit refunded. - Search, channel listings and playlists sit next to transcripts, which the library does not do at all.
What it does not do: download video or audio, read comments, return descriptions or tags, or manage a channel you own. It returns captions that already exist. If a video has none, nobody can give you a transcript without running speech-to-text.
youtube-transcript-api vs TranscriptAPI
| Concern | youtube-transcript-api (self-hosted) | TranscriptAPI (hosted) |
|---|---|---|
| Cost | Free library. Residential proxy billed per GB once you leave a home connection, plus retries. | 1 credit per transcript. 20 free, then from $10 for 2,500 or $49/month for 25,000. Cache hits free. |
| Setup | pip install, a proxy account, proxy config, retry and backoff logic. | One bearer token and an HTTPS GET. |
| Blocking | Your problem. RequestBlocked / IpBlocked from any cloud IP without proxies. | Ours. A block on our side is a 503, refunded, with retryable: true. |
| Formats | Segments; SRT, VTT, text via formatter classes. | format=json|txt|srt|vtt on the same call. |
| Translation | YouTube's own translated tracks where they exist. | translate_to=de, any language, +1 credit per 40 segments (minimum 2). |
| Search, channel, playlist | Not covered; you add yt-dlp or the Data API. | /search, /channel/videos, /channel/search, /playlist, 1 credit each. |
| Maintenance | Watch releases, redeploy on each YouTube change, keep the proxy account funded. | None on your side. |
| Data leaves your network | No. | Yes: video IDs and the returned text. |
| Still the right choice when | Residential connection, low volume, or a policy against third-party services. | Cloud-hosted, more than a few dozen fetches a day, or you are tired of the proxy bill. |
Python: before and after
Python · YouTubeTranscriptApi().fetch → requests.get
from youtube_transcript_api import YouTubeTranscriptApi from youtube_transcript_api.proxies import WebshareProxyConfig ytt = YouTubeTranscriptApi( proxy_config=WebshareProxyConfig( proxy_username="...", proxy_password="...", ) ) # raises RequestBlocked / IpBlocked when the # exit IP is flagged; you write the retry fetched = ytt.fetch("dQw4w9WgXcQ", languages=["en"]) segments = fetched.to_raw_data() # [{"text": ..., "start": 0.0, "duration": 3.52}]
import requests r = requests.get( "https://api.transcriptapi.io/transcript", params={"video_id": "dQw4w9WgXcQ", "language": "en"}, headers={"Authorization": "Bearer ta_..."}, timeout=60, ) r.raise_for_status() segments = r.json()["transcript"] # [{"start": 0.0, "duration": 3.52, "text": ...}] # SRT instead? add format="srt" # German? add translate_to="de"
The keys match, so a function that used to return fetched.to_raw_data() can return r.json()["transcript"] and nothing downstream notices. The one behaviour change worth handling: a 404 means the video has no readable captions and retryable is false, so do not loop on it. A 502 or 503 is transient and already refunded; retry with backoff.
The full endpoint-by-endpoint mapping, including the older get_transcript() classmethod form, is in the migration guide.
When the library is still the right choice
Be honest with yourself about volume and network before you swap. The library wins when:
- You run on a residential connection, a Raspberry Pi at home, or a desktop script. There is no block to route around.
- You fetch a few transcripts a day and a failure means a manual retry, not an on-call page.
- You are not allowed to send video IDs or transcript text to a third party.
- You want translated captions only where YouTube already provides them, and never AI translation.
If you are on a cloud host and fetching in the hundreds a day, the proxy bill and the retry code are what you are paying for; that is the line item a hosted API replaces. For a broader look at the other paid options, see the comparison of YouTube transcript APIs, and if you are mid-outage right now, start with what each blocked error means.
Pricing
One credit is one transcript, search or listing. Translation adds one credit per 40 segments, minimum two. Cached repeats are free, and any call that fails after being charged is refunded.
| Plan | Credits | Price | Per transcript |
|---|---|---|---|
| Free | 20 | $0, no card | — |
| Top-up (never expires) | 2,500 / 10,000 / 50,000 / 200,000 | $10 / $39 / $149 / $449 | 0.4¢ down to 0.22¢ |
| Production | 25,000 / month | $49 / month | 0.2¢ |
| Enterprise | 1,000,000 / month | from $249 / month | 0.025¢ |
Details and the per-call cost of translation are on the pricing page. The hosted vs self-hosted cost breakdown works the numbers at 1,000, 25,000 and 200,000 transcripts a month, proxy bandwidth included.
Sign in and you get 20 credits with no card. That is enough to port a fetch function, run it against the videos that were failing, and see the hint field on the ones that cannot be read. The API reference has every parameter.
Frequently asked questions
Is TranscriptAPI a drop-in replacement for youtube-transcript-api?
For the fetch, nearly. Both return a list of segments with text, start and duration in seconds, so code downstream of the fetch usually does not change. What changes is the call itself: one HTTPS GET with a bearer token instead of a library instance with proxy configuration. Language selection and translation are query parameters rather than method calls.
Why does youtube-transcript-api work locally but fail on my server?
YouTube blocks caption requests from IP ranges it knows belong to cloud providers. Your laptop is on a residential connection, your server is on AWS, GCP, Hetzner or similar, and the library raises RequestBlocked or IpBlocked from there. The library's own README says the same and recommends rotating residential proxies.
How much does the hosted alternative cost compared with running the library?
The library is free; the residential proxy it needs in the cloud is not, and neither is the time spent on retries and YouTube format changes. TranscriptAPI is one credit per transcript: 20 free credits on signup, 2,500 credits for $10 as a one-time top-up, or $49 a month for 25,000. Cached repeats of the same video are free and failed videos are refunded.
Which videos will TranscriptAPI not return?
The same ones the library cannot: videos with captions turned off, private or deleted videos, and age-restricted videos. Those come back as a 404 with error, hint and retryable: false, and the credit is refunded. There is no video download, no comments, and no metadata beyond what the endpoints document.
Do I have to change my data model?
No. GET /transcript returns transcript as an array of {start, duration, text}, which is the same shape as fetched.to_raw_data() from the library. SRT, VTT and plain text come from the format parameter if you were using the library's formatters.
When should I keep using youtube-transcript-api?
When you run on a residential connection, need a handful of transcripts a day, or cannot send video IDs to a third party. The library is well maintained and free; the problem it does not solve is the network you run it from.