YouTube Transcripts - Captions, SRT, Timestamps
Pricing
from $5.00 / 1,000 transcript fetcheds
YouTube Transcripts - Captions, SRT, Timestamps
Extract YouTube video transcripts via API, MCP, or schedule — captions (manual or auto-generated), timestamps, SRT subtitles, multi-language. $0.002 per video. One JSON row per URL. No browser, no API key.
Pricing
from $5.00 / 1,000 transcript fetcheds
Rating
0.0
(0)
Developer
Heim AI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
YouTube Transcripts — Captions from Video URLs
URL in → transcript out. Pass YouTube watch/shorts/youtu.be links; get one JSON dataset row per video with the caption track (manual or auto-generated). No API key, no browser. Built for MCP agents, API clients, and scheduled pipelines.
| Actor id | kaz_kakyo/youtube-transcripts |
| Minimal input | { "youtubeUrls": ["https://www.youtube.com/watch?v=…"] } |
| Cost | $0.005 per video · $0.00005/run start |
| Output | Dataset rows with type: "transcript" or type: "error" |
Call it (MCP / API / schedule)
MCP (agents)
{"actor": "kaz_kakyo/youtube-transcripts","input": {"youtubeUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"]}}
Optional extras agents usually want:
{"youtubeUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],"languages": ["en"],"includeTimestamps": true,"includeSrt": true}
After the run, read the default dataset. Every row has a type discriminator — filter on "transcript"; treat "error" as per-video failure. Missing captions, private/age-restricted/region-blocked videos, and bad URLs become error rows and the run still SUCCEEDS (including all-failed batches) so agent mistakes do not look like platform outages. The run fails only on a post-charge delivery failure (charged but could not write the dataset).
API / apify-client
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('kaz_kakyo/youtube-transcripts').call({ youtubeUrls: ['https://www.youtube.com/watch?v=jNQXAC9IVRw'], includeTimestamps: true },{ maxTotalChargeUsd: 1.0 }, // hard budget for this run);const { items } = await client.dataset(run.defaultDatasetId).listItems();const transcripts = items.filter((i) => i.type === 'transcript');
Same shape via REST: POST /v2/acts/kaz_kakyo~youtube-transcripts/runs with your token, then poll or attach a webhook.
Make it recurring (what sticky callers do)
- Save a Task in Console with your fixed options (
languages,includeTimestamps,includeSrt). Agents and cron jobs call the task id, not ad-hoc input. - Schedule the Task (hourly/daily) when the URL list is stable — e.g. a channel watchlist you refresh elsewhere.
- Webhook on
SUCCEEDEDto your endpoint / Zapier / Make — pulldefaultDatasetIdand process onlytype === "transcript"rows. - Cap spend on every automated run with
maxTotalChargeUsd. When the cap hits, remaining videos becometype: "error"skipped rows — no surprise bill, no silent free transcripts. - Chain: any YouTube search/channel scraper that outputs video URLs → this actor. For speech-to-text of arbitrary media files (not YouTube captions), use
kaz_kakyo/audio-transcriberwith a direct file URL instead.
Long runs checkpoint finished video IDs — a platform migration resumes without re-billing completed videos.
Output contract
One dataset item per input URL (plus skipped/invalid rows). Success shape:
{"type": "transcript","url": "https://www.youtube.com/watch?v=jNQXAC9IVRw","videoId": "jNQXAC9IVRw","title": "Me at the zoo","channel": "jawed","channelId": "UC…","durationSeconds": 19,"language": "en","languageName": "English","autoGenerated": false,"languageFallback": false,"transcript": "Full caption text…","availableLanguages": [{ "language": "en", "name": "English", "autoGenerated": false }],"segments": [{ "start": 0.0, "duration": 2.1, "text": "…" }],"srt": "1\n00:00:00,000 --> …"}
| Field | When present |
|---|---|
transcript, videoId, title, channel, durationSeconds, language, autoGenerated | always on success |
languageFallback | true when preferred languages did not match and another track was used |
availableLanguages | always on success |
segments | includeTimestamps: true |
srt | includeSrt: true |
segmentsUrl / srtUrl | rare — oversized payloads spilled to the key-value store |
Failure / skip row (never charged):
{ "type": "error", "url": "https://…", "videoId": "…", "error": "…", "errorCode": "captions_disabled" }
Download the dataset as JSON, CSV, Excel, or HTML from Console or the dataset API.
Why this one
- Cheap captions path. $0.005 per video undercuts typical Store $0.01+/result listings. Near-zero compute — HTTP only, no browser, no Whisper.
- Agent-safe. Bad/missing-caption URLs become
type: "error"rows; the run still succeeds. - Timestamps + SRT when you need them; plain
transcriptby default for RAG / MCP context packing. - Language-aware. Prefer your
languageslist; manual captions beat auto-generated within a language.
Pricing
| Event | Price | When |
|---|---|---|
| Transcript fetched | $0.005 | Successful caption delivery (one charge per video) |
| Actor start | $0.00005 | Per run |
Error / skipped rows are never billed. Cap spend with maxTotalChargeUsd on the run or task.
Input rules agents must follow
youtubeUrls(required) — YouTubewatch/shorts/youtu.be/embed/liveURLs, or bare 11-char video IDs. Max 500 per run. Duplicates are collapsed by video ID.languages— optional preferred BCP-47 codes in order (default prefersen, then any available).includeTimestamps— addssegments[]with{ start, duration, text }.includeSrt— adds an.srt-format string.
Videos with captions disabled, private/deleted, age-restricted, or region-blocked return error rows. This actor fetches existing YouTube captions — it does not run speech-to-text. For arbitrary audio/video file URLs, use kaz_kakyo/audio-transcriber.
See the Input tab for the full schema. See the API tab for run/dataset endpoints.
FAQ
Do I need a YouTube API key? No. The actor uses the public Innertube player + timedtext endpoints.
Manual vs auto captions? Within a preferred language, manual tracks are chosen over auto-generated (autoGenerated: true when ASR was used).
Why did my URL fail? No public captions, or the video is private / age-gated / region-blocked. Check error / errorCode on the dataset row — the run status will still be SUCCEEDED.
How do I keep costs predictable on a schedule? Set maxTotalChargeUsd on the run/task.
If this saved you time, a Store review on the actor page helps a solo dev. Hit a problem? Open an issue.
Telemetry
Each run records one anonymous event: a salted hash of the caller account ID (never the raw ID), run origin (Console / API / MCP / …), and a timestamp. No inputs, results, or personal data — adoption measurement only.