YouTube Transcript & RAG Chunker
Pricing
from $5.00 / 1,000 video chunkeds
YouTube Transcript & RAG Chunker
Get the full transcript of any YouTube video, playlist, channel or search - as plain text, SRT/VTT, or RAG-ready token-window chunks (overlap, dedup, token counts, deep links). Transcript-only or transcript + chunks, your choice. Multi-language + translation. Per-video pricing.
Turn YouTube into a vector database in one run. Returns retrieval-ready transcript chunks plus SRT/VTT/TXT/JSON/Markdown — built for LLM apps, agents, knowledge bases, fine-tuning, search and accessibility. It is the only YouTube transcript actor that ships token-window chunking with overlap, ASR dedup, per-chunk token counts and deep-link timestamps out of the box, so you can embed every chunk without a preprocessing step.
Best for: RAG over video, LLM fine-tuning datasets, semantic search, content moderation, agent memory, subtitles, and accessibility. Input a video, playlist, channel or search query; get the full transcript of each video on its summary row, plus one self-contained row per chunk.
Turn YouTube videos, playlists, channels and search queries into RAG-ready transcript chunks and standard subtitle formats. Purpose-built for retrieval: token-window chunking with overlap, ASR boundary-reflow deduplication, per-chunk token counts, and deep-link timestamps so every chunk links back to the exact moment in the video. Also emits SRT, VTT, plain-text, JSON and Markdown.
You are charged per successfully chunked video (price set in the Apify Console). Videos with no captions, blocks, or failures are returned as uncharged status rows.
Two modes
- Transcript only (
includeRagChunks: false) — want just the transcript? Set this off. You get one clean row per video carrying the full transcript (plus title/channel/duration/etc. and optional SRT/VTT/Markdown). No chunk rows, no chunking — ideal when you simply need the text. - Transcript + RAG chunks (
includeRagChunks: true, default) — the full transcript and token-window chunk rows (one chunk per line, with overlap, dedup, token counts and deep links) for vector-DB / RAG ingestion.
In both modes the full transcript is always present on each video's summary row in the transcript field.
What it does
- Ingests video URLs, playlist URLs, channel URLs (any
@handle,/channel/UC...,/c/Name,/user/Name), or free-text search queries. - For each video, calls the ANDROID YouTube Innertube
/playerendpoint (no 1.3 MB watch-page fetch) to get both captions and full metadata in one tiny POST. - Picks a caption track by your
languagespreference andcaptionPreference(manual vs ASR), with optionaltranslateTo. - Fetches the
json3caption track, rebuilds timed segments, and dedups ASR segments that repeat across boundary windows. - Chunks by token window (with overlap) or fixed timestamp window, counts tokens with the chosen tokenizer, and emits the formats you requested.
Why it is different
The chunking surface is the product. Most transcript actors hand you one big text blob; this one hands you retrieval primitives:
- Token-window chunking with configurable overlap (carries context across chunk boundaries).
- ASR boundary-reflow deduplication (YouTube auto captions re-emit text at window edges; we collapse it).
- Per-chunk
tokenCount(o200k_base / cl100k_base) andwordCountso you can budget embeddings/context. - Per-chunk
deepLink(https://youtu.be/<id>?t=<sec>s) so a retrieved chunk can cite its source moment. - Optional SRT / VTT / TXT / Markdown attached to each video summary for non-RAG use cases.
Input fields
| Field | Type | Default | Description |
|---|---|---|---|
startUrls | string[] | (required) | Video / playlist / channel / search URLs. |
searchQueries | string[] | [] | Free-text queries; each is run and result videos enqueued. |
languages | string[] | ["en"] | Preferred caption languageCodes in priority order. |
captionPreference | enum | manual | manual prefer human captions; auto prefer ASR. |
translateTo | string | (none) | Optional &tlang translation languageCode. |
chunkSizeTokens | int | 512 | Target tokens per chunk (128-8192), tokenWindow mode. |
chunkOverlapTokens | int | 64 | Overlap tokens per chunk (0-512). |
chunkingMode | enum | tokenWindow | tokenWindow or timestampWindow. |
timestampWindowSeconds | int | 60 | Window length (10-600), timestampWindow mode. |
tokenizerModel | enum | o200k_base | o200k_base (GPT-4o/4.1/o-series) or cl100k_base (GPT-4/3.5). |
outputFormats | string[] | ["chunkRows","json"] | One or more of: chunkRows, json, srt, vtt, txt, markdown. |
maxVideos | int | 50 | Hard cap on videos processed across all sources (1-1000). |
proxyConfiguration | proxy | residential US | Apify Proxy config. Residential US is strongly recommended. |
Output
Three row shapes land in the default dataset:
Flat chunk row (type: "chunk", free, emitted when chunkRows is requested):
chunkId,videoId,index,totalChunksstartMs,endMs,text,tokenCount,wordCountdeepLink(https://youtu.be/<videoId>?t=<seconds>s)videoTitle,channelName,channelId,language,isAsr,captionLanguage,sourceUrl
Video summary row (type: "video", charged, emitted for every chunked video):
videoId,title,channelName,channelId,publishedAt(null on the ANDROID client),durationSecdescription(truncated to 2000 chars),keywords,viewCountlanguage,isAsr,captionLanguage,sourceUrltotalChunks,totalTokens,totalWordschunks(nested, present unlesschunkRowsis also requested, in which case chunks travel as flat rows)- Optional
srt,vtt,txt,markdownwhen those formats are requested
Status row (type: "status", free): no_captions / blocked / failed / unsupported_url, with videoId, url, reason.
Example input
{"startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ","https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf","https://www.youtube.com/@mkbhd/videos"],"searchQueries": ["apify actor tutorial"],"languages": ["en"],"captionPreference": "manual","chunkSizeTokens": 512,"chunkOverlapTokens": 64,"chunkingMode": "tokenWindow","tokenizerModel": "o200k_base","outputFormats": ["chunkRows", "json", "srt"],"maxVideos": 50,"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US" }}
Pricing
Charged per successfully chunked video (one type: "video" row per video). Set the USD unit price in the Apify Console; the actor honours ACTOR_MAX_TOTAL_CHARGE_USD to cap spend. Flat chunk rows and status rows are free.
Important notes
- Token counts are estimates for non-OpenAI models.
o200k_basematches GPT-4o / 4.1 / o-series;cl100k_basematches GPT-4 / 3.5. For Claude, embedding models, or other tokenisers, expect 5-15% drift. Size your chunks with headroom. - Residential US proxy is the default. Datacenter egress can be bot-flagged and silently return no
captionTracks; the actor detects non-OKplayabilityStatusand retires the session. - Known limitations:
- Channel URLs return ~30 latest videos. Deep history pagination via
/browsecontinuation is unreliable and intentionally not implemented. Use playlist URLs for exhaustive channel crawls. - Search returns ~20 results per query (the first results page).
- Videos without captions produce a free
no_captionsstatus row, not a charged video row. publishedAtisnullon every video summary: the ANDROID/playerclient omits the upload date.
- Channel URLs return ~30 latest videos. Deep history pagination via
- The actor does not store or download audio/video; it returns transcript text only.
Changelog
See CHANGELOG.md.