Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Fetch YouTube video captions/transcripts and metadata. Use when you need to download video transcripts, extract captions from YouTube URLs, get video descriptions and metadata, or process YouTube video text content. Supports residential proxy for reliable caption and metadata fetching (credentials can be auto-loaded from environment or a shell startup file).
.claude/skills/valtterimelkko-youtube-caption/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | -5% | 0% |
| case-07 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 4% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 4% | 0% |
Download captions/transcripts and metadata from any YouTube video using the youtube-transcript-api library with optional residential proxy support.
Required Python package:
bashpip install youtube-transcript-api
Residential Proxy Credentials (auto-loaded from environment or a shell startup file):
bash# Reddit proxy for YouTube caption and metadata fetching export YOUTUBE_PROXY_URL="http://username:password@host:port" # legacy fallback also supported: export REDDIT_PROXY_URL="http://username:password@host:port"
The skill automatically fetches these credentials from the environment or a shell startup file when caption or metadata fetching requires proxy support.
bashpython3 ./scripts/fetch_caption.py --url "https://www.youtube.com/watch?v=VIDEO_ID"
bashpython3 ./scripts/fetch_caption.py --url "https://youtu.be/VIDEO_ID" --metadata-only
bashpython3 ./scripts/fetch_caption.py --url "https://www.youtube.com/watch?v=VIDEO_ID" --captions-only
| Parameter | Required | Default | Description | |-----------|----------|---------|-------------| | --url or -u | Yes | - | YouTube video URL (supports various formats) | | --metadata-only | No | false | Fetch only video metadata (uses proxy) | | --captions-only | No | false | Fetch only captions (uses proxy) | | --language or -l | No | en | Language code for captions (e.g., en, es, fr) | | --output or -o | No | - | Save output to JSON file |
Returns JSON with both captions and metadata:
json{ "success": true, "video_id": "dQw4w9WgXcQ", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "metadata": { "title": "Video Title", "description": "Full video description...", "channel": "Channel Name", "channel_id": "UC...", "published_at": "2025-01-15T10:00:00Z", "duration": "10:30", "duration_seconds": 630, "view_count": 1000000, "thumbnail": "https://i.ytimg.com/vi/...", "links_in_description": [ "https://example.com/link1", "https://example.com/link2" ] }, "captions": { "text": "Full transcript text...", "language": "en", "is_generated": true, "word_count": 1500, "duration_seconds": 630 } }
youtube-transcript-api with residential proxy (to avoid IP blocks)urllib with residential proxy (to bypass YouTube bot detection)YOUTUBE_PROXY_URL, or legacy REDDIT_PROXY_URL)| Error | Cause | Solution | |-------|-------|----------| | TranscriptsDisabled | Video has captions disabled | Try another video | | NoTranscriptFound | No captions in requested language | Try --language with different code | | VideoUnavailable | Video is private/deleted | Check video URL | | ProxyError | Proxy connection failed | Check proxy credentials in your environment or shell startup file |
bashpython3 ./scripts/fetch_caption.py --url "https://www.youtube.com/watch?v=VIDEO_ID" -o output.json
bashpython3 ./scripts/fetch_caption.py --url "https://youtu.be/VIDEO_ID" --language es
bashpython3 ./scripts/fetch_caption.py --url "URL" --captions-only | jq -r '.captions.text'
bashpython3 ./scripts/fetch_caption.py --url "URL" --metadata-only | jq '.metadata.links_in_description'
links_in_description array extracted from the video description| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 25,404 | 9,616 | -62% | 1 | 1 | 0% | 2,350 | 1,973 | -16% | 0 | 0 | — |
case-02 | fail→fail | 6,028 | 3,707 | -39% | 1 | 1 | 0% | 1,092 | 1,769 | +62% | 0 | 0 | — |
case-03 | fail→pass | 10,903 | 3,879 | -64% | 1 | 1 | 0% | 1,951 | 1,854 | -5% | 0 | 0 | — |
case-04 | fail→fail | 8,686 | 8,418 | -3% | 1 | 1 | 0% | 1,709 | 2,844 | +66% | 0 | 0 | — |
case-05 | pass→pass | 13,379 | 10,926 | -18% | 1 | 1 | 0% | 2,770 | 3,504 | +26% | 0 | 0 | — |
case-06 | pass→pass | 10,618 | 7,612 | -28% | 1 | 1 | 0% | 2,238 | 2,847 | +27% | 0 | 0 | — |
case-07 | fail→pass | 9,735 | 3,281 | -66% | 1 | 1 | 0% | 1,965 | 1,783 | -9% | 0 | 0 | — |
case-08 | fail→pass | 8,123 | 4,153 | -49% | 1 | 1 | 0% | 1,603 | 1,675 | +4% | 0 | 0 | — |
case-09 | fail→pass | 8,727 | 2,186 | -75% | 1 | 1 | 0% | 1,266 | 1,426 | +13% | 0 | 0 | — |
case-10 | fail→pass | 8,545 | 2,704 | -68% | 1 | 1 | 0% | 1,532 | 1,592 | +4% | 0 | 0 | — |
case-11 | fail→pass | 8,450 | 3,396 | -60% | 1 | 1 | 0% | 1,393 | 1,818 | +31% | 0 | 0 | — |
case-12 | fail→pass | 5,613 | 3,631 | -35% | 1 | 1 | 0% | 1,039 | 1,729 | +66% | 0 | 0 | — |
case-13 | fail→pass | 8,288 | 3,493 | -58% | 1 | 1 | 0% | 1,544 | 1,571 | +2% | 0 | 0 | — |
case-14 | pass→pass | 8,935 | 8,093 | -9% | 1 | 1 | 0% | 1,482 | 2,428 | +64% | 0 | 0 | — |
case-15 | pass→pass | 12,296 | 2,152 | -82% | 1 | 1 | 0% | 1,984 | 1,461 | -26% | 0 | 0 | — |
case-16 | pass→pass | 10,260 | 2,671 | -74% | 1 | 1 | 0% | 1,668 | 1,621 | -3% | 0 | 0 | — |
case-17 | pass→pass | 3,035 | 1,310 | -57% | 1 | 1 | 0% | 466 | 1,284 | +176% | 0 | 0 | — |
case-18 | pass→pass | 7,372 | 2,726 | -63% | 1 | 1 | 0% | 1,319 | 1,569 | +19% | 0 | 0 | — |
case-19 | pass→pass | 8,111 | 1,823 | -78% | 1 | 1 | 0% | 1,368 | 1,370 | +0% | 0 | 0 | — |
case-20 | pass→pass | 4,157 | 2,066 | -50% | 1 | 1 | 0% | 666 | 1,528 | +129% | 0 | 0 | — |
case-21 | pass→pass | 5,588 | 1,880 | -66% | 1 | 1 | 0% | 862 | 1,444 | +68% | 0 | 0 | — |
case-22 | pass→pass | 4,125 | 2,050 | -50% | 1 | 1 | 0% | 644 | 1,498 | +133% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +36 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.