Extract a YouTube Video's English Transcript as Structured Data
Pull a YouTube video's English subtitles as timestamped segments with full video metadata — no API key, ready for analysis or archiving.

A video's spoken content is useless to a pipeline until it is text. Thirdwatch's YouTube Subtitle Scraper returns every caption track a video offers as timestamped segments plus full video metadata — no API key, no OAuth.
Skip the setup: Run this as a ready-to-go task on Apify — pre-loaded with the configuration from this guide.
Why extract a video's transcript
YouTube hosts the largest archive of spoken-word content on the internet, but transcripts sit behind the watch page and an OAuth-gated API. For a single video the fix is copying the transcript panel; for a research dataset, competitor audit, or accessibility review you need captions as structured data.
The useful unit is one row per video: which segments exist, when each starts, whether the text was human-written or machine-generated, and the video metadata you would otherwise need a second call to get.
The subtitle scraper reads the public caption endpoints directly, so the batch path is a list of URLs in and transcript rows out.
How does this compare to the alternatives?
| Approach | Cost model | Coverage | Effort |
|---|---|---|---|
| YouTube Data API + OAuth | Quota-limited, free tier | Only authorised captions / own channel | Key + OAuth setup |
| Manual transcript-panel copy | Analyst hours | One video at a time | Doesn't scale |
| Thirdwatch YouTube Subtitle Scraper | Pay per video row | All public caption tracks | Zero setup |
Why this Actor
- Manual and auto-generated tracks both supported —
captionSourcelabels which you got. - Every segment carries
startMs,durationMsandtext, so timestamp-level alignment survives. availableLanguageslists every track the video offers — discovery and extraction in one pass.- Each video gets its own proxy session with a fresh-exit retry, so multi-video batches stay reliable.
- Full metadata on the row: title, channel, duration, view count, upload date.
How to do it in 3 steps
Step 1: Configure the input
Set the inputs as shown below — videoUrls takes the targets, languages picks the caption language(s) and preferManual chooses human-written over auto-generated tracks.
Step 2: Run the Actor
Run it from the console, the API, or the linked saved task. One dataset row is written per video.
Step 3: Use the output
Each row carries the video metadata, the caption track as segments (with startMs/durationMs/text), and the joined transcript string.
{
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ"
],
"languages": [
"en"
],
"preferManual": true,
"proxyCountry": "US"
}Each dataset row looks like:
{
"videoId": "dQw4w9WgXcQ",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up (Official Video)",
"channel": "Rick Astley",
"language": "en",
"captionSource": "manual",
"segmentCount": 61,
"segments": [
{
"startMs": 18170,
"durationMs": 2290,
"text": "We're no strangers to love"
}
],
"transcript": "We're no strangers to love ..."
}What to watch for
Heavily scraped videos sometimes return a 429 on the caption file even after the fresh-exit retry — those come back as error rows, not silent gaps. Videos with no captions at all behave the same way, which is itself a useful audit signal.
Related use cases
- Harvest YouTube Subtitles in Multiple Languages at Once
- Audit Which YouTube Videos Only Have Auto-Generated Captions
- Build a Transcript Dataset from a Batch of Lecture Videos
- Turn YouTube Podcast Episodes into a Searchable Transcript Corpus
- All Thirdwatch use-case guides
Run the YouTube Subtitle Scraper on Apify Store — pay per result, free to try, no credit card to test.
Frequently asked questions
Do I need a YouTube API key?
No — the Actor reads the public caption endpoints, so there is nothing to provision.
What languages work?
Any language the video ships a track for. Pass ISO 639-1 codes in `languages`, or omit it and read `availableLanguages` on the row to see what exists.
Auto captions or human captions?
Both are supported. `preferManual` prefers human-written tracks; `captionSource` on the row tells you which type was actually returned.
Why did one video return an error row?
Heavily scraped videos occasionally hit a caption-side rate limit. The Actor retries once on a fresh proxy session; a persistent failure comes back as an `error` row you can retry.
Can I get plain text without timestamps?
Yes — `transcript` is the segments joined into one string. Keep `segments` too if you want timestamp-level retrieval.
How many videos per run?
Dozens comfortably — each video gets an isolated proxy session, so batch size is bounded by run timeout rather than rate limits.