YouTube Transcript Scraper

Export public YouTube captions as transcript text and timestamped segments. Use video URLs or IDs, select a language, and download JSON or CSV for research and RAG.

Data fields

FieldTypeDescription
videoIdstringYouTube video identifier.
videoUrlstringCanonical public watch URL.
titlestringPublic title when metadata is enabled and available; otherwise omitted.
channelNamestringPublic channel name when enabled and available; otherwise omitted.
languagestringLanguage of the selected caption track; may differ from the requested language.
isAutoGeneratedbooleanWhether the selected track is marked as auto-generated; omitted when unavailable.
transcriptTextstringCombined caption text when extraction succeeds.
segmentsarrayCaption text segments. Timing properties are included only when requested.

Input preview

videoUrls🎬 YouTube video URLs
videoIdsVideo IDs
languagePreferred caption language
includeTimestampsInclude timestamps
includeMetadataInclude video metadata
maxVideosMaximum videos

API and agents

This actor can be run through Apify API, datasets, webhooks, schedules, and the official Apify MCP server.

How this actor works

See example inputs, outputs, API usage, and practical limits before running this actor on Apify.

Open Apify page

Export public YouTube captions as transcript text and optional timestamped segments. Supply video URLs or IDs, request a caption language, and download JSON or CSV for research, summaries, search indexes, and RAG.

This Actor retrieves existing public captions and may request a YouTube-provided translation when supported. It does not transcribe audio with AI when captions are missing or run its own translation model.

Quick start

Paste one public video URL, keep maxVideos small, and inspect captionsAvailable, error, and transcriptText before using the output.

{
  "videoUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "language": "en",
  "includeTimestamps": true,
  "includeMetadata": true,
  "maxVideos": 1
}

Example output

Illustrative shortened success record; the caption text below is not taken from the linked video. Optional metadata is omitted in this example.

{
  "videoId": "dQw4w9WgXcQ",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "language": "en",
  "isAutoGenerated": false,
  "transcriptText": "Illustrative caption text.",
  "segments": [
    {
      "start": 0,
      "duration": 2.1,
      "text": "Illustrative caption text."
    }
  ],
  "captionsAvailable": true
}

What does it return?

One result row identifies each processed video. Successful results can include combined caption text, segment text, timing in seconds, the selected language, and available title/channel metadata. Unavailable captions or failed videos produce diagnostic rows; other videos in the batch can still complete.

Who is it for?

  • Research teams: search and compare public talks, lectures, and interviews.
  • Content teams: review webinar or demo captions and prepare source-linked summaries.
  • RAG builders: chunk transcript text and retain video URLs and timestamps.
  • Media reviewers: check language availability and caption quality before downstream use.

Input settings

Setting JSON key Type / default What it does
YouTube video URLs videoUrls array / not set Public YouTube watch, shorts, live, embed, or youtu.be URLs to extract transcripts from.
Video IDs videoIds array / [] Optional raw 11-character YouTube video IDs. Use this instead of URLs if you already have IDs.
Preferred caption language language string / "en" Preferred caption language, such as en, es, de, or fr. The Actor may request a YouTube-provided translation when supported, then fall back to another available track. Check the returned language.
Include timestamps includeTimestamps boolean / true Include start and duration values for every transcript segment.
Include video metadata includeMetadata boolean / true Include title, channel name, duration, and thumbnail URL when YouTube exposes them publicly.
Maximum videos maxVideos integer / 5 Maximum number of videos to process in this run. Keep this low for the first test run. Minimum 1; maximum 500.
Proxy configuration proxyConfiguration object / {"useApifyProxy":true,"apifyProxyGroups":["RESIDENTIAL"]} Optional proxy configuration for blocked requests. The input default selects Apify Residential Proxy; the current Actor tries direct access first and uses the configured proxy as fallback. Check your run cost before scaling.

URL and language behavior

Accepted inputs include watch, Shorts, live, embed, and youtu.be URLs. Put raw 11-character IDs in videoIds. Neither input mode discovers all videos on a channel.

The Actor first looks for the requested language or a related language variant. When supported, it may request a YouTube-provided caption translation. If that request fails or is unavailable, another public track can be selected; always check the returned language. With includeTimestamps: false, segments still contain text but timing fields are omitted. Metadata fields may be omitted when disabled or unavailable.

Tips and limits

  • Check availability: private, deleted, members-only, region-restricted, or captionless videos may not yield transcript text.
  • Check accuracy: automated captions can contain recognition errors; verify quotes against the original video.
  • Control batch size: use maxVideos to cap work, especially when proxy fallback is needed.
  • Handle partial results: inspect error even when the run completes; do not index an error row as a transcript.
  • Respect content rights: public accessibility does not grant redistribution or model-training rights. Use captions only where your processing is permitted.

API usage

Use your Apify API token through the APIFY_TOKEN environment variable. Node.js and Python examples wait for the run and read its first dataset page; paginate the dataset for larger exports.

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/youtube-transcript-scraper').call({
  "videoUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "language": "en",
  "includeTimestamps": true,
  "includeMetadata": true,
  "maxVideos": 1
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import json
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = json.loads('''{
  "videoUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "language": "en",
  "includeTimestamps": true,
  "includeMetadata": true,
  "maxVideos": 1
}''')
run = client.actor("fetch_cat/youtube-transcript-scraper").call(run_input=run_input)
print(client.dataset(run["defaultDatasetId"]).list_items().items)

cURL

Save the quickstart JSON as input.json. This request starts a run asynchronously; use its returned run ID to check completion and its defaultDatasetId to retrieve results.

curl -X POST "https://api.apify.com/v2/acts/fetch_cat~youtube-transcript-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @input.json

MCP and AI agents

Use the official Apify MCP server, not a separate custom server. The focused URL below selects this Actor. Authenticate with Apify when your client prompts you; configuration syntax and OAuth support depend on the client.

Claude Code

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

HTTP-capable MCP client configuration

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/youtube-transcript-scraper"
    }
  }
}

Example prompt: "Extract captions from these two public YouTube URLs. Summarize successful transcripts with timestamped source references and list unavailable videos separately."

Use the same input keys as the input table. Review the returned source URLs and any error or availability fields before using results in an automated summary.

Common workflows

  • Knowledge-base updates: submit newly published video URLs, then send successful transcripts to your document or vector store.
  • Scheduled reviews: schedule a fixed input list with Apify and compare exports downstream; channel discovery is a separate step.
  • Timestamped summaries: ask your downstream model to cite the video URL and segment start time for each claim.

Support

If a run fails or output looks wrong, open an issue from the Actor page. Include the Apify run ID or run URL, non-sensitive input JSON, expected output, actual output, and one reproducible public URL (or the exact search input). Do not share tokens, cookies, passwords, or private data.

Common questions

Questions and answers reused from the canonical actor README.

Does it work without YouTube cookies?

It is designed for public videos and caption tracks without a YouTube login. Apify API and MCP access still require Apify authentication.

Why is transcript text missing?

Read error and captionsAvailable. Captions may be unavailable, inaccessible, or blocked for that request. A successful batch run does not mean every video yielded text.

Can I request Spanish or French captions?

Yes, set language to es or fr. Check the returned language because the Actor can fall back to another available track.

Does it export SRT or VTT files?

This Actor returns a dataset with text and optional segments. Use the segment timing to create subtitle files downstream; it does not promise native SRT/VTT output.