YouTube Transcript Scraper - Text, SRT & VTT avatar

YouTube Transcript Scraper - Text, SRT & VTT

Pricing

from $2.40 / 1,000 results

Go to Apify Store
YouTube Transcript Scraper - Text, SRT & VTT

YouTube Transcript Scraper - Text, SRT & VTT

Export available YouTube captions as text, timestamped segments, SRT, VTT or JSON. Choose preferred languages or require manual captions. Returns caption counts and an optional video title. Source access and translation availability vary.

Pricing

from $2.40 / 1,000 results

Rating

0.0

(0)

Developer

Ben

Ben

Maintained by Community

Actor stats

0

Bookmarked

148

Total users

3

Monthly active users

4 hours ago

Last modified

Share

YouTube Transcript Scraper: text, SRT and VTT captions

Extract caption tracks available on a YouTube video, select a language and export readable text or subtitles. Each successful row keeps the original timestamped segments alongside your chosen output format. The Actor uses existing captions; it does not transcribe audio or create captions for a video that has none.

Open the tested video example, or paste your own video URLs into the input form. No separate API key is required. Availability depends on the video's caption tracks and current source access.

Price: Free-plan result events cost $3 per 1,000 returned video rows, plus the start event. Unavailable-caption rows are also charged results. Start with one known video and check transcript_available before scaling.

Quick start

Start with one video and inspect the returned language and transcript_available before processing a batch:

{
"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"preferredLanguages": ["en"],
"includeAutoGenerated": false,
"outputFormat": "srt",
"includeVideoMetadata": false,
"maxVideos": 1
}

The SRT content is in formatted_transcript. segments remains a structured array with text, start and duration, so you can use the same row for subtitle export and text analysis. The dataset's Formatted captions view shows the selected format; Transcript overview shows video identity, language and counts.

Choose a caption track

InputBehavior
videoUrlsYouTube URLs or 11-character video IDs. Duplicate IDs are processed once. Invalid input fails before fetching videos.
preferredLanguagesLanguage codes in priority order, such as ["en-US", "en", "de"]. Manual captions take precedence within a language. An empty list accepts any available language.
includeAutoGeneratedtrue allows generated caption tracks; false accepts only manual tracks. Default: true.
translateToTranslate the selected track if YouTube offers the requested language. Empty preserves the original language.
outputFormattext, timestamped, srt, vtt or json. Default: text.
includeVideoMetadataFetch the title through public oEmbed. false skips that request and returns a null title. This option does not fetch view counts or video duration.
maxVideosCap the number of distinct videos. The form defaults to three; 0 removes the item cap, subject to the run's timeout and spending limit.

An unavailable preferred language is reported explicitly. The Actor does not silently substitute a language outside the list. To permit any language, use preferredLanguages: [].

Translation limitation, September 10, 2026: both French-translation cloud checks encountered a source access block, while original English caption exports returned data. Translation selection passes offline checks, but translated-track delivery remains unverified. Start with original captions for production workflows.

Accepted URL forms include watch?v=, youtu.be/, embed/, shorts/ and live/. Existing API aliases videos, startUrls and languages remain accepted; use the documented form fields for new integrations.

Output fields

FieldMeaning
video_id, video_urlNormalized YouTube identity and canonical URL.
titleVideo title when metadata is enabled and available; otherwise null.
transcript_availableWhether a usable caption track was returned for the selected options.
language, source_languageReturned language and original caption-track language.
is_generatedWhether the original caption track was autogenerated.
is_translatedWhether the selected track was translated into a different language.
segmentsCaption text with start times and durations in seconds.
segment_count, word_countCounts for the returned captions.
full_textCaption text joined with spaces. The legacy includeFullText: false option omits this duplicate text.
output_format, formatted_transcriptRequested format and its string content. JSON output is a serialized segment array.
scraped_atUTC collection timestamp.
error, error_typeExplanation when the requested captions or translation are unavailable.

This abbreviated segment comes from the September 9, 2026 example run; timings are in seconds:

{
"video_id": "dQw4w9WgXcQ",
"language": "en",
"is_generated": false,
"transcript_available": true,
"segments": [{"text": "[♪♪♪]", "start": 1.36, "duration": 1.68}],
"segment_count": 61,
"word_count": 487
}

Only the first segment is shown; the counts describe the complete dated transcript. Caption tracks can change after collection.

Save subtitle files

Choose srt or vtt, download the dataset as results.json, then run this standard-library Python example in your virtual environment:

import json
import re
from pathlib import Path
for row in json.loads(Path("results.json").read_text()):
if not row.get("transcript_available"):
continue
video_id = row["video_id"]
output_format = row["output_format"]
if not re.fullmatch(r"[A-Za-z0-9_-]{11}", video_id) or output_format not in ("srt", "vtt"):
raise ValueError("Expected a video ID and SRT/VTT output")
Path(f"{video_id}.{output_format}").write_text(row["formatted_transcript"], encoding="utf-8")

The other formats support different workflows: text keeps one caption per line, timestamped prefixes each line with its start time in seconds, and json preserves the segment objects. This is caption extraction, so the Actor does not summarize, translate through another provider or generate embeddings.

Costs and failure handling

The Free-tier result event is $0.003 per returned video row, with a $0.00005 start event per GB of allocated memory, minimum one. Plan discounts apply. Unavailable-caption rows are still returned results and incur that result event; inspect the selected options before scaling a batch. Check the Pricing tab for current terms and set a maximum run charge.

Known missing-video, missing-caption, unmatched-language and unsupported-translation conditions return transcript_available: false with an error type. Access, network, parsing and storage failures fail the run instead of being labeled “no captions.” A failed batch may already contain completed rows; preserve them and inspect the run status before retrying. Invalid input does not trigger a substitute demo video.

Common questions

Can it create captions for a video with none? No. It downloads available caption tracks. Speech recognition requires a separate transcription tool and appropriate rights to the audio.

Does turning off autogenerated captions also forbid translation? No. It selects a manual source track; translateTo can still request an offered translation. is_generated describes the source track, while is_translated describes the returned text.

Can it return a different language if my preference is missing? Only if you listed that language or supplied an empty preference list. A translation must also be offered by YouTube for the selected track.

Why is the title null? Metadata may be disabled or its oEmbed request may be unavailable. Caption availability and metadata availability are separate.

Can I automate this? Use the saved Task, Apify API or an n8n/Make workflow. Keep a list of successfully processed video IDs downstream if you want to avoid processing them again; this Actor does not maintain a cross-run deduplication database.

Use caption data only where you have the necessary rights and follow YouTube's terms. The Actor does not retrieve private or unavailable tracks.