# YouTube Transcript Scraper – Text & Timestamps (`scrapingmonkey/youtube-video-transcript-scraper`) Actor

Extract existing YouTube captions from video URLs. Get full transcript text, timed segments, language details, caption tracks, and video context in one row.

- **URL**: https://apify.com/scrapingmonkey/youtube-video-transcript-scraper.md
- **Developed by:** [ScrapingMonkey](https://apify.com/scrapingmonkey) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

Extract the captions already available for public YouTube videos, with readable text and segment timing. **YouTube Transcript Scraper** keeps the full transcript, language information, caption-track details, and video context in one row per input.

Use it to index spoken content, prepare research notes, or connect passages to their position in a video. It retrieves existing captions; it does not generate speech-to-text from videos that have none.

| At a glance | Details |
|---|---|
| 📥 Input | Full YouTube video URLs, with an optional caption language |
| 📤 Output | Full text, timed segments, selected language, caption tracks, and video context |
| 🔐 Login required | No YouTube credentials or cookies |
| ⚡ Processing | Up to 5 requests concurrently with automatic retries |
| 💾 Delivery | One transcript row per processed input; segments stay in that row |

### What the YouTube transcript scraper extracts 🔎

The Actor selects one caption track for each input and collects the text YouTube makes available from that track.

- Full transcript text and number of nonempty segments
- Segment text, start, duration, end, and a readable timestamp
- Selected language code, source-track name, and requested language
- Automatic-caption and translation indicators
- Available caption tracks and translation-language options
- Video ID, source URL, title, channel ID, author, and available view count

### How to scrape YouTube video transcripts 🚀

1. Add one or more full video URLs to `inputList`.
2. Leave `language` empty for automatic selection, or enter a code such as `en`.
3. Start the Actor and review transcript and failed rows.
4. Export full text or the aligned segment columns for your workflow.

```json
{
  "inputList": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ]
}
```

### YouTube transcript data fields and output 📦

| Field group | Included data |
|---|---|
| Video context | ID, URL, title, author, channel ID, and views |
| Transcript | Full text, availability flag, and segment count |
| Timing | Text, start, duration, end, and timestamp for each segment |
| Language | Requested and selected language, track name, generated and translated flags |
| Track options | Available caption tracks and translation languages |

Complete illustrative success item. The content and values below are fictional examples, not a live result:

```json
{
  "input": "https://www.youtube.com/watch?v=TrailWalk01x",
  "status": "success",
  "video.id": "TrailWalk01x",
  "video.url": "https://www.youtube.com/watch?v=TrailWalk01x",
  "video.title": "A forest walk in three stops",
  "video.channel_id": "UCaaaaaaaaaaaaaaaaaaaaaa",
  "video.author": "Trail Journal",
  "video.views": 12400,
  "requested_language": null,
  "language": "en",
  "language_name": "English",
  "is_generated": false,
  "is_translated": false,
  "transcript_available": true,
  "full_text": "Welcome to the forest trail. We will stop at the viewpoint and follow the river back.",
  "segments.text": [
    "Welcome to the forest trail.",
    "We will stop at the viewpoint and follow the river back."
  ],
  "segments.start_seconds": [
    0.0,
    3.0
  ],
  "segments.duration_seconds": [
    2.5,
    4.0
  ],
  "segments.end_seconds": [
    2.5,
    7.0
  ],
  "segments.timestamp": [
    "0:00.000",
    "0:03.000"
  ],
  "segments_count": 2,
  "tracks.name": [
    "English"
  ],
  "tracks.language_code": [
    "en"
  ],
  "tracks.vss_id": [
    ".en"
  ],
  "tracks.url": [
    "https://www.youtube.com/api/timedtext?v=TrailWalk01x&lang=en"
  ],
  "tracks.is_auto_generated": [
    false
  ],
  "tracks.is_translatable": [
    true
  ],
  "translation_languages.language_code": [
    "es"
  ],
  "translation_languages.name": [
    "Spanish"
  ]
}
```

One video transcript stays in one table row. JSON uses the same literal dotted keys as the columns. Entries in `segments.text`, `segments.start_seconds`, and the other segment columns align by position. Times are in seconds; gaps and overlapping captions can reflect the source track.

Missing optional fields can be `null`, empty strings, or empty lists. Some flags default to `false` when no signal is present. A failed row retains `input`, sets `status` to `failed`, and leaves the result-data fields null.

### Input requirements and coverage ⚙️

| Parameter | Type | Default | Rules |
|---|---|---|---|
| `inputList` | array of strings | Required | At least one full YouTube video URL. Bare video IDs are not accepted. |
| `language` | string | `""` | Optional language code, such as en or es. Empty prefers English, then the first available track. |

Accepted video forms include watch URLs, youtu.be links, and supported /shorts/, /live/, /embed/, or /v/ URLs. Bare IDs and channel links are not accepted.

Language selection first looks for the requested code, then a track in the same base language. With no match, it prefers English or the first track and requests translation only if YouTube exposes that language and the source track permits translation. An unsupported language or a video without usable caption text produces a failed result. `language_name` describes the selected source track; for translated text, use `language` to identify the output language.

Repeated input entries are processed separately, even when they refer to the same target. Remove duplicate entries before the run if you want to avoid repeated results.

### YouTube transcript use cases 🎯

#### Searchable video libraries

Index full transcript text with the video URL so a search can return both the passage and its source.

#### Research and quotations

Locate passages with segment start times, then check the original video before quoting or interpreting them.

#### Caption-based language workflows

Collect an available language track or supported translation and retain flags that identify its origin.

#### Accessibility review

Inspect the text and timing supplied with videos you manage to find captions that need manual review.

### Pricing and billable transcript rows 💰

Check the Actor's **Pricing** tab for the current charging model and rate.

Under dataset-item pricing, each saved success or failed row can be billable. Automatic retries do not independently create extra rows. Repeated input entries can produce repeated billable results.

A transcript with many segments remains one dataset item. Missing captions or an unavailable requested language can result in a saved failed row.

### YouTube Video Transcript Scraper API and integrations 🔌

Use the Actor ID from the **API** tab as `$ACTOR_ID` and your Apify token as `$APIFY_TOKEN`.

```bash
curl -X POST "https://api.apify.com/v2/acts/$ACTOR_ID/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"inputList":["https://www.youtube.com/watch?v=jNQXAC9IVRw"]}'
```

This request starts a run. Retrieve the default dataset after completion, or use schedules and webhooks to connect it to a recurring workflow. Export JSON, CSV, or Excel, or send selected fields to Google Sheets, Make, Zapier, or your own application.

### Reliability and limits ⚠️

Temporary request failures are retried. Invalid or unavailable targets produce failed rows while other inputs can continue. If a required collection step cannot be completed, the target can fail even when some public information is visible in a browser.

Caption availability can differ by video, language, region, or access state. Automatic captions and YouTube translations can contain errors; the output preserves their text rather than correcting it. Empty caption responses and inaccessible tracks can fail. Caption URLs may expire.

### Frequently asked questions ❓

#### Can it transcribe a video with no captions?

No. It retrieves existing caption tracks and does not run speech recognition.

#### Which language is selected by default?

English is preferred when available; otherwise the first available track is used.

#### Can I request a translated transcript?

Yes, when the selected track is translatable and YouTube lists the requested translation language. Unsupported requests fail.

#### Does each segment become a row?

No. Full text and all timed segments stay in one transcript row.

#### Are generated captions identified?

Yes. `is_generated` identifies an automatic source track, while `is_translated` identifies a requested translation.

#### Are timestamps exact word timings?

They describe caption segments supplied by YouTube, not separate timing for every word.

### Support, responsible use, and related actors 🛟

For a reproducible issue, share the run ID, a safe public input, and the field or behavior you expected through the Actor's support channel. Keep tokens and other credentials out of support messages.

Use public content in accordance with applicable privacy, copyright, contractual, and platform requirements.

# Actor input Schema

## `inputList` (type: `array`):

Add full YouTube video URLs, one per item. Raw video IDs are not accepted.

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

Language code such as en or es. Leave empty to prefer English, then the first available track. Translation is requested only when YouTube exposes it.

## Actor input object example

```json
{
  "inputList": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ]
}
```

# Actor output Schema

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

Success and failed rows. Check the status column.

# 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 = {
    "inputList": [
        "https://www.youtube.com/watch?v=jNQXAC9IVRw"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapingmonkey/youtube-video-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 = { "inputList": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"] }

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

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

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

```

## CLI example

```bash
echo '{
  "inputList": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ]
}' |
apify call scrapingmonkey/youtube-video-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapingmonkey/youtube-video-transcript-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Wu7Krq8tyNJ51XO8g/builds/c8Qyb9SrvqTNic69f/openapi.json
