YouTube Transcript Scraper - video, channel and playlist avatar

YouTube Transcript Scraper - video, channel and playlist

Pricing

from $3.00 / 1,000 transcripts

Go to Apify Store
YouTube Transcript Scraper - video, channel and playlist

YouTube Transcript Scraper - video, channel and playlist

Get transcripts from YouTube videos, whole channels and playlists. Every video you ask for gets a row - with the transcript, or with the exact reason there is none. Rows without a transcript are never charged.

Pricing

from $3.00 / 1,000 transcripts

Rating

0.0

(0)

Developer

Marek Hartmann

Marek Hartmann

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

YouTube Transcript Scraper

Get transcripts from YouTube videos, whole channels and playlists.

Every video you ask for gets a row. Either with the transcript, or with the exact reason there is none. Rows without a transcript are never charged.

Why another YouTube transcript scraper

Because of a failure mode we measured ourselves.

The YouTube watch page still lists a video's caption tracks, but the signed URL it hands out returns HTTP 200 with a zero-length body. An Actor that sees "captions exist", downloads them, and never checks the length will report success and save an empty dataset. You pay for the run and get nothing, with a green tick in the console.

This Actor checks the length. If the body is empty, the run fails loudly instead of charging you for nothing.

That failure mode is not hypothetical. Across the YouTube transcript Actors in the Store you can find reviews like "worked less than half the time", "did not give response to the video" and "this scraper did not scrape the channels I put in" sitting next to high success rates. We do not claim to know what any particular competitor does internally — we only know what the endpoint does, because we measured it, and what it costs you when nobody checks.

What you get per video

FieldWhat it is
transcriptThe transcript, in the format you chose — or null
errorCode / errorWhy there is no transcript, per video
language, isAutoGeneratedWhich track was actually used
availableLanguagesWhat the video does have, when your language is missing
title, channelName, viewCountVideo metadata
channelId / playlistIdWhich channel or playlist the row came from
segmentCount, wordCount, durationSecondsSize of the transcript

Input

Anything that looks like a YouTube link is accepted — including a bare video ID and a single video URL, which some competing Actors refuse outright:

https://www.youtube.com/watch?v=dQw4w9WgXcQ
https://youtu.be/jNQXAC9IVRw
https://www.youtube.com/shorts/dQw4w9WgXcQ
dQw4w9WgXcQ
https://www.youtube.com/@YouTube
https://www.youtube.com/playlist?list=PL...

Options: transcript language, whether to include auto-generated subtitles, output format (plain, timestamps, srt), and a cap on how many videos are taken per channel.

Output formats

  • plain — one continuous block of text, ready for an LLM
  • timestamps[00:01:23] line of text, one line per caption
  • srt — a valid subtitle file you can use as-is

What a failure means here

The run either gives you data, or tells you why it could not. There is no third option where you pay for silence.

errorCode in the rowWhat it meansCharged?
NO_TRANSCRIPTThe video has no subtitles at allno
LANGUAGE_NOT_AVAILABLENot in your language — the row lists the ones that existno
VIDEO_NOT_FOUNDThe ID is well-formed but the video is goneno
VIDEO_PRIVATEPrivate, or members-onlyno
AGE_RESTRICTEDNeeds a signed-in accountno
VIDEO_UNAVAILABLE_HEREBlocked in the proxy's country — try another oneno
NOT_YET_AVAILABLEA premiere or a scheduled stream that has not airedno
VIDEO_UNAVAILABLEUnplayable for a reason YouTube words in a way we don't recogniseno
CHANNEL_NOT_FOUNDThe channel or playlist does not existno
BAD_TARGETWe could not read that input as a YouTube linkno
BUDGET_REACHEDYour maxTotalChargeUsd ran out before this oneno
LIST_TRUNCATEDYouTube stopped handing us the rest of a long list — the list is not completeno
CHARGE_UNCONFIRMEDThe Apify platform answered a charge call in a shape we don't recognise, so we stopped. Your limit was not reached — don't raise itno

None of those fail the run — they are properties of the input, and you get a row saying so. These do fail the run, loudly, because they are our problem:

SituationWhat happens
YouTube blocks us as a botRun fails after retrying from other IPs
YouTube changes its response formatRun fails — we do not guess
A signed caption URL returns an empty bodyRun fails — empty is not a transcript

If a whole run comes back with nothing but "no subtitles" rows, the Actor asks a control question first — it fetches a video it knows has subtitles. If that one fails too, the run fails instead of telling you your videos have no subtitles.

A run that extracts nothing costs you the start price and nothing else, even if the dataset has 200 rows explaining why.

One honest caveat: transcripts are charged as they are delivered, not at the end. If a long run is cut short — by us being blocked, or by a format change — the transcripts you already received stay in the dataset and stay charged. The run is marked FAILED so you can see it did not finish, and you keep what you paid for. Re-running skips nothing you already have only if you pass the same input; there is no cross-run deduplication.

What this Actor does not do

Written down because you should know before you pay, not after.

  • No cross-run deduplication. Re-running the same input downloads and charges again. Within one run the same video is only ever fetched and charged once, including after a migration.
  • No translation. You get the caption tracks the video actually has. If your language is missing, the row tells you which ones exist.
  • Channels are capped per target, not per run. Ten channels at 100 videos each is a thousand transcripts — set maxVideosPerChannel or your maxTotalChargeUsd accordingly.
  • requestsFromUrl is not supported. Paste the links in directly; a requestsFromUrl entry comes back as an explained input error, not silence.
  • Live streams in progress have no finished transcript, so they come back as NOT_YET_AVAILABLE.
  • A run cut short keeps what it delivered. Transcripts are charged as they land, so if we get blocked at video 400 of 500, the first 399 stay in the dataset and stay charged, and the run is marked FAILED so you can see it did not finish.

Pricing

Pay per event:

  • 0.00005 USD per run start — charged once per GB of memory, so the intended 1 GB run start costs exactly this; a 4 GB run start costs 4×
  • 3.00 USD per 1 000 transcripts — one event per transcript actually extracted. A row without a transcript is free.

To say it the way a reviewer of a competing Actor asked and never got answered: 1 000 results means 1 000 transcripts. Not 1 000 videos attempted, not 1 000 API calls.

Proxy

YouTube blocks datacentre IPs almost immediately, so the default here is a residential proxy — measured, not assumed: through the datacentre pool the very first request comes back as "Sign in to confirm you are not a bot".

If a run does get blocked mid-way, the Actor swaps to a new proxy session and retries rather than failing on the first refusal.

Run report

Every run writes a RUN_REPORT record into the key-value store: what was requested, what each target returned, and how many rows were actually billed. It is written as the run goes, not only at the end, so it exists even if a long run is cut short. Each transcript row also carries transportClient — which strategy actually answered for that video.

Each target in the report gets an outcome:

outcomeWhat it means
OKEvery video that had a transcript returned one
PARTIALSome transcripts came back, then your maxTotalChargeUsd stopped the rest
BUDGET_REACHEDThe budget stopped this target before any transcript came back
CHARGE_UNCONFIRMEDThe platform stopped confirming charges, so this target was not fetched — your limit was not reached
DUPLICATEEvery video here was already downloaded earlier in this same run
MIXEDSome were already downloaded earlier in this run, the rest have no transcript
NO_TRANSCRIPTSNone of the videos has a transcript — and the canary proved we can still read

If a run is migrated to another machine mid-way, it picks up where it left off and does not re-download or re-charge what it already delivered.


Built by Marek Hartmann. I also build custom Apify Actors to order — if you need a scraper for a source that is not in the Store yet, get in touch.