YouTube Channel Transcripts - Whole Channel, up to 5,000 Videos
Pricing
$5.00 / 1,000 transcripts
YouTube Channel Transcripts - Whole Channel, up to 5,000 Videos
One row per video for a whole YouTube channel (@handle, URL or id) or playlist: title, views, duration, date and the full transcript, with optional timestamps. Up to 5,000 videos per source, with language fallback and optional translation.
YouTube Channel Transcripts - a whole channel, playlist or search as text
Give it a YouTube channel (@handle, channel URL or id), a playlist, or a search written as
search: your query, and get one row per video with title, views, duration and the full transcript, plus
optional timestamps. Built for feeding whole channels into notes, search indexes and LLMs.
Up to 5,000 videos per source, and you pay only for videos whose transcript was returned.
What data you get
Two row types, told apart by type:
sourcerow (one per channel, playlist or search, free):source,channel,channel_id,channel_url,listed(videos read),picked(left after filters and the skip list),status.videorow (one per picked video):video_id,url,title,view_count,duration_seconds,published_at,live_status,channel,channel_urlstatus:ok,no_transcript,captions_disabled,unavailable,blockedorerror, with a note inerrortext(full transcript, one string),word_count,segment_countlanguage,source_language(differ when translated),is_generated(true= YouTube's automatic captions)segments[]withstart,duration(seconds) andtextper caption line, whenincludeSegmentsis on
Each run also saves a SUMMARY record (listed, delivered, free and skipped counts) in its key-value store.
Use cases
- Searchable archive of a creator's teaching - pull the back catalogue once, then keep it current.
- Ground an AI assistant or RAG index - one text field per video, with title and URL for citations.
- Follow a channel weekly - on a schedule, already-delivered videos are skipped, so you get new uploads.
- Quote-mining a podcast or talk series -
includeSegmentstimestamps every line.
How to use it (quick start)
- Open the Actor in Apify Console (you need an Apify account).
- In Channels or playlists, enter sources such as
@Apifyorsearch: cold plunge recovery; set Max videos per source and any filters. - Click Start, then export the results as JSON, CSV or Excel from the Dataset tab.
For code and AI agents, see below.
Input
| Field | What it does | Default |
|---|---|---|
sources (required) | @handles, channel ids (UC...), playlist ids (PL...), URLs, or search: your query | ["@Apify"] |
maxVideosPerSource | Videos read from each source, 1 to 5,000 | 50 |
minViews | Skip videos with fewer views; 0 = off | 0 |
minDurationSeconds / maxDurationSeconds | Duration filters in seconds; 0 = off | 0 / 0 |
skipAlreadyDone | Skip videos already delivered for this source in earlier runs | true |
languages | Caption languages in order of preference | ["en"] |
allowAutoGenerated | Fall back to YouTube's automatic captions | true |
translateTo | Optional language code to translate into | "" |
includeSegments | Add timestamped segments[] (larger rows) | false |
concurrency | Videos processed in parallel, 1 to 20 | 5 |
maxRetries | Fresh proxy sessions per video when blocked, 1 to 10 | 4 |
proxyConfiguration | YouTube blocks datacenter IPs for transcripts | Apify Proxy, RESIDENTIAL |
A @handle or channel URL/id reads the channel's Videos tab, newest first; a playlist keeps playlist order; a
search keeps YouTube's result order. Tab URLs like https://www.youtube.com/@handle/shorts or /streams are passed
through unchanged, for Shorts or past live streams.
Whole channel, skipping videos of 60 seconds or less:
{ "sources": ["@Apify"], "maxVideosPerSource": 500, "minDurationSeconds": 61 }
Top 20 search results, keeping those with at least 10,000 views:
{ "sources": ["search: cold plunge recovery"], "maxVideosPerSource": 20, "minViews": 10000 }
A playlist in Spanish or English, translated to English, with timestamps:
{ "sources": ["https://www.youtube.com/playlist?list=YOUR_PLAYLIST_ID"], "languages": ["es", "en"], "translateTo": "en", "includeSegments": true }
Output
Real rows from a default-input run (@Apify, 50 videos; run zZ1awuWiPm6M65n9G, 2026-10-02 UTC), trimmed: long text cut, last row reduced
to key fields. The run returned 1 source row and 50 video rows (48 ok, 2 captions_disabled).
[{"type": "source", "status": "ok","source": "https://www.youtube.com/@Apify/videos","channel": "Apify", "channel_id": "UCTgwcoeGGKmZ3zzCXN2qo_A","channel_url": "https://www.youtube.com/channel/UCTgwcoeGGKmZ3zzCXN2qo_A","listed": 50, "picked": 50},{"type": "video", "channel": "Apify","channel_url": "https://www.youtube.com/channel/UCTgwcoeGGKmZ3zzCXN2qo_A","video_id": "W-5GagvbThI","title": "How to Connect Apify to Hermes Agent (Live Web Data for Your AI)","view_count": 1000, "duration_seconds": 959, "published_at": null,"url": "https://www.youtube.com/watch?v=W-5GagvbThI", "live_status": null,"status": "ok", "language": "en", "source_language": "en", "is_generated": true,"segment_count": 411, "word_count": 2943,"text": "Hey everyone, Michael here, developer advocate at Amplify and today I'm going to be going over..."},{"type": "video", "video_id": "G39sQ5dhaHw","view_count": 993000, "duration_seconds": 50,"status": "captions_disabled", "error": "Captions are disabled for this video"}]
Use it with AI agents (MCP)
Apify's hosted MCP server exposes this Actor as a tool. Add it to your MCP client with your Apify token:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=actors,docs,leekung125/youtube-channel-transcripts","headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }}}}
Example prompt: "Get transcripts of the 20 newest @Apify videos and summarise each." Apify's MCP docs also describe a browser sign-in flow that needs no token.
Use it from code
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("leekung125/youtube-channel-transcripts").call(run_input={"sources": ["@Apify"], "maxVideosPerSource": 20})items = client.dataset(run.default_dataset_id).list_items().items
JavaScript (npm i apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('leekung125/youtube-channel-transcripts').call({ sources: ['@Apify'], maxVideosPerSource: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
cURL (returns the dataset rows in the response):
curl -X POST "https://api.apify.com/v2/acts/leekung125~youtube-channel-transcripts/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" -d '{"sources": ["@Apify"], "maxVideosPerSource": 10}'
Schedules, webhooks and integrations (Make, Zapier, n8n, Google Sheets) work as for any Apify Actor.
Pricing
$0.005 per video row whose transcript was returned (event transcript, status ok) = $5.00 per 1,000
transcripts. You pay only this event price; there is no separate platform-usage charge.
| Transcripts returned | Arithmetic | Cost |
|---|---|---|
| 1,000 | 1,000 x $0.005 | $5.00 |
| 10,000 | 10,000 x $0.005 | $50.00 |
| 100,000 | 100,000 x $0.005 | $500.00 |
Never charged: source rows and listing; videos removed by filters or skipAlreadyDone; video rows with status
no_transcript, captions_disabled, unavailable, blocked or error. The default run above was charged for
48 transcripts ($0.24). If you set a maximum total charge, the Actor stops starting new videos once it is reached
and sets spending_limit_hit: true in SUMMARY.
Limits and honesty notes
- Transcripts are what YouTube provides: uploaded captions, else automatic captions (
is_generated: true), which can contain errors. Members-only, private and live-without-captions videos return no transcript. - Language fallback: (1) uploaded captions in your
languages, in order; then, only ifallowAutoGeneratedis on, (2) automatic captions in yourlanguages, (3) the first caption track YouTube lists, in any language. Checklanguageper row; the label is YouTube's (an English talk in the default run came back aslt). - Translation uses YouTube's caption translation and only works on translatable tracks; otherwise you get the original language.
published_atis often empty: on that default run it wasnullon all 50 video rows.- View counts can be rounded by the listing (that run shows
1000,1100,993000). - Filters apply after listing, so you can get fewer rows than
maxVideosPerSource. Videos with unknown duration pass the duration filters; videos with unknown views failminViews. - Search sources:
channelandchannel_urlon video rows describe the search, not the uploader. - The skip list is a named key-value store in your account (
youtube-channel-transcripts-memo), keyed by source. Onlyokvideos go in it, so videos without a transcript are retried (free). Skipped videos still count towardmaxVideosPerSource. It is saved when a source finishes: a run aborted or timed out mid-source forgets that source's deliveries, and they are fetched and charged again next run. - Blocks: a listing gets 3 attempts, a video
maxRetriesattempts, each on a fresh proxy session. Then you get a freeblockedvideo row, or asourcerow with statuserror. - Large channels take time: the 50-video default run took about 64 s (one run, not a benchmark). The default run timeout is 3,600 s; raise it under Run options for very large channels.
- No headless browser, no YouTube login, no viewer, commenter or contact data.
- Reliability, measured on our own runs: 239 of 239 runs in the last 30 days succeeded (our account's run history, read 2026-10-02). These are our own test and monitoring runs, not customer runs.
FAQ
Do I need a YouTube API key? No. You need an Apify account (and an Apify API token for code).
Is it legal to scrape YouTube transcripts? It reads publicly available videos and captions without logging in. You are responsible for using the data lawfully and within YouTube's terms; do not resell personal data.
Can I export to CSV or Excel? Yes, or JSON, from the Dataset tab or the API.
Can I run it on a schedule and only get new videos?
Yes. Schedule it in Apify Console; with skipAlreadyDone on (the default), videos already delivered for that source
are skipped and not charged again.
Can I use it from an AI agent / MCP? Yes, through Apify's hosted MCP server (see above).
Why did I get fewer rows than I asked for?
The source has fewer videos, filters removed some, skipAlreadyDone skipped earlier deliveries, or a spending limit
was reached. The source row's listed and picked and the SUMMARY record show which.
What happens when a video has no captions or YouTube blocks the request?
You get a row with a non-ok status and a note in error. It is not charged.
What is charged?
Only video rows with status ok, at $0.005 each.
Related Actors
| Actor | What it does |
|---|---|
| YouTube Transcript Scraper | Transcripts for a list of videos |
| YouTube Search Scraper | Keyword to ranked video rows |
| Google Play Reviews Scraper | Android app reviews |
| App Store Reviews Scraper | Apple App Store reviews |
| Google Trends Scraper | Google Trends interest, regions and related data |
Support
Open an issue on the Issues tab with the run ID and your input; we read every issue.