YouTube Transcripts & Captions Scraper (Subtitles at Scale) avatar

YouTube Transcripts & Captions Scraper (Subtitles at Scale)

Pricing

from $3.50 / 1,000 results

Go to Apify Store
YouTube Transcripts & Captions Scraper (Subtitles at Scale)

YouTube Transcripts & Captions Scraper (Subtitles at Scale)

Extract transcripts and captions from YouTube videos at scale. Returns full text, per-segment timing, and all available languages (manual + auto-generated). For RAG, sentiment analysis, video summarization, and agent workflows. No API key.

Pricing

from $3.50 / 1,000 results

Rating

0.0

(0)

Developer

Thirdwatch

Thirdwatch

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

3

Monthly active users

40 minutes ago

Last modified

Share

Thirdwatch portfolio: 5K users across 88 public Actors, 2M+ records delivered, and >99% run success. Explore all Thirdwatch Actors.

Pull transcripts from any YouTube video — full text plus timestamps, every language track, no API key.

Pull transcripts and closed captions from any YouTube video, at scale, with no API key. Returns the full transcript text plus timestamped segments, all available caption languages, and whether the captions are human-written or auto-generated.

Built for RAG pipelines over video libraries, sentiment analysis, video summarization, accessibility workflows, and agentic tools that read video content.

What you get

A clean, structured transcript record per video. Choose a preferred language or let the actor fall back to whatever's available. Returns both the full joined transcript_text (ideal for vector stores) and a segments array with per-line timestamps (ideal for subtitle overlays and chapter generation).

Output fields

FieldDescription
video_id11-character YouTube video ID
video_urlCanonical watch URL
language_codeActual caption language returned (ISO 639-1)
language_nameHuman-readable language name
is_auto_generatedtrue if auto-captions, false if human-written
auto_translatedtrue if auto-translated into the requested language
available_languagesArray of {code, name, is_auto_generated} for every track on the video
transcript_textFull transcript joined into one string
segmentsArray of {text, start, duration} per caption line
segment_countNumber of caption lines
total_duration_secondsTotal covered duration
data_sourceOrigin tag
used_residential_proxytrue only when the direct request was blocked and the paid fallback succeeded

Failures are not written to the paid result dataset. They are available in the run's ERRORS key-value-store record with codes such as no_captions_available, private_video, region_locked, age_restricted_or_login_required, video_unavailable, no_player_response, transcript_fetch_failed, and empty_transcript.

Example output

{
"video_id": "dQw4w9WgXcQ",
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"language_code": "en",
"language_name": "English",
"is_auto_generated": false,
"auto_translated": false,
"available_languages": [
{"code": "en", "name": "English", "is_auto_generated": false},
{"code": "es", "name": "Spanish", "is_auto_generated": false},
{"code": "en", "name": "English (auto-generated)", "is_auto_generated": true}
],
"transcript_text": "We're no strangers to love You know the rules and so do I ...",
"segment_count": 58,
"total_duration_seconds": 212.48,
"segments": [
{"text": "We're no strangers to love", "start": 18.8, "duration": 7.0},
{"text": "You know the rules and so do I", "start": 25.8, "duration": 3.5},
{"text": "A full commitment's what I'm thinking of", "start": 29.3, "duration": 3.7}
],
"data_source": "youtube_timedtext"
}

Example unbilled error diagnostic (no captions published)

{
"failed_count": 1,
"failed_videos": [
{
"video_id": "abc123XYZ_0",
"video_url": "https://www.youtube.com/watch?v=abc123XYZ_0",
"error": "no_captions_available",
"available_languages": [],
"data_source": "youtube_innertube"
}
]
}

Input parameters

ParameterRequiredDescription
videoUrlsOne ofYouTube URLs. Supports watch?v=, youtu.be/, shorts/, embed/.
videoIdsOne ofRaw 11-character video IDs. Either videoUrls or videoIds must be provided.
languageCodeNoPreferred caption language. Default en.
preferManualNoPrefer human-written captions over auto-generated. Default true.
includeTimestampsNoInclude the segments array. Default true. Turn off for smaller RAG payloads.
includeAutoTranslateNoFall back to YouTube auto-translate if the requested language isn't available. Default false.
useResidentialProxyNoAllow residential retry after a direct IP-dependent failure. Direct HTTP is always tried first. Default true.
maxResultsNoCap on transcripts returned. Default 5, max 10000.

Pricing

Only successfully delivered transcripts are billed. Ordinary direct-HTTP transcripts start at $0.003 per video; subscriber tiers reduce that to $0.0025, $0.002, and $0.0015. If YouTube blocks direct cloud egress and the residential fallback succeeds, that transcript has one additional $0.004 proxy fallback event. Videos without captions and other failed inputs are recorded under ERRORS and are not billed as results.

Use cases

  • AI engineers (RAG): index thousands of talks, lectures, tutorials for semantic search. transcript_text drops straight into your vector store.
  • Content marketers: generate written blog posts, newsletters, and social clips from podcast and YouTube content at scale.
  • Product & research teams: run sentiment analysis across competitor channels and track topic drift over time.
  • Accessibility & compliance: build closed-caption corpora in bulk for ADA / WCAG compliance.
  • Agent builders: plug into Claude / GPT / MCP workflows so an agent can "read" a YouTube URL.
  • Language learners & translators: grab multilingual caption tracks side-by-side for study material.
  • Video summarization tools: feed full transcripts into an LLM to generate chapter markers, key takeaways, and tl;drs.

Limitations

  • Not all videos have transcripts — some uploaders disable captions entirely. Those videos are listed in the unbilled ERRORS record with no_captions_available.
  • Auto-generated transcripts are lower quality — especially for music, accents, and technical content. Set preferManual: true (default) to pick human-written tracks whenever available.
  • Age-restricted and private videos are blocked — they appear in the unbilled ERRORS record rather than the paid result dataset. Region-locked videos behave the same way.
  • YouTube occasionally throttles heavy uninterrupted runs; the actor backs off automatically on rate limits.

Compared to alternatives

  • Apify's pintostudio/youtube-transcript-scraper — similar scope at $0.01 per transcript; our direct path starts at $0.003 and keeps failed videos unbilled.
  • youtube-transcript-api (Python library) — free to run yourself, but you handle the proxy, consent cookie, and retry logic. This actor is a hosted drop-in with built-in reliability.
  • Official YouTube Data API — captions endpoint requires OAuth and channel ownership; not usable for third-party videos.

Pairs well with

  • YouTube Scraper — pull video metadata (title, description, views, likes, channel) first, then feed the IDs here for transcripts.
  • Google News Scraper — enrich news-video transcripts with source articles.
  • Reddit Scraper — cross-reference discussion threads with the video's transcript.

FAQ

Does this work on YouTube Shorts? Yes — youtube.com/shorts/{id} URLs work identically to regular videos.

Do I need an API key? No. The actor uses YouTube's public caption endpoints — no OAuth, no Google Cloud project.

Can I get transcripts for private videos? No. Private videos return a private_video error. Only publicly published videos are supported.

Which languages are supported? Every language a video has published captions for. Use languageCode to pick your preferred track, or enable includeAutoTranslate to cross-translate.

What happens if captions are disabled? The video is omitted from paid results and recorded under ERRORS with error: "no_captions_available", so your pipeline can filter, retry, or skip it without paying for a transcript that was not delivered.

Can I feed this straight into a vector DB? Yes — the transcript_text field is a single joined string designed for RAG ingestion. Turn off includeTimestamps to drop the segments array and shrink payloads further.


Built by Thirdwatch. Questions? Open an issue or reach out on the Apify Store listing.

Last verified: 2026-05