YouTube Subtitles & Transcript Scraper API - Channels avatar

YouTube Subtitles & Transcript Scraper API - Channels

Pricing

from $2.13 / 1,000 transcripts

Go to Apify Store
YouTube Subtitles & Transcript Scraper API - Channels

YouTube Subtitles & Transcript Scraper API - Channels

Bulk YouTube transcript API. YouTube to text: get YouTube transcripts for videos, YouTube Shorts, playlists, channels: each YouTube video transcript, subtitles, captions as text, JSON, YouTube SRT, VTT, RAG chunks; YouTube translation; YouTube transcript MCP. YouTube channel, playlist transcripts.

Pricing

from $2.13 / 1,000 transcripts

Rating

4.0

(1)

Developer

Saulius AutomatesIT

Saulius AutomatesIT

Maintained by Community

Actor stats

1

Bookmarked

117

Total users

46

Monthly active users

4 days ago

Last modified

Categories

Share

Bulk YouTube transcript API: paste videos, Shorts, channels, playlists or search terms and get every transcript back as text, RAG chunks, SRT or VTT. $2.50 per 1,000 transcripts. Videos without captions cost nothing.

  • Proven at scale. One customer ran 8,500 runs and 436,000+ videos through it in a single day.
  • Whole channels and playlists in one input. A channel URL, playlist URL or search term expands to its videos automatically. Mix them freely with single video links.
  • Pay only for delivered transcripts. No captions, private, deleted or blocked videos get a free diagnostic row, never a charge. Platform usage (compute, proxies) is included in the price.
  • Ready for AI. chunks gives paragraph-sized pieces with start and end times for RAG and embeddings; clean-text gives readable paragraphs for LLM prompts. Works from the API, Python, JavaScript, n8n, Make, Zapier and any MCP client (Claude, ChatGPT, Cursor).
  • Translate any transcript. Set translateTo (en, es, de, pt-BR…) and a Spanish or Hindi video comes back in English, at the same price.
  • Filter by upload date. publishedAfter: "7 days" on a channel limits results to recent videos. This is a date filter, not a record of previous runs: overlapping windows can return and charge for the same transcript again.
  • No YouTube API key, no login, no cookies.

Try it free: Apify's free plan includes $5 of usage credit every month, enough for about 2,000 transcripts, less the negligible Actor-start charge. Videos without captions incur no transcript charge.

Quick start

  1. Paste one or more YouTube links or search terms into Videos, channels, playlists, or searches.
  2. Pick a Transcript format (text if unsure).
  3. Click Start. Transcripts stream into the dataset as they are extracted. Export as JSON, CSV, Excel, or download the srt / vtt column as subtitle files.
{
"videoUrls": ["https://www.youtube.com/@mkbhd"],
"transcriptFormat": "clean-text",
"maxVideosPerSource": 50
}

That returns the 50 newest uploads of the channel as paragraph text. Cost at the Free-plan price: at most $0.125.

What you can paste

InputExampleWhat happens
Video URL or IDyoutube.com/watch?v=dQw4w9WgXcQ, youtu.be/…, dQw4w9WgXcQOne transcript
YouTube Shortsyoutube.com/shorts/…One transcript
Live replay, embedyoutube.com/live/…, youtube.com/embed/…One transcript
Channelyoutube.com/@handle, youtube.com/channel/UC…The channel's uploads, newest first, up to maxVideosPerSource
Playlistyoutube.com/playlist?list=…Every video in the playlist, up to maxVideosPerSource
Search termmachine learning tutorialThe top search results, up to maxVideosPerSource

Pricing

$2.50 per 1,000 transcripts ($0.0025 each) on the Free plan. Paid Apify plans get the Store discount automatically: Bronze $2.375, Silver $2.25, Gold and above $2.125 per 1,000. Each run also has a $0.00005 start fee per GB of memory (about $0.00005 per run at the default 1 GB). Proxy and compute costs are included. That is the whole bill.

JobTranscripts deliveredFree planBusiness plan (Gold, -15%)
100-video playlist, 92 have captions92$0.23$0.20
1,000-video channel backfill~1,000~$2.50~$2.13
Daily check of 20 channels, 5 new videos each100 a day~$7.50 a month~$6.38 a month
20,000-video research corpus~20,000~$50.00~$42.50
100,000 videos a month~100,000~$250~$212.50

Apify's Starter plan gets the Bronze discount, Scale gets Silver and Business gets Gold, applied automatically. The free plan's $5 monthly credit covers about 2,000 transcripts.

  • Videos without captions cost $0, and so do private, deleted and blocked ones.
  • Set Maximum total charge in the run options to hard-cap spending. The Actor stops cleanly at the cap and keeps everything it already delivered.
  • For context, the two most-used YouTube transcript Actors on the Store charge $5 and $10 per 1,000 results (checked October 2026).

Translate YouTube transcripts

Set translateTo to a language code and every transcript comes back in that language:

{
"videoUrls": ["https://www.youtube.com/@elrubiusOMG"],
"translateTo": "en",
"maxVideosPerSource": 20
}
  • A real caption track in that language always wins. Otherwise you get YouTube's own machine translation of the best track, the same one the player's "Auto-translate" menu shows.
  • Rows carry translatedTo and translatedFrom (for example es), so you can tell translated text from original captions.
  • Same price per transcript. If YouTube refuses a translation (it rate limits them hard; the Actor retries up to 20 times), you get the original-language transcript with translationError set, never an empty row.
  • Works with every format: text, clean-text, chunks, srt and vtt, so translated SRT subtitles are one field away.

Recent uploads: transcripts by upload date

publishedAfter and publishedBefore take a date (2026-10-01) or an age (7 days, 24 hours, 2 weeks, 1 month) and apply to channels and search terms:

{
"videoUrls": ["https://www.youtube.com/@TED", "https://www.youtube.com/@veritasium"],
"publishedAfter": "24 hours",
"transcriptFormat": "chunks"
}
  • Channels are listed newest first and stop at the first video older than the window, so older uploads are never fetched or charged.
  • Searches use YouTube's own upload date filter, then the same check.
  • YouTube lists only a rounded age ("1 month ago"); videos on the boundary are checked to the day. Rows get publishedTimeText.
  • A run that finds nothing new ends cleanly with "No videos in the date window" and costs only the start fee, so a daily schedule on 50 channels costs cents on quiet days.
  • Single video links and playlists are not filtered.
  • There is no cross-run deduplication. Repeating an input or using overlapping date windows can fetch and charge for the same video again. For strict deduplication, keep processed video IDs in your workflow and submit only unseen video links.

For a date range combine both: "publishedAfter": "2026-08-01", "publishedBefore": "2026-08-31".

Bulk and recurring workloads

The Actor is built for large, repeated jobs, not just one-off lookups:

  • Throughput. 436,000+ videos processed for one customer in a day across 8,500 API runs. Results stream into the dataset while a run is still going.
  • Predictable cost. One flat event with platform usage included, the plan discount applied automatically, and Maximum total charge per run as a hard ceiling.
  • Nothing wasted. No-caption, private, deleted and blocked videos come back as free failure rows, so a channel where 20% of videos lack captions costs 20% less. Set includeFailures to false to drop those rows.
  • Safe to automate. The SUMMARY record reports exactly what happened in every run, and a restarted run never charges twice for the same video.

Running a large or recurring workload (100,000+ videos a month)? Open an issue on the Issues tab with your volume and output format, and you will get help sizing runs and concurrency.

Output

One dataset item per video:

{
"type": "transcript",
"videoId": "dQw4w9WgXcQ",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up (Official Video)",
"channelName": "Rick Astley",
"channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
"lengthSeconds": 213,
"viewCount": 1697651560,
"language": "en",
"languageName": "English",
"isAutoGenerated": false,
"transcriptFormat": "text",
"transcript": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪…",
"segmentCount": 61,
"wordCount": 488,
"availableLanguages": ["en", "en (auto)", "de-DE", "ja", "pt-BR", "es-419"],
"sourceInput": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"scrapedAt": "2026-08-11T21:35:20.991Z"
}

Upload date, likes, comments and word-level timestamps

Two switches add fields to each row, at no extra charge:

  • includeVideoStats: true adds publishDate (2009-10-24), likeCount (19491698), commentCount (2400000) and commentCountText (2.4M, as YouTube shows it). It reads the watch page once more per video; a field is null when YouTube hides it (likes hidden, comments off).
  • wordTimestamps: true adds words: [{ "text": "never", "start": 18.4, "end": 18.72 }, …], every word with its own start and end second, for karaoke style subtitles, cutting video at an exact word, or quoting the exact second. YouTube keeps per-word timing on auto-generated captions only, so manual captions give []; set preferAutoGenerated: true to get word timing where a video has both.

Videos that can't produce a transcript get a type: "failure" row (free of charge) with an error code such as NO_CAPTIONS, NO_MATCHING_LANGUAGE, or LOGIN_REQUIRED, so your pipeline can handle them explicitly. A run report with per-outcome counts is saved under the SUMMARY key of the run's key-value store.

Transcript formats

YouTube does not hand out prose. A caption track is a list of ~2-second display fragments, cut mid-sentence, with sound cues ([Music], [Applause]) inline — and auto-generated (ASR) tracks usually carry no punctuation at all. Pick the format that matches what you do next:

Formattranscript containsUse it for
textCaption fragments joined with spaces, exactly as YouTube sends themAnything already doing its own cleanup
clean-textThe same words, sound cues removed, split into paragraphs at pausesReading, summarising, prompting an LLM
segments[{ text, start, duration }] per caption fragmentTiming analysis, building your own subtitles
chunks[{ text, start, end, wordCount }] per paragraphRAG, embeddings, timestamped citations
srt / vttA ready-to-save subtitle filePlayers, editors, upload back to YouTube

clean-text and chunks share one cleanup pass: sound cues are dropped, and the words are regrouped into paragraphs that break at any pause of 2 seconds or more in the audio, or at chunkWords words (default 150) when the speaker never pauses. Each paragraph is capitalised and given a closing full stop. chunks keeps the start/end timing of every paragraph, so a retrieval hit can be linked straight back to youtube.com/watch?v=…&t=123s.

{
"transcriptFormat": "chunks",
"transcript": [
{ "text": "Hi I'm Matt I've worked at the RC now for 15 years as a patrolman today I'm going to talk you through going through a wheel change…", "start": 4.799, "end": 52.12, "wordCount": 155 },
{ "text": "Off now as doing this when the vehicle's on the jack could cause the jack to dislodge…", "start": 50.12, "end": 97.759, "wordCount": 150 }
],
"chunkCount": 4
}

What the cleanup does not do: it adds no punctuation inside a paragraph and corrects no words. If YouTube's ASR wrote the RC for "the RAC", that is what you get — restoring punctuation and fixing transcription errors needs a language model, which this Actor deliberately doesn't run (it would cost far more than the transcript itself). Manual caption tracks are usually already punctuated, and clean-text leaves that punctuation intact.

text and segments are unchanged from earlier builds — existing runs and integrations keep their exact output.

Input

{
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/jNQXAC9IVRw",
"https://www.youtube.com/@mkbhd",
"https://www.youtube.com/playlist?list=PLFgquLnL59alCl_2TQvOiD5Vgm1hCaGSI",
"machine learning tutorial"
],
"languages": ["en"],
"transcriptFormat": "text",
"maxVideosPerSource": 200
}

Switching from another YouTube transcript Actor? Its input runs here as is: youtube_url, channel_url, channel, videoUrl, urls, startUrls, max_videos, language, translate_to, targetLanguage, start_date, end_date, searchKeywords (each keyword is searched on YouTube), maxPagesPerUrl (about 20 videos a page), outputFormat (json, text, srt, vtt, captions, singleStringText), outputFormats, subType and timestamps are all accepted and mapped to the fields below.

FieldDefaultDescription
videoUrls—Video URLs/IDs, channel URLs (@handle or /channel/UC…), playlist URLs, or search queries
languages["en"]Preferred transcript languages, in priority order
transcriptFormattexttext, clean-text, segments, chunks, srt, or vtt
chunkWords150Target paragraph size for clean-text / chunks
preferAutoGeneratedfalsePrefer auto-generated (ASR) captions over manual ones
fallbackToAnyLanguagetrueUse the best available track if no preferred language exists
translateTo—Return every transcript in this language (en, es, pt-BR…), YouTube machine translation when no real track exists. Same price
includeVideoDetailsfalseAdd description, tags, thumbnail URL and live flag to each row. No extra charge
includeVideoStatsfalseAdd exact upload date, like count and comment count. One extra request per video, no extra charge
wordTimestampsfalseAdd words with each word's start and end second (auto-generated captions). No extra charge
publishedAfter—Channels and searches: only videos uploaded on or after a date (2026-10-01) or within an age (7 days)
publishedBefore—Channels and searches: only videos uploaded on or before a date or older than an age
includeFailurestrueEmit uncharged diagnostic rows for videos without transcripts
maxVideosPerSource200Cap per channel/playlist/search
maxResults100000Global cap per run (spend guard)
concurrency10Parallel video fetches (1–25)
proxyStrategyautoauto ladder, or force datacenter-only / residential-only
maxUnchargedRatio90Stop early if more than this % of the first 200+ videos return no transcript. Set 100 to disable
maxResidentialAttempts0Cap on premium-proxy escalations per run. 0 = auto (25% of queued videos, min 500)

Early stopping

Two safeguards end a run cleanly rather than working through a list that cannot pay its way. Neither marks the run as failed, and both are reported in the SUMMARY record:

  • No transcripts available — if more than maxUnchargedRatio % of the first 200+ videos return no transcript, the run stops and says so. This almost always means the videos have no caption tracks. Normal jobs, including ones where many videos legitimately lack captions, are unaffected.
  • Premium proxy budget — YouTube bot-checks are retried on a residential proxy, which is much more expensive. Once maxResidentialAttempts is spent the run continues on datacenter only.

SUMMARY reports stoppedAtUnchargedLimit, premiumProxyAttempts and premiumProxyBudget alongside the existing counters.

Is there an official YouTube transcript API?

Not for other people's videos. The YouTube Data API's captions.download method "requires the user to have permission to edit the video", needs OAuth with the youtube.force-ssl or youtubepartner scope, and costs 200 quota units per call, so the default 10,000 units a day allow 50 downloads (YouTube Data API reference).

OptionAny public videoWorks from a serverCost
YouTube Data API captions.downloadNo, only videos you can editYesFree, about 50 downloads a day on the default quota
youtube-transcript-api (Python library)YesUsually blocked on cloud IPs unless you add a residential proxyFree, plus the proxy plan
This ActorYes, any public video with captionsYes, proxies included$2.50 per 1,000 transcripts; videos without captions free

youtube-transcript-api blocked on AWS, GCP or a VPS? (RequestBlocked, IpBlocked)

The youtube-transcript-api Python library works on a laptop and then raises RequestBlocked or IpBlocked once deployed, because YouTube blocks most IP ranges that belong to cloud providers. The library's own README says so and recommends rotating residential proxies. This Actor does the same lookup on Apify with proxy rotation built in, and segments returns the same text, start and duration fields.

Before, with the library:

from youtube_transcript_api import YouTubeTranscriptApi
fetched = YouTubeTranscriptApi().fetch("dQw4w9WgXcQ", languages=["en"])
for snippet in fetched:
print(snippet.start, snippet.text)

After, with a drop-in function that fetches many videos in one run:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
def fetch_transcripts(video_ids, languages=("en",)):
"""{video_id: [{"text", "start", "duration"}, ...]} for every video that has captions."""
run = client.actor("sauliusautomatesit/youtube-transcript-scraper").call(run_input={
"videoUrls": list(video_ids),
"languages": list(languages),
"transcriptFormat": "segments",
})
transcripts = {}
for item in client.dataset(run.default_dataset_id).iterate_items():
if item["type"] == "transcript":
transcripts[item["videoId"]] = item["transcript"]
else:
print("no transcript:", item["videoId"], item["error"])
return transcripts
transcripts = fetch_transcripts(["dQw4w9WgXcQ", "jNQXAC9IVRw"])
for snippet in transcripts["dQw4w9WgXcQ"][:3]:
print(snippet["start"], snippet["text"])
youtube-transcript-apiThis Actor
fetch(video_id, languages=[...])videoUrls (IDs, links, channels, playlists) and languages
snippet.text, .start, .durationtranscriptFormat: "segments": text, start, duration
TextFormatter, SRTFormatter, WebVTTFormattertranscriptFormat: text, clean-text, srt, vtt
list(video_id)availableLanguages on every row
TranscriptsDisabledfree row with error: "NO_CAPTIONS"
NoTranscriptFoundfree row with error: "NO_MATCHING_LANGUAGE", or the best other track with fallbackToAnyLanguage
RequestBlocked, IpBlockedretried on a fresh proxy; a video still blocked is a free row, never a charge

Tutorial: Python, AI agents and RAG

Four copy-paste recipes. Each one needs an Apify API token (Apify Console > Settings > API & Integrations); the free plan's monthly credit covers about 2,000 transcripts.

1. Python: every video of a channel in one call

$pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("sauliusautomatesit/youtube-transcript-scraper").call(run_input={
"videoUrls": ["https://www.youtube.com/@3blue1brown"],
"maxVideosPerSource": 5,
"transcriptFormat": "clean-text",
})
for item in client.dataset(run.default_dataset_id).iterate_items():
if item["type"] == "transcript":
print(item["title"], item["wordCount"], "words")
else:
print("skipped", item["videoId"], item["error"])

run.default_dataset_id is for apify-client 3.x; on 2.x write run["defaultDatasetId"]. The same code works with a playlist URL, a list of video links or a search term. To cap spend, pass max_total_charge_usd=1 to .call() and the run stops cleanly at $1.

2. AI agents: one MCP URL, one tool

This URL gives any MCP client exactly one tool, this Actor, instead of a search over the whole Apify Store:

https://mcp.apify.com/?tools=sauliusautomatesit/youtube-transcript-scraper

Claude Code:

$claude mcp add --transport http youtube-transcripts "https://mcp.apify.com/?tools=sauliusautomatesit/youtube-transcript-scraper"

Cursor (~/.cursor/mcp.json), Claude Desktop, VS Code and other clients that take JSON:

{
"mcpServers": {
"youtube-transcripts": {
"url": "https://mcp.apify.com/?tools=sauliusautomatesit/youtube-transcript-scraper",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Clients that support OAuth (Claude.ai custom connectors, ChatGPT) need only the URL and open an Apify sign-in on first use. Then ask things like:

  • "Get the transcripts of the last 10 videos on @lexfridman and list every book mentioned, with the timestamp."
  • "Pull the transcript of this video and turn it into a blog post outline."

The agent fills in videoUrls, maxVideosPerSource and transcriptFormat from the input schema. Videos without captions come back as free failure rows, so the agent can say why instead of guessing.

3. LangChain and CrewAI

pip install langchain-apify
export APIFY_API_TOKEN=YOUR_APIFY_TOKEN
from langchain_apify import ApifyActorsTool
youtube = ApifyActorsTool("sauliusautomatesit/youtube-transcript-scraper")
rows = youtube.invoke({"run_input": {
"videoUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],
"transcriptFormat": "chunks",
}})

youtube is a normal LangChain tool, so it also goes straight into an agent's tool list.

4. RAG: timestamped chunks that cite the exact second

chunks returns paragraphs (broken at pauses of 2 seconds or more, or every chunkWords words), each with its start time. Turn them into documents whose source link jumps to the moment:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("sauliusautomatesit/youtube-transcript-scraper").call(run_input={
"videoUrls": ["https://www.youtube.com/@3blue1brown"],
"maxVideosPerSource": 20,
"transcriptFormat": "chunks",
"chunkWords": 150,
})
docs = []
for item in client.dataset(run.default_dataset_id).iterate_items():
if item["type"] != "transcript":
continue
for i, chunk in enumerate(item["transcript"]):
docs.append({
"id": f"{item['videoId']}-{i}",
"text": chunk["text"],
"metadata": {
"title": item["title"],
"channel": item["channelName"],
"url": f"https://www.youtube.com/watch?v={item['videoId']}&t={int(chunk['start'])}s",
},
})
print(len(docs), "chunks ready to embed")

Load docs into any vector store (Chroma, pgvector, Pinecone, Qdrant, LangChain or LlamaIndex documents). When the retriever returns a chunk, metadata.url sends the reader to the exact second. To keep a channel's index fresh, save the input as a Task with a daily schedule and embed only video IDs you have not seen.

Other ways to call it

API (one call, results in the response)

curl -X POST "https://api.apify.com/v2/acts/sauliusautomatesit~youtube-transcript-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"], "transcriptFormat": "clean-text" }'

For large jobs, start the run asynchronously and read the dataset when it finishes; results stream into the dataset while the run is still going.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('sauliusautomatesit/youtube-transcript-scraper').call({
videoUrls: ['https://www.youtube.com/@mkbhd'],
maxVideosPerSource: 10,
transcriptFormat: 'srt',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
if (item.type === 'transcript') console.log(item.videoId, item.title, item.transcript.length, 'characters of SRT');
else console.log('skipped', item.videoId, item.error);
}

npm install apify-client first. The same input works with plain fetch against the API call above.

n8n, Make and Zapier

Use the Apify node or module, choose Run an Actor, enter sauliusautomatesit/youtube-transcript-scraper, pass the input JSON, then read the dataset items in the next step. transcript holds the text, type lets you filter out free failure rows.

Scheduled monitoring

Save your input as a Task with "publishedAfter": "24 hours" and give it a daily schedule in Schedules on a list of channel URLs. Each run uses a rolling upload-date window; quiet days cost only the start fee. Date boundaries and overlapping runs can return the same video again. The Actor does not remember previous runs, so store processed video IDs in your workflow when you need strict deduplication.

For recurring queues of explicit video URLs, use the Python incremental transcript example. It remembers successful transcripts locally before submitting more requests. Keep the same state file between runs. The example does not discover channel uploads or deduplicate a channel expanded inside the Actor; failed or unprocessed videos remain eligible for retry.

Use cases

  • AI and RAG pipelines. Turn channels into LLM-ready corpora with timestamped chunks.
  • Content repurposing. Transcripts for blogs, newsletters, show notes and social clips.
  • Media and brand monitoring. Schedule runs on channels and search terms.
  • Research. Collect interview and lecture transcripts with timestamps for citation.
  • Subtitles. Batch-download SRT/VTT files for re-upload, accessibility or translation.

Limitations

  • Transcripts come from YouTube caption tracks (manual or auto-generated). Videos with captions disabled can't be transcribed — they're reported as NO_CAPTIONS and not charged. To transcribe the audio of videos without captions, try Media Transcriber (YouTube support there is best effort).
  • Live streams in progress and age-restricted videos are generally not extractable.
  • Channel expansion returns the channel's regular uploads (newest first), up to maxVideosPerSource.

FAQ

Does YouTube have an official transcript API? Not for other people's videos. The YouTube Data API only lets you download captions for videos you have permission to edit. This Actor reads the public caption tracks YouTube shows in its player, for any public video.

Why does youtube-transcript-api raise RequestBlocked on my server? YouTube blocks most cloud provider IPs. The section "youtube-transcript-api blocked on AWS, GCP or a VPS?" above shows how to swap the call for this Actor and keep your segment handling.

How do I get a YouTube transcript in Python? pip install apify-client and use the fetch_transcripts function above, or tutorial recipe 1 for a whole channel.

How do I get the transcripts of a whole YouTube channel? Paste the channel URL (youtube.com/@handle) and set maxVideosPerSource to the number of uploads you want. Playlists and search terms work the same way.

How much does it cost to transcribe 10,000 YouTube videos? About $25 on the Free plan and $21.25 on Gold, minus every video without captions, which is free.

Do I need a YouTube API key or cookies? No. The Actor uses YouTube's public endpoints.

What languages are supported? Anything YouTube has captions for. Set languages to your priority list; availableLanguages on every item shows what exists.

Can I translate a YouTube transcript to English (or any language)? Yes. Set translateTo to en (or es, de, fr, pt-BR…). You get YouTube's machine translation when the video has no track in that language, at the same price. See Translate YouTube transcripts.

How do I filter a channel to recent videos? Set publishedAfter to 7 days (or a date). Older uploads are excluded, but overlapping scheduled runs can return and charge for the same videos again. See Recent uploads.

Can I get timestamps? Yes. Segment-level timestamps (a few seconds each) via segments, srt or vtt, or paragraph-level ones via chunks.

The transcript is one long block with no punctuation — can you fix that? Set transcriptFormat to clean-text or chunks. That removes sound cues and breaks the text into paragraphs at pauses in the audio. Punctuation within a sentence comes from YouTube: manual caption tracks have it, auto-generated ones usually don't, and this Actor doesn't run a language model to invent it. See Transcript formats.

What happens on a video that's private or deleted? A free failure row with the error code, never a charge.

  • Google Ads Transparency API: every Google and YouTube ad an advertiser runs, with the YouTube link of each video ad. Feed those links into this Actor to get the script of every competitor video ad.
  • Telegram Channel Scraper: every post from public Telegram channels as clean rows, for the same research, monitoring and RAG pipelines.
  • Google Trends API: search interest over time for the topics your videos cover, to pick what to transcribe or publish next.
  • Bing Search API: live web search results for the same AI agents and RAG pipelines, now that Microsoft has retired its own Bing API.
  • Bilibili API: videos, stats and danmaku from China's biggest video platform.

Support and reviews

Found a problem or missing a feature? Open an issue on this Actor's Issues tab; issues are answered within 24 hours. If this Actor saves you time, please leave a short review. Reviews are how other people find it.