# YouTube Transcript Scraper: No API Key (`themineworks/youtube-transcript-scraper`) Actor

Get timestamped YouTube transcripts and captions as clean JSON with segments, fullText and char count. No API key, no login. Feed video transcripts straight into RAG, LLMs and AI agents via Claude, ChatGPT and any MCP server.

- **URL**: https://apify.com/themineworks/youtube-transcript-scraper.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Videos, AI
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 transcripts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## 📝 YouTube Transcript Scraper: Captions to Clean JSON (No API Key)

### Overview

YouTube Transcript Scraper pulls timestamped transcripts and captions from any public YouTube video and returns them as clean, structured JSON, ready to drop straight into a RAG pipeline, a vector store, or an LLM prompt. Give it a list of video URLs (or bare IDs) and get back per-video segments, a joined `fullText`, the caption language, and a character count.

No API key, no OAuth, no quota. It works on any public video, including auto-generated captions.

✅ No login required | ✅ No API key | ✅ Pay only for delivered transcripts | ✅ MCP-ready for AI agents

### Features

Structured JSON output. Per-segment `{ start, dur, text }` plus a joined `fullText`.
Any URL shape. `watch?v=`, `youtu.be`, `/shorts/`, `/embed/`, or bare 11-char IDs.
Language preference with fallback. Prefer `en`, `es`, `hi` and fall back to the default track.
Auto vs. human captions flagged. `isAutoGenerated` tells you which you got.
Free failure handling. Videos with captions disabled return `no-captions` and are never billed.

### How it works

The official YouTube Data API caption endpoints require OAuth, channel ownership, and a daily quota. You effectively cannot download the caption text of videos you do not own. This scraper reads the same public caption tracks YouTube already serves to any viewer's player. No key, no OAuth, no quota.

For each video, the actor resolves the canonical ID, reads available caption tracks from the watch page, and pulls the timed-text XML for the preferred language (falling back if that language is missing). Segments are cleaned into `{ start, dur, text }` items in seconds and joined into a readable `fullText`. Videos with captions disabled return `status: no-captions` and are not billed.

### 🧾 Input configuration

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://youtu.be/9bZkp7q19f0",
    "kJQP7kiw5Fk"
  ],
  "language": "en",
  "includeTimestamps": true,
  "proxy": { "useApifyProxy": true }
}
````

### 📤 Output format

```json
{
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley, Never Gonna Give You Up (Official Video)",
  "language": "en",
  "isAutoGenerated": false,
  "segments": [
    { "start": 18.8, "dur": 3.2, "text": "We're no strangers to love" },
    { "start": 22.0, "dur": 3.36, "text": "You know the rules and so do I" }
  ],
  "fullText": "We're no strangers to love You know the rules and so do I ...",
  "charCount": 1542,
  "segmentCount": 84,
  "status": "ok",
  "scrapedAt": "2026-07-10T09:15:00.000Z"
}
```

Every transcript record contains these fields:

| Field | Description |
| --- | --- |
| 🆔 `videoId` | 11-character YouTube video ID |
| 🔗 `url` | Canonical watch URL |
| 🏷️ `title` | Video title (null if unparsable) |
| 🌐 `language` | Language code of the caption track used |
| 🤖 `isAutoGenerated` | True for auto (ASR) captions, false for human/uploaded |
| ⏱️ `segments` | Ordered `{ start, dur, text }` items in seconds |
| 📝 `fullText` | All segment text joined into one readable string |
| 🔢 `charCount` | Character length of `fullText` |
| 📊 `segmentCount` | Number of transcript segments |
| 🚦 `status` | `ok`, `no-captions`, or `error` |
| 🕒 `scrapedAt` | ISO 8601 timestamp of the fetch |

The run also pushes a final `status: "summary"` record with counts (`transcriptsScraped`, `noCaptions`, `errored`, `chargedFor`).

### 💼 Common use cases

**RAG and vector search**
Chunk `fullText`, embed it, and let an LLM answer questions grounded in video content.
Chain into the rag-crawler to index entire channels.

**Video summarization**
Pipe transcripts to an LLM for TL;DRs, chapter markers, or highlight reels.
Batch process a channel to produce weekly digests.

**Content repurposing**
Turn webinars, podcasts, and tutorials into articles, show notes, and social posts.
Feed the `segments[]` array into a subtitle or translation workflow.

**Research and dataset building**
Mine spoken content across many videos for topics, keywords, and tone.
Assemble timestamped speech-to-text corpora for fine-tuning or analysis.

### 🚀 Getting started

1. Open the actor in Apify Console (or call it via API or MCP).
2. Under YouTube video URLs or IDs, paste one or more videos: watch URLs, `youtu.be` links, `/shorts/`, `/embed/`, or bare IDs.
3. Set preferred caption language (e.g. `en`, `es`, `hi`). The actor falls back to the default track if that language is missing.
4. Toggle Include timestamps on for `{ start, dur, text }` segments, or off for `fullText` only.
5. Click Save and Start, then download the dataset as JSON, CSV, or Excel, or pull via API or MCP.

### FAQ

**Do I need a YouTube API key or account?**
No. The scraper reads public caption tracks directly from the watch page and the public `timedtext` endpoint. No API key, no OAuth, no login, and no quota.

**What video URL formats are supported?**
Full `watch?v=` URLs, `youtu.be/…` short links, `/shorts/…`, `/embed/…`, and bare 11-character video IDs. Each resolves to the canonical video automatically.

**What happens if a video has no captions?**
The record comes back with `status: "no-captions"` and is not charged. Only videos that return an actual transcript are billed.

**Can I choose the caption language?**
Yes. Set preferred caption language to a two-letter code (e.g. `en`, `es`, `hi`, `fr`). The actor prefers an exact match, then a language-prefix match (`en` matches `en-US`), then the video's default track, then the first available, and reports what it used in `language`.

**Are auto-generated (ASR) captions supported?**
Yes. When only auto captions exist, the actor returns them and sets `isAutoGenerated: true`, so you can tell human captions apart from machine ones.

**How is it priced?**
Pay per result: one charge per transcript actually returned. The first 10 transcripts on every account are free for life, so you can test before you spend.

**Can I use it inside an AI agent?**
Yes. It is exposed as an MCP tool. See below.

### Use in Claude, ChatGPT & any MCP agent

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

Or call it programmatically with the Apify client:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('themineworks/youtube-transcript-scraper').call({
  videoUrls: ['https://www.youtube.com/watch?v=dQw4w9WgXcQ'],
  language: 'en',
  includeTimestamps: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### 🛠️ Complete your YouTube pipeline

Pair the transcript scraper with the rest of the video suite:

- **[YouTube Channel Scraper](https://apify.com/themineworks/youtube-channel)**: subscribers, video list, and channel stats, no API key.
- **[RAG Crawler](https://apify.com/themineworks/rag-crawler)**: index entire sites for LLM retrieval.
- **[Reddit Scraper](https://apify.com/themineworks/reddit-scraper)**: pull public posts and comment trees for training data.

Typical flow: youtube-channel discovers the videos, youtube-transcript-scraper turns them into text, the RAG crawler assembles the wider corpus.

Found a bug or have a feature request? Open an issue on the actor's Apify Console page or reach out through the Apify profile.

# Actor input Schema

## `videoUrls` (type: `array`):

List of YouTube videos to fetch transcripts for. Accepts full watch URLs (https://www.youtube.com/watch?v=...), youtu.be short links, /shorts/ URLs, /embed/ URLs, or bare 11-character video IDs.

## `language` (type: `string`):

Two-letter language code for the caption track to prefer (e.g. 'en', 'es', 'hi', 'fr'). If a track in this language is not available, the actor falls back to the video's default/first available track.

## `includeTimestamps` (type: `boolean`):

When enabled, each segment includes its start time and duration (in seconds). The joined fullText is always returned regardless of this setting.

## `proxy` (type: `object`):

Optional proxy. Apify Proxy (datacenter) is usually sufficient for the public YouTube caption endpoints. Use RESIDENTIAL only if you hit rate limits.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "language": "en",
  "includeTimestamps": true,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "language": "en",
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/youtube-transcript-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "language": "en",
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/youtube-transcript-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "language": "en",
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call themineworks/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=themineworks/youtube-transcript-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Transcript Scraper: No API Key",
        "description": "Get timestamped YouTube transcripts and captions as clean JSON with segments, fullText and char count. No API key, no login. Feed video transcripts straight into RAG, LLMs and AI agents via Claude, ChatGPT and any MCP server.",
        "version": "0.1",
        "x-build-id": "dhdSn86qWMfthPRUj"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/themineworks~youtube-transcript-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-themineworks-youtube-transcript-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/themineworks~youtube-transcript-scraper/runs": {
            "post": {
                "operationId": "runs-sync-themineworks-youtube-transcript-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/themineworks~youtube-transcript-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-themineworks-youtube-transcript-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "videoUrls"
                ],
                "properties": {
                    "videoUrls": {
                        "title": "YouTube video URLs or IDs",
                        "type": "array",
                        "description": "List of YouTube videos to fetch transcripts for. Accepts full watch URLs (https://www.youtube.com/watch?v=...), youtu.be short links, /shorts/ URLs, /embed/ URLs, or bare 11-character video IDs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "language": {
                        "title": "Preferred caption language",
                        "type": "string",
                        "description": "Two-letter language code for the caption track to prefer (e.g. 'en', 'es', 'hi', 'fr'). If a track in this language is not available, the actor falls back to the video's default/first available track.",
                        "default": "en"
                    },
                    "includeTimestamps": {
                        "title": "Include timestamps",
                        "type": "boolean",
                        "description": "When enabled, each segment includes its start time and duration (in seconds). The joined fullText is always returned regardless of this setting.",
                        "default": true
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional proxy. Apify Proxy (datacenter) is usually sufficient for the public YouTube caption endpoints. Use RESIDENTIAL only if you hit rate limits.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
