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](/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](https://apify.com/scrape-lads/video-transcript-scraper?utm_source=scrapelads&utm_medium=site&utm_campaign=blog-youtube-transcript-api-ip-blocked&utm_content=video-transcript-scraper)
