Troubleshooting
YouTube transcript API blocked or rate limited?
It works on your laptop, then fails in production. Almost always the same cause, and it is not your code.
Why it happens
YouTube has no public API for transcripts. The captions you see in a video player come from an internal endpoint, and libraries like youtube-transcript-api call that endpoint directly. It is unauthenticated, undocumented and unsupported — which means it has no quota, no Terms of Service for automated access, and no obligation to answer you.
YouTube's anti-abuse layer does the obvious thing: it scores the IP address making the request. A residential IP with a normal browsing history gets served. A datacenter IP making thousands of caption requests in an hour gets one of these:
# python
>>> YouTubeTranscriptApi.get_transcript("dQw4w9WgXcQ")
RequestBlocked: IP address is blocked by YouTube,
or IpBlocked, or an empty transcript list.
The failure modes you will see, in rough order of frequency:
- 429 Too Many Requests — rate-limited, usually temporary.
- Empty caption track list — the response succeeds but contains no tracks. Common from flagged IPs and for videos with captions disabled.
- RequestBlocked / IpBlocked — the IP itself is refused. Rotating to a different IP usually clears it.
- Consent-page redirects — EU/UK IPs hit a cookie-consent interstitial before the caption track.
The tell: if it works locally and fails on a server, it is IP reputation. If it fails for specific videos everywhere, it is the video (no captions, private, region-locked, or music-only content).
Four ways around it, honestly compared
1. Rotate residential proxies yourself
Rotate the request IP through a residential proxy pool. This is what actually fixes the problem, because residential IPs are not pre-flagged the way datacenter ranges are.
- Upside: full control, works with the library you already use.
- Downside: residential bandwidth is billed per GB and is not cheap; you now need retry logic, rotation policy, consent-page handling and per-domain concurrency limits. Expect a week of work before it is stable.
2. Use the official YouTube Data API
The Data API is stable, documented and quota-based — and it does not return transcript text. It returns metadata, and for some videos a caption track reference, but downloading the actual track still goes through the same blocked endpoint.
- Upside: fully sanctioned for the metadata it does return.
- Downside: not a transcript solution. Teams regularly migrate to it expecting transcripts and discover the gap after the work.
3. Run a headless browser with captions turned on
Open the video in a browser, enable the caption panel and read the rendered cues from the DOM. This gets around the endpoint, but not around IP reputation, and it is slow and brittle.
- Upside: works for videos where the direct endpoint fails.
- Downside: a browser per video, minutes instead of seconds, and it breaks when the player UI changes.
4. Use a hosted actor and pay per transcript
Someone else maintains the proxy pool, the retry policy and the parser. You send a URL and get text back.
- Upside: no infrastructure, no library drift, and someone else absorbs the maintenance when YouTube changes something.
- Downside: per-result pricing, and you depend on their uptime.
Which one you should pick
| Your situation | Reasonable choice |
|---|---|
| Hobby project, a few dozen videos | Library plus a delay and retries. Accept occasional failures. |
| Production pipeline, steady volume | Residential proxy rotation, or a hosted actor if you would rather not own it. |
| Metadata only | Official YouTube Data API. |
| Multi-platform (TikTok, Reels, X too) | Hosted actor. Each platform has a different failure mode; maintaining all of them is a job. |
| One-off research, hundreds of videos | Hosted actor. Proxy setup will cost more than the run. |
How our actor handles it
The Video Transcript API runs on Apify's proxy infrastructure and reads the native caption track when one exists. When a video has no captions at all — common on TikTok, Instagram and X — it sends the audio through Whisper instead of failing.
That last part matters more than it sounds. A blocked caption endpoint and a video with no captions look the same from the outside: you get no text. Only one of them is fixed by rotating an IP.
What it will not fix
- Private, deleted or region-locked videos
- Videos where captions are disabled and the audio is music only
- Live streams
Those come back as unresolved rows rather than billable results, so a bad batch costs you time instead of money.
Test it on the videos that are failing for you
Paste the URLs that return empty tracks in your current setup and compare the output.
Open the transcript actor