YouTube Transcript Scraper — Pay Per Result, No Empty Charges avatar

YouTube Transcript Scraper — Pay Per Result, No Empty Charges

Pricing

from $5.00 / 1,000 results

Go to Apify Store
YouTube Transcript Scraper — Pay Per Result, No Empty Charges

YouTube Transcript Scraper — Pay Per Result, No Empty Charges

Extract transcripts/subtitles from YouTube videos in bulk. Paste URLs or IDs — get clean text, timestamped segments, SRT/VTT subtitle files, and video metadata (title, channel, views). Pay per result — videos without captions are never billed.

Pricing

from $5.00 / 1,000 results

Rating

0.0

(0)

Developer

Sergei Peleskov

Sergei Peleskov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

YouTube Transcript Scraper — bulk captions & subtitles extractor

Scrape YouTube transcripts, subtitles and captions in bulk. Paste a list of video links or IDs and get back clean, LLM/RAG-ready text plus timestamped segments for every video that has captions. Pay per result — videos without captions, or videos that are unavailable, are never billed.

Works with regular videos, YouTube Shorts, live VOD, and bare video IDs. No proxies, no YouTube API keys, no scraping setup on your side.

Why this Actor

This Actor vs typical transcript scrapers

This ActorTypical transcript scrapers
Pay for videos without captions❌ Never — skipped, not billed✅ Charged per call, you get data: null
Input formats✅ watch / youtu.be / Shorts / embed / live / mobile / bare IDs, mixed⚠️ One rigid URL field, confusing mutually-exclusive inputs
Output✅ Both plain text AND timestamped segments, always⚠️ One format, join/split is your problem
Subtitle file export✅ Ready-to-save SRT and VTT on demand⚠️ Rare — build the file yourself
Channel/playlist listing✅ List every video first, pay transcripts only for the ones you pick❌ One-shot channel scrape — you pay for the whole channel blind
Batch in one run✅ Hundreds of videos⚠️ Often one video per run
Skipped videos explained✅ Human-readable reason per video in OUTPUT❌ Silent nulls
Platform usage on top✅ Never — all-inclusive❌ Compute + proxy billed separately

Price on the tag vs price on the invoice

Most transcript scrapers charge $X /1,000 videos + Apify platform usage on top (compute units, proxy, storage). The sticker price is not the final price.

This Actor is pay-per-result, all-inclusive: $5.00 /1,000 successful transcripts already covers residential proxies, retries, and compute. No platform usage line on your bill. Videos without captions are never billed.

Run 1,000 videos, get a predictable invoice. That's the whole pricing model.

What it does

Give it a list of YouTube videos — full links, short links, Shorts, or bare video IDs, mixed however you like — and it returns each video's transcript as both plain text and timestamped segments. You can batch hundreds of videos in one run. There's no scraping setup, no proxies, and no YouTube API keys to manage on your side: reliability (retries, residential IP rotation, rate-limit handling) is handled for you. Videos that genuinely have no captions are reported separately and cost you nothing.

Use cases

  • LLM & RAG pipelines — feed clean transcript text straight into embeddings, summarization, or chat-with-video apps
  • Content research & repurposing — turn videos into articles, newsletters, show notes
  • Subtitle & caption workflows — timestamped segments ready for SRT/VTT generation or alignment
  • SEO & competitive analysis — analyze what competitor channels actually say, at scale
  • Search & indexing — make video libraries full-text searchable

Input

FieldTypeRequiredDescription
modestringnotranscripts (default) — get transcripts of the videos in videoUrls. listVideos — list every video of one channel/playlist in videoUrls (no transcripts).
videoUrlslist of stringsyesTranscripts mode: one video per line (links or IDs, mixed), max 500 per run. List-videos mode: exactly one channel/playlist reference (@handle, /channel/UC…, /playlist?list=…, or a bare playlist/UC id).
languagestringnoTranscripts mode only. Preferred transcript language code (en, es, pt-BR). Leave empty for the video's default.
strictLanguagebooleannoIf true, a video is skipped when the exact language isn't available (instead of falling back). Default false.
subtitleFormatstringnoAdd ready-to-use subtitle file content to each result: none (default), srt, vtt, or both. Does not change pricing.

Supported link forms: youtube.com/watch?v=…, youtu.be/…, youtube.com/shorts/…, /embed/…, /live/…, and their m. mobile variants — plus bare video IDs.

Examples

1. Mixed links and IDs

{
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/jNQXAC9IVRw",
"9bZkp7q19f0"
]
}

2. Prefer Spanish, fall back if unavailable

{
"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"language": "es"
}

Not sure which language a video is in? Leave language empty and keep strictLanguage off — you'll always get whatever transcript the video has.

3. Strict: only Spanish, skip otherwise

{
"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"language": "es",
"strictLanguage": true
}

4. Also get subtitle files (SRT + VTT)

{
"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"subtitleFormat": "both"
}

Each result then also carries ready-to-save srt and vtt fields.

Output

Each successful video becomes one dataset item:

{
"videoId": "dQw4w9WgXcQ",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"language": "en",
"kind": "manual",
"requestedLanguageMatched": true,
"video": {
"title": "Rick Astley - Never Gonna Give You Up",
"channel": "Rick Astley",
"channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
"durationSec": 213,
"viewCount": 1694000000
},
"segments": [
{ "startMs": 0, "durationMs": 1200, "text": "..." }
],
"text": "full transcript as plain text ...",
"srt": "1\n00:00:00,000 --> 00:00:01,200\n...\n",
"vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:01.200\n...\n"
}
  • text is the whole transcript as one plain-text string — ready to drop into an LLM prompt or a RAG pipeline.
  • segments gives you the same text split into timestamped chunks (startMs, durationMs) for captioning, search, or alignment.
  • video is always included: title, channel, channelId, durationSec, viewCount (any field may be null if YouTube omits it).
  • srt / vtt are included only when you set Subtitle file format (srt, vtt, or both) — ready-to-save subtitle file content.
  • kind is manual (human-written) or asr (auto-generated).
  • requestedLanguageMatched is true/false when you asked for a language (false = a fallback track was returned), or null when you didn't.

Skipped videos are not in the dataset. A per-run summary is written to the key-value store record OUTPUT, listing every skipped video with a plain-English reason (no captions, unavailable, etc.).

List all videos of a channel

Set What to get to List all videos of a channel or playlist (mode: listVideos) and put exactly one channel or playlist reference in videoUrls. You get one dataset item per video — no transcripts, much cheaper — so you can see a channel's whole catalogue before spending anything on transcripts.

Input:

{
"mode": "listVideos",
"videoUrls": ["https://www.youtube.com/@MrBeast"]
}

Accepted references: a channel link (youtube.com/@handle or /channel/UC…), a playlist link (youtube.com/playlist?list=…), or a bare playlist / UC… id. Exactly one — more than one entry, or a single video link, fails the run before anything is billed.

Each item:

{
"videoId": "GvgqDSnpRQM",
"url": "https://www.youtube.com/watch?v=GvgqDSnpRQM",
"title": "Andrew Willis, Skatepark Engineer",
"channel": "Google Search Stories",
"durationSec": 90,
"position": 1,
"source": { "type": "playlist", "id": "PLBCF2DAC6FFB574DE", "url": "https://www.youtube.com/playlist?list=PLBCF2DAC6FFB574DE" }
}

position is the 1-based order as YouTube returns it (newest first). title/durationSec are best-effort and may be null. Very large channels are capped; if so the run still returns the list it got and notes it in the OUTPUT summary.

Listing results are written to a dataset named video-list (not the default dataset) — open it from the run's Storage tab. This keeps listing billed at the cheap per-video rate, separate from transcript results.

Listing price: $0.50 / 1,000 videos listed — 10× cheaper than transcripts, so previewing a channel is nearly free.

Recipe: preview a channel, then pay only for what you want

  1. Run listVideos on the channel @handle → get every videoId (cheap).
  2. Skim titles/durations, pick the videos you actually need.
  3. Run transcripts mode with just those IDs in videoUrls.

You pay full transcript price only for the videos you chose — not the whole channel. One-shot "scrape the whole channel" actors can't do this: they transcribe (and bill) everything blind.

Pricing

Pay per result. You only pay for successful transcripts — videos without captions, unavailable videos, and unreadable input are never billed. There are no subscriptions and no charges for empty results. Listing a channel/playlist (listVideos mode) is billed separately at $0.50 / 1,000 videos listed.

Reliability

YouTube's transcript backend breaks roughly twice a year — and every time it does, transcript scrapers across the ecosystem go dark for days (most recently December 2025 and January 2026). This Actor is built around that fact:

  • Dedicated gateway, not a script in a container. Requests go through a self-hosted API layer with automatic retries, residential IP rotation, and rate-limit back-off. A single YouTube hiccup doesn't fail your run.
  • 24/7 breakage monitoring. Upstream error rates are monitored continuously; a spike pages the operator immediately — issues are typically being worked before users notice.
  • Honest failure reporting. Transient problems are retried transparently. Only genuinely-missing transcripts are reported as skipped — with the reason, and without a charge.
  • Actively maintained. This is a production service, not an abandoned side project. Check the issue response time on this page.

FAQ

A video has no captions — what happens? It's skipped (not added to the dataset), listed in the OUTPUT summary as NO_CAPTIONS, and you're not charged for it. The run still succeeds.

What if I'm not sure of the video's language? Leave language empty (or keep strictLanguage off). You'll get the video's available transcript. Set a language only when you specifically want one, and turn on strictLanguage only when a fallback is unacceptable.

Can I get SRT/VTT files? Yes. Set Subtitle file format to srt, vtt, or both, and each result gains an srt and/or vtt field with ready-to-save subtitle file content (built from the same timestamps as segments). It doesn't change pricing — you're still charged one result per video.

Can I get transcripts for a whole channel? In two cheap steps. First run List all videos of a channel (mode: listVideos) on the channel @handle — that lists every video ID for $0.50/1,000, no transcripts. Then run Transcripts mode with the IDs you actually want. This "preview before you pay" flow means you never pay to transcribe videos you don't need. (There is deliberately no single "whole-channel transcripts" button — it would bill you for the entire back catalogue up front.)

Do YouTube Shorts work? Yes. youtube.com/shorts/… links (and youtu.be, embed, live, mobile m. variants) are all accepted.

Does it work with auto-generated captions? Yes — both human-written (manual) and auto-generated (asr) tracks are extracted; the kind field tells you which one you got.

What about region-restricted videos? If a video can't be accessed due to region restrictions, it's skipped and reported as GEO_BLOCKED in the summary — not billed.

Why did some videos get skipped? Open the OUTPUT record in the run's key-value store. Every skipped video is listed with its reason (NO_CAPTIONS, VIDEO_UNAVAILABLE, LANG_NOT_FOUND, GEO_BLOCKED, INVALID_INPUT, or a temporary error after retries). The final log line also shows the success count.

Support

Questions, issues, or a feature request? Open an issue on the Issues tab — response times are shown on this page — or email info@greza.dev.