YouTube Transcript Scraper with SRT and VTT
Pricing
from $2.00 / 1,000 transcripts
YouTube Transcript Scraper with SRT and VTT
Extract existing YouTube video and Shorts captions from URLs or IDs. Get full text, timestamped segments, caption languages, basic video details, and optional SRT/VTT files for research and LLM workflows. No YouTube API key or account required. Independent tool, not affiliated with YouTube.
Pricing
from $2.00 / 1,000 transcripts
Rating
0.0
(0)
Developer
Arjun AI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Get existing YouTube video and Shorts transcripts from URLs or video IDs. Export the selected caption track as full text, timestamped segments, or downloadable SRT and WebVTT files, with caption languages and basic video details. No YouTube API key or YouTube account is required.
The Actor reads captions already supplied by YouTube. It does not download video/audio, transcribe speech, translate text, or create AI summaries. It is an independent tool, not affiliated with YouTube or Google.
What can you do with YouTube transcripts?
- Prepare caption text for your own LLM, search index, or RAG workflow while keeping timestamps and source video IDs.
- Collect existing captions from interviews, talks, tutorials, and Shorts for research and content review.
- Download SRT/VTT subtitles for editing or playback, without downloading the video.
- Choose uploaded or automatic captions, require a particular language, or allow a clearly reported language fallback.
- Process up to 100 inputs in a run, with one selected track per unique video and no extra result for each segment or file format.
Quick start
- Add video or Shorts URLs, or 11-character IDs, to Video / Shorts URLs or IDs.
- Keep Preferred caption languages set to Auto to use the video's default caption language. To request a specific language, remove Auto and select its name from the dropdown.
- Run the Actor and open Transcripts and input statuses in the Dataset.
- Export JSON, CSV, Excel, or other Dataset formats. To download SRT/VTT, select the formats before running, then open the Subtitle file downloads Dataset view or Storage → Key-value store.
{"videos": ["https://www.youtube.com/watch?v=UF8uR6Z6KLc","https://www.youtube.com/shorts/cjSKS1D9Kow","https://www.youtube.com/watch?v=Vs-bzi-jNiE"]}
These inputs were verified in cloud runs and cover an English talk, an English Short, and a Chinese interview. Availability and source captions can change.
Want to save captions directly to a spreadsheet? Use the ready-to-import n8n workflow and Google Sheets setup guide.
What you receive
One selected caption track is returned per unique video ID. Duplicate watch links, shortened links, Shorts links, and IDs for the same content are processed once in a run.
The complete fetched track is returned without a character, segment, or video-duration truncation setting. This does not guarantee that the source captions cover every spoken word. An uploaded track can be incomplete, and YouTube's automatic captions can contain recognition errors.
Input reference
| Parameter | Type | Default | Description |
|---|---|---|---|
videos | string array | Three example videos | Required; 1–100 video/Shorts URLs or IDs. Channel, playlist, and search inputs are not supported. |
languages | string array | ["auto"] | Dropdown multiselect with readable names for common languages; custom caption codes are also accepted. Select up to 10 in priority order. Remove Auto before selecting specific languages. The underlying values remain codes such as en, zh-Hans, and ja. |
captionType | string | preferManual | preferManual, preferAuto, manualOnly, or autoOnly. Preferences apply within the matching language. |
fallbackToAnyLanguage | boolean | true | Allow another available language if none of the requested languages is found. The actual language is always reported. Only-type restrictions remain in force. |
includeSegments | boolean | true | Include every timestamped segment. When false, omit segments; full text and requested subtitle files are still returned. |
subtitleFormats | string array | [] | Optional srt, vtt, or both. Files are generated locally from the fetched track without another YouTube request. |
In the form, Caption type uses “uploaded captions” for tracks not marked auto-generated by YouTube. Prefer uploaded captions is the recommended default; Uploaded captions only never substitutes an auto-generated track. The API values preferManual and manualOnly remain unchanged.
For most runs, enter your videos and keep the defaults. If you require a particular language, remove Auto, select that language, and turn Allow another language off. Leave Subtitle files (optional) empty unless you need SRT/VTT. Turn Include timestamped segments off only when you want a smaller result, not fewer requests.
Supported links include youtube.com/watch?v=…, youtu.be/…, youtube.com/shorts/…, youtube.com/embed/…, and public live-replay URLs. A bare ID does not identify whether an upload is a regular video or Short; the same caption retrieval works for both.
Language and caption selection
The form offers Auto plus 33 common language choices. Select a language by name instead of memorizing its code. If a code is not listed, enter it as a custom value. These are convenient suggestions, not a promise that every video has those tracks or an exhaustive list of YouTube caption languages.
For automatic selection, keep Auto by itself. For a specific language, remove Auto first; an Auto entry placed first would otherwise take priority. The selected array order is the language priority. Use the JSON editor to inspect or change the order when multiple languages are selected, for example ["zh-Hans", "zh-Hant", "en"].
The Actor evaluates your language list in order. An exact language code is preferred; a broad code such as en can match en-US. Common equivalent Chinese codes (zh-CN/zh-Hans and zh-TW/zh-Hant) are recognized. auto follows YouTube's default caption selection when supplied. Otherwise it checks captions associated with the default audio track, preferring the audio track's language or a regional variant before the first associated caption. Only when these hints are unavailable does it fall back to an automatic-caption track, then the first available track. It does not transcribe audio to detect its language.
preferManual and preferAuto allow the other type if the preferred type is absent. manualOnly and autoOnly never switch type. If no suitable track exists, a languageUnavailable row explains why and lists available tracks.
Manual means the track is not marked asr by YouTube. It does not independently certify human authorship, accuracy, or complete coverage. Available tracks can include the same language twice, once for each type.
{"videos": ["Vs-bzi-jNiE"],"languages": ["zh-Hans", "en"],"captionType": "manualOnly","fallbackToAnyLanguage": false,"includeSegments": true,"subtitleFormats": ["srt", "vtt"]}
This requests an existing Simplified Chinese uploaded track first, then English. It does not translate English into Chinese.
Dataset fields
Successful records have recordType: "transcript" and status: "success".
| Fields | Meaning |
|---|---|
inputValue, videoId, url | Original input, case-sensitive content ID, and canonical watch URL. |
title, description, durationSeconds, thumbnailUrl, viewCount | Basic video information from the same player response. Source-dependent metadata can be null. |
channelId, channelName, channelUrl | Basic publishing-channel identity. No separate channel profile lookup is performed. |
languageCode, languageName | The caption track actually returned. |
isAutoGenerated | Whether the source track is marked asr by YouTube. |
isTranslated | False in this version; no automatic translation is requested. |
availableLanguages | Available track language codes, labels, and automatic-caption indicators. No temporary caption URLs are exposed here. |
transcriptText | All fetched, nonempty caption text, joined with newlines in source order. |
segments | Optional complete array of { "text": "…", "start": 0.0, "duration": 1.5 }; times are seconds. Missing source duration is null. |
subtitleFiles | Requested file formats, filenames, and Key-Value Store record keys. Platform runs also include file URLs. |
warnings | Present only when there is a relevant caption note, such as a track ending unusually early. |
scrapedAt | UTC time when the result was created. |
The text, timing, metadata, and track properties originate from YouTube. Field names, canonical URLs, joined full text, subtitle formats, statuses, and warnings are normalized or produced by this Actor. It does not add analysis scores, token counts, or network diagnostic fields to successful Dataset records.
Real YouTube Shorts output example
The following excerpt comes from a verified cloud result. Only selected fields and the first caption segment are shown to keep this example short. The actual transcriptText and segments contain the complete fetched track, not just this excerpt.
{"recordType": "transcript","status": "success","videoId": "cjSKS1D9Kow","url": "https://www.youtube.com/watch?v=cjSKS1D9Kow","durationSeconds": 29,"channelName": "Sabrina Ramonov 🍄","languageCode": "en","isAutoGenerated": true,"isTranslated": false,"transcriptText": "Don't pay for another AI course that","segments": [{"text": "Don't pay for another AI course that","start": 0.0,"duration": 3.6}]}
SRT and WebVTT
To generate both downloadable formats, select SRT and VTT in Subtitle files (optional), or use this input:
{"videos": ["https://www.youtube.com/shorts/cjSKS1D9Kow"],"languages": ["en"],"fallbackToAnyLanguage": false,"includeSegments": false,"subtitleFormats": ["srt", "vtt"]}
File references are included only for requested formats. Leaving subtitleFormats empty does not generate files. Setting includeSegments to false only removes the JSON segment array: full text and requested files are still returned.
In the Dataset, open the Subtitle file downloads view and inspect subtitleFiles. Each entry contains format, fileName, recordKey, and, on Apify, a file url. You can also download the files from the run's Storage → Key-value store. File-link access follows the storage permissions; a link is not a promise of unrestricted public access.
SRT and VTT are generated from the same fetched segments, without another YouTube request. They do not produce extra transcript-result events. Local runs expose recordKey and fileName without a cloud file URL.
Cue ends normally use native start plus duration. When a duration is missing, export uses the next cue's start, or the video end for the last cue when available. The JSON segment keeps its original null duration.
Early-ending captions
A source track can cover only part of a video. The Actor may include a CAPTIONS_END_EARLY warning when the selected track ends unusually early. This is a heuristic note, not proof of missing speech: a long silent ending can also trigger it. The result still contains all fetched text from the selected track; no different-language text or AI-generated content is substituted.
Status rows and run summary
When an input cannot yield a transcript, the Dataset receives recordType: "transcriptStatus", the input value, a status code, a readable message, and a suggestion describing the next action. retryable indicates whether a temporary request failure may succeed on a later run; it does not schedule another automatic retry. Video metadata and empty subtitle arrays are not added to these rows.
The default Dataset table puts What happened, Recommended action, and Can retry later near the beginning, so unsuccessful inputs are understandable without opening the run logs. These fields are only added to status rows, not successful transcripts.
| Status | Meaning |
|---|---|
noTranscript | The playable video returned no available caption track. |
languageUnavailable | The requested language or strict caption type was unavailable. |
invalidInput | The value was not a supported YouTube video URL or ID. |
unavailable | The video could not be accessed publicly, for example because it is private, removed, or restricted. |
requestBlocked | YouTube rejected the request or returned an empty response for a listed track. This is not treated as proof of no captions. |
failed | A network timeout, server error, or unreadable response prevented extraction. |
chargeLimitReached | The budget did not allow this input to be processed or its transcript to be saved. |
Example status shape:
{"recordType": "transcriptStatus","status": "noTranscript","inputValue": "https://www.youtube.com/watch?v=aqz-KE-bpKQ","videoId": "aqz-KE-bpKQ","url": "https://www.youtube.com/watch?v=aqz-KE-bpKQ","errorCode": "NO_TRANSCRIPT","message": "YouTube returned no available caption tracks for this video.","retryable": false,"suggestion": "Check captions on YouTube or use another video. This Actor does not generate captions."}
For request failures, REQUEST_TIMEOUT means that the HTTP request or overall retrieval reached its time limit. NETWORK_ERROR means another network failure prevented the request from completing. The message identifies whether the Actor was fetching video information or downloading a known caption track when that context is available. Neither code is evidence that captions are missing, and neither should be treated as noTranscript or proof that the video is unavailable. Low-level network error types and curl codes stay in OUTPUT, not the Dataset.
The run's OUTPUT record reports result totals, duplicate inputs skipped, per-input outcomes, timings, and whether the budget was reached. A run containing only normal no-caption or unavailable outcomes can complete successfully. If every request fails technically or is blocked, the run fails after writing its status rows and summary.
Pricing
The price is $2 per 1,000 successfully saved transcripts ($0.002 each), plus $0.00005 per Actor start at the supported 256–1024 MB memory settings. Platform usage is included. Full text, requested timestamped segments, and requested SRT/VTT files are included in the same transcript price, with no format add-ons or current volume discounts. Check the Actor's Pricing tab for the applicable rates.
The implementation uses the custom event youtube-transcript: one event for one successfully saved selected caption track, regardless of the number of segments or requested file formats. Duplicate IDs, no-caption inputs, invalid inputs, unavailable videos, blocked requests, and failed requests do not trigger this event. A fetched native track carrying an early-ending warning is still a delivered track, not a guarantee of full-video speech coverage.
Status rows do not trigger transcript-result events, and there is no separate Dataset-item fee. The Actor Start fee still applies when no transcript is returned. API and export formats do not change the transcript unit: one successfully saved selected track is one result. For example, one run delivering 10 transcripts costs $0.02005 at the supported memory settings.
The Actor observes the maximum run charge and stops accepting further paid results when another event is unaffordable. A few requests already in progress may finish while the remaining budget is being used; their transcripts are not delivered or charged over the limit.
Performance and limits
The normal path uses one player request and one caption request per video. Up to three videos are processed concurrently, and completed results are written immediately. No video/audio file is downloaded.
Each video's initial retrieval attempt has a 12-second total limit. A retryable request may use a fallback attempt, limited to 20 seconds per HTTP request. If that fallback is blocked by an automated-traffic check or returns an empty caption body, one additional attempt with a new network session is allowed. Both fallback attempts share the same 40-second total budget; timeouts and ordinary network errors do not trigger the additional attempt. These are upper limits, not fixed waits or response-time guarantees. They apply per video, not to the whole run, and do not include container startup or task queueing. A download interrupted by a timeout is reported as a status, not saved as a successful partial transcript. Other inputs continue processing.
Captions may be missing for a public video. Live streams still in progress and newly uploaded videos may not have finalized captions. Recognition quality and punctuation are determined by the source. Rolling automatic-caption timing is preserved; it is not independently aligned word or speaker timing.
The default memory is 512 MB. Processing time varies with caption availability and network conditions. There is no fixed seconds-per-video promise, unlimited automatic retry, speech-recognition fallback, channel expansion, or playlist expansion.
YouTube transcript API and integrations
Use the Actor's API tab for generated examples, or call the Apify API from your own workflow. An Apify account is required; API calls use an Apify token, not a YouTube API key.
curl --request POST \--url 'https://api.apify.com/v2/acts/arjun_code~youtube-transcript-scraper/run-sync-get-dataset-items' \--header 'Authorization: Bearer YOUR_APIFY_TOKEN' \--header 'Content-Type: application/json' \--data '{"videos":["https://www.youtube.com/shorts/cjSKS1D9Kow"],"languages":["en"],"subtitleFormats":["srt","vtt"]}'
Read the returned Dataset items and follow subtitleFiles[].url for requested subtitle files. For larger jobs, start an asynchronous run and retrieve its Dataset when it finishes. Apify also provides scheduling, webhooks, and integrations for connecting the output to your existing tools.
Save YouTube transcripts to Google Sheets with n8n
Use the workflow JSON, setup guide, and real output examples to save existing captions without writing your own integration.
- Import the workflow JSON into n8n and connect your own Apify and Google Sheets credentials.
- Prepare the eight worksheet headers listed in the guide, then set
videoUrl,spreadsheetUrl, andsheetNamein Workflow input. - Run manually. A successful transcript adds one row with the video ID, title, URL, channel, caption language, automatic-caption flag, full fetched text, and extraction time.
Missing-caption and request-failure records follow a separate status branch rather than becoming blank spreadsheet rows. This example handles one video per execution and appends a new row when a successful URL is run again; it does not transcribe audio or generate summaries.
The workflow has no separate template fee. Actor pricing still applies, and n8n or Google services may have their own charges. The linked package is available on GitHub; it is not an approved n8n template-library listing.
FAQ
Does this create transcripts for videos without subtitles?
No. It returns existing YouTube caption tracks. It does not run speech recognition or an LLM.
Can I get every available language in one run?
This version selects one track per video. availableLanguages lists existing tracks so you can choose another language for a later run. Translation target lists are not advertised as existing captions.
Why did I get another language?
fallbackToAnyLanguage defaults to true. Set it to false to require a language from your priority list. Check languageCode in each result.
Does this support Chinese captions?
Yes, when the video already offers a matching track. Select Chinese (Simplified) (zh-Hans) or Chinese (Traditional) (zh-Hant), remove Auto, and disable Allow another language if you require Chinese. The Actor recognizes equivalent source codes such as zh-CN and zh-TW and reports the actual source code. It does not translate another language into Chinese.
Why are there no subtitle files in my result?
Files are optional and off by default. Select SRT and/or VTT before running, then inspect subtitleFiles or Storage → Key-value store. Choosing an export format in the Dataset toolbar exports the Dataset; it does not enable SRT/VTT generation for the Actor.
Why did a public video fail?
A public video may lack captions, lack the requested language, be restricted for the request, or encounter a temporary network failure. Read the status row's message and suggestion. retryable: true means a later run may succeed; it does not mean the Actor will keep retrying or that success is guaranteed.
Can I collect all videos from a channel?
Use YouTube Channel Content Scraper or YouTube Search Scraper to discover videos, then pass their URLs or IDs to this Actor.
For detailed metrics and video metadata, use YouTube Video Details Scraper. For discussion text, use YouTube Comments Scraper.
How do I report a problem?
Open the Actor's Issues tab with the run ID, affected video ID, relevant settings, and whether the requested captions are visible on YouTube. Share the status message when available. Do not share tokens, cookies, or account credentials.
Related YouTube tools
- YouTube Search Scraper: discover video, channel, and Shorts URLs from keywords.
- YouTube Channel Content Scraper: list a channel's videos, Shorts, and streams before passing selected IDs here.
- YouTube Video Details Scraper: collect detailed video metadata and metrics.
- YouTube Channel Details Scraper: look up publishing-channel profiles.
- YouTube Comments Scraper: collect public discussion text separately from captions.
Responsible use
This independent tool is not affiliated with or endorsed by YouTube or Google. Existing captions can contain errors or cover only part of a video. Use the output only where you have permission and comply with source terms and applicable privacy and copyright requirements.