Skip to main content
Extract captions from any YouTube video without an API key. Uses a two-tier approach: fast yt-dlp extraction when available, with browser-based fallback.

Endpoint

POST /youtube/transcript

Request body

url
string
required
YouTube video URL. Supported formats:
  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://www.youtube.com/embed/VIDEO_ID
  • https://www.youtube.com/shorts/VIDEO_ID
languages
string[]
default:"['en']"
ISO 639-1 language codes for caption preference (e.g., ["en", "es", "fr"]). The first available language will be used.

Response

status
string
required
Response status: "ok" on success, "error" on failure
transcript
string
Full transcript text with timestamps in the format:
[00:18] First line of text
[00:23] Second line of text
Only present when status is "ok".
video_url
string
required
Normalized video URL
video_id
string
required
11-character YouTube video ID extracted from the URL
video_title
string
Video title (when available)
language
string
Language code of the returned transcript (e.g., "en", "es")
total_words
number
Word count in the transcript
method
string
Extraction method used: "yt-dlp" (fast) or "browser" (fallback)
available_languages
object[]
List of available caption languages when using browser fallback method

Error response

When status is "error":
code
number
Error code (e.g., 404 for no captions available)
message
string
Human-readable error description

Two-tier extraction approach

Fast path: yt-dlp

When yt-dlp is installed, the server uses it for fast, reliable caption extraction:
  • No browser needed
  • Completes in 2-5 seconds
  • Supports subtitle formats: JSON3, VTT, SRV3
  • Auto-downloads and parses captions
Install yt-dlp:
pip install yt-dlp
# or
brew install yt-dlp

Fallback: Browser intercept

If yt-dlp is not available, the server:
  1. Launches a browser session
  2. Navigates to the video URL
  3. Mutes and plays the video
  4. Intercepts the caption network request (/api/timedtext)
  5. Parses the intercepted caption data
This method is slower (10-20 seconds) and can be interrupted by YouTube ads.

Language selection

Captions are requested in the order specified in the languages array. The first available language is returned. ISO 639-1 codes: Use standard two-letter codes (en, es, fr, de, ja, etc.) or extended codes with region (en-US, pt-BR). If the requested language is unavailable, the endpoint returns an error with available languages listed.

Error codes

CodeMessageCause
400Could not extract YouTube video ID from URLInvalid or malformed URL
400Blocked URL schemeNon-HTTP/HTTPS protocol
404No captions available for this videoVideo has no captions/subtitles
404No captions loaded during playbackBrowser fallback failed (ad blocked playback)
404Caption data intercepted but could not be parsedUnknown caption format
500Internal server errorUnexpected failure

Examples

Basic request

curl -X POST http://localhost:9377/youtube/transcript \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  }'
Response:
{
  "status": "ok",
  "transcript": "[00:18] ♪ We're no strangers to love ♪\n[00:23] ♪ You know the rules and so do I ♪\n[00:28] ♪ A full commitment's what I'm thinking of ♪",
  "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "video_id": "dQw4w9WgXcQ",
  "video_title": "Rick Astley - Never Gonna Give You Up (Official Video)",
  "language": "en",
  "total_words": 548,
  "method": "yt-dlp"
}

Multi-language request

curl -X POST http://localhost:9377/youtube/transcript \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "languages": ["es", "fr", "en"]
  }'
Returns Spanish captions if available, otherwise falls back to French, then English.

Error response (no captions)

{
  "status": "error",
  "code": 404,
  "message": "No captions available for this video",
  "video_url": "https://www.youtube.com/watch?v=example123",
  "video_id": "example123",
  "video_title": "Example Video"
}

Error response (invalid URL)

{
  "error": "Could not extract YouTube video ID from URL"
}

Use cases

  • Analyze video content without watching
  • Generate summaries or key insights from video transcripts
  • Index video content for search
  • Accessibility: convert video content to text
  • Multi-language content analysis
  • Research and data extraction from educational videos

Performance

MethodTypical DurationNotes
yt-dlp2-5 secondsRecommended for production
Browser fallback10-20 secondsCan fail if YouTube shows ads

Limitations

  • Videos without captions will return a 404 error
  • Private or age-restricted videos may fail
  • Browser fallback can be interrupted by YouTube ads or anti-bot measures
  • The endpoint does not bypass YouTube’s Terms of Service - use responsibly

See also

Build docs developers (and LLMs) love