YouTube Transcript & RAG Chunker avatar

YouTube Transcript & RAG Chunker

Pricing

from $5.00 / 1,000 video chunkeds

Go to Apify Store
YouTube Transcript & RAG Chunker

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.

Pricing

from $5.00 / 1,000 video chunkeds

Rating

0.0

(0)

Developer

William

William

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

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

  1. Ingests video URLs, playlist URLs, channel URLs (any @handle, /channel/UC..., /c/Name, /user/Name), or free-text search queries.
  2. For each video, calls the ANDROID YouTube Innertube /player endpoint (no 1.3 MB watch-page fetch) to get both captions and full metadata in one tiny POST.
  3. Picks a caption track by your languages preference and captionPreference (manual vs ASR), with optional translateTo.
  4. Fetches the json3 caption track, rebuilds timed segments, and dedups ASR segments that repeat across boundary windows.
  5. 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) and wordCount so 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

FieldTypeDefaultDescription
startUrlsstring[](required)Video / playlist / channel / search URLs.
searchQueriesstring[][]Free-text queries; each is run and result videos enqueued.
languagesstring[]["en"]Preferred caption languageCodes in priority order.
captionPreferenceenummanualmanual prefer human captions; auto prefer ASR.
translateTostring(none)Optional &tlang translation languageCode.
chunkSizeTokensint512Target tokens per chunk (128-8192), tokenWindow mode.
chunkOverlapTokensint64Overlap tokens per chunk (0-512).
chunkingModeenumtokenWindowtokenWindow or timestampWindow.
timestampWindowSecondsint60Window length (10-600), timestampWindow mode.
tokenizerModelenumo200k_baseo200k_base (GPT-4o/4.1/o-series) or cl100k_base (GPT-4/3.5).
outputFormatsstring[]["chunkRows","json"]One or more of: chunkRows, json, srt, vtt, txt, markdown.
maxVideosint50Hard cap on videos processed across all sources (1-1000).
proxyConfigurationproxyresidential USApify 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, totalChunks
  • startMs, endMs, text, tokenCount, wordCount
  • deepLink (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), durationSec
  • description (truncated to 2000 chars), keywords, viewCount
  • language, isAsr, captionLanguage, sourceUrl
  • totalChunks, totalTokens, totalWords
  • chunks (nested, present unless chunkRows is also requested, in which case chunks travel as flat rows)
  • Optional srt, vtt, txt, markdown when 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_base matches GPT-4o / 4.1 / o-series; cl100k_base matches 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-OK playabilityStatus and retires the session.
  • Known limitations:
    • Channel URLs return ~30 latest videos. Deep history pagination via /browse continuation 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_captions status row, not a charged video row.
    • publishedAt is null on every video summary: the ANDROID /player client omits the upload date.
  • The actor does not store or download audio/video; it returns transcript text only.

Changelog

See CHANGELOG.md.