# YouTube Transcript Scraper - Transcripts with Timestamps (`datasignalslab/youtube-transcript-scraper`) Actor

Get the transcript of any YouTube video as clean text and as timestamped segments, in the language you choose. Works with manual and auto-generated captions. $2 per 1,000 transcripts, no API key, no login.

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

## Pricing

$2.00 / 1,000 transcript returneds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Transcript Scraper: transcripts with timestamps, built to keep working

Get the transcript of any YouTube video as clean text and as timestamped segments. Paste video URLs or ids, list the languages you prefer, and run. Built for teams that feed video content into an LLM, a search index or a content pipeline and need a source that is checked every day, because YouTube changes its player and most transcript tools break for a while when it does.

No API key, no quota, no login. It works with captions written by a person and with the captions YouTube generates automatically.

**Run it with the default input to see it work.** It returns the English transcript of one video, as full text and as segments.

### What you get

One row per video that has captions:

| field | meaning |
|---|---|
| `video_id` | The 11 character YouTube video id |
| `title` | Video title |
| `channel_name` | Channel that published the video |
| `channel_id` | Id of the channel |
| `duration_seconds` | Length of the video in seconds |
| `view_count` | Number of views |
| `language` | Language code of the transcript |
| `language_name` | Name of the caption track as YouTube shows it |
| `is_auto_generated` | True when YouTube generated the captions by speech recognition |
| `available_languages` | Every caption language the video has |
| `word_count` | Number of words in the transcript |
| `text` | The full transcript as one text |
| `segments` | The transcript per line with start time and duration in seconds. Null when timestamps are switched off |
| `url` | Link to the video |

Example row:

```json
{
  "video_id": "dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video)",
  "channel_name": "Rick Astley",
  "channel_id": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "duration_seconds": 213,
  "view_count": 1700000000,
  "language": "en",
  "language_name": "English",
  "is_auto_generated": false,
  "available_languages": [
    "de-DE",
    "en",
    "ja"
  ],
  "word_count": 487,
  "text": "We're no strangers to love You know the rules and so do I",
  "segments": [
    {
      "start": 18.64,
      "duration": 3.24,
      "text": "We're no strangers to love"
    }
  ],
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
```

### How to scrape YouTube transcripts with this Actor

1. Open the Actor in the Apify Console and click Try for free. The input is prefilled with one video URL and English.
2. Replace `videos` with the video URLs or ids you want, one per line. Watch URLs, youtu.be links, Shorts links and plain 11 character ids all work.
3. Put your preferred language codes in `languages`, in order. Leave `fallbackToAnyLanguage` on to get whatever language the video has when yours is missing, or switch it off to skip such videos for free.
4. Click Start. One row per video with captions appears in the Dataset tab. Export as JSON, CSV or Excel, or read the rows through the Apify API.
5. From code: `POST https://api.apify.com/v2/acts/datasignalslab~youtube-transcript-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN` with the same JSON input as the body.

### Input

| field | what it does |
|---|---|
| `videos` | video URLs (watch, youtu.be or Shorts) or 11 character video ids, one per line |
| `languages` | language codes in order of preference, default `en`. Captions written by a person win over auto-generated ones in the same language |
| `fallbackToAnyLanguage` | default on. When none of your languages exist, return the language the video does have |
| `includeTimestamps` | default on. Adds `segments` with start time and duration per line. The full `text` is always included |

Minimal input:

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

German if available, otherwise English, otherwise skip the video:

```json
{ "videos": ["dQw4w9WgXcQ", "https://youtu.be/jNQXAC9IVRw"], "languages": ["de", "en"], "fallbackToAnyLanguage": false }
```

Plain text only, for an LLM prompt:

```json
{ "videos": ["https://www.youtube.com/shorts/dQw4w9WgXcQ"], "languages": ["en"], "includeTimestamps": false }
```

### Pricing

Pay per transcript returned: **$2 per 1,000 transcripts**, which is $0.002 per video, charged only for rows that land in the dataset. A video without captions, a private video or a video in none of your languages with the fallback off returns nothing and costs nothing. No start fee. Apify's free monthly credit covers hundreds of transcripts, so you can evaluate without paying.

Example: 1,000 transcripts cost $2.00 and 10,000 cost $20.00. A channel's back catalogue of 350 videos costs $0.70. A daily schedule for 20 new videos is $0.04 a day, about $1.20 a month.

#### More from DataSignals Lab

This Actor is one of the pay-per-result data Actors of [DataSignals Lab](https://datasignalslab.com): job listings per ATS platform and job board, app and company reviews, YouTube comments and transcripts, website contacts and tech stacks. Every Actor returns the same clean JSON style and charges only for rows that land in the dataset, so you can combine feeds without remapping fields. All Actors and prices are listed on [datasignalslab.com](https://datasignalslab.com).

### Use cases

- LLM and RAG teams: `text` goes straight into a prompt or an embedding index, `segments` give the timestamp to link an answer back to the moment in the video.
- Content marketers: a video turned into a blog post, a newsletter or social posts, with `word_count` to pick the videos worth the effort.
- Researchers: the spoken text of lectures, interviews and talks, with `is_auto_generated` to decide how much cleanup a transcript needs.
- SEO teams: what a competitor's videos actually say, with `available_languages` to see which markets they caption for.
- Accessibility and localisation teams: the caption tracks a video already has, to find the languages still missing.
- AI agents that answer "what does this video say about X" from the real transcript through MCP.

Want the comments under the video as well? See [YouTube Comments Scraper](https://apify.com/datasignalslab/youtube-comments-scraper).

### YouTube transcript API alternative: how it compares

- YouTube's official API does not return caption text for videos you do not own. This Actor reads the caption tracks of any public video with captions.
- Several alternatives accept a channel URL with a maximum number of videos, translate on the fly or export SRT and VTT files. This Actor takes video URLs or ids only and returns JSON. `segments` has start and duration per line, so SRT or VTT is a few lines of code on your side.
- Reliability is the buying question in this niche. The Actor reads captions through the player endpoints of the YouTube mobile apps, tries each video over three connections, and is run against a known video every day so a change on YouTube's side is noticed the same morning.
- The price is $2 per 1,000 transcripts with no start fee and no charge for videos without captions. Most alternatives charge between $2 and $10 per 1,000.

### Reliability

The transcript niche breaks often. In 2026 YouTube changed its web player so that caption URLs return an empty body without a browser token, and timeouts and empty captions became the most common complaint about transcript tools. This Actor is built around that:

- Captions are read through the player endpoints the YouTube iOS and Android apps use, not the web player. Those endpoints returned working caption tracks when the web player stopped doing so.
- Each video is tried over up to three connections, with the iOS client first and the Android client second on each. The first two go through Apify's datacenter proxy, the third through a residential proxy, because YouTube sometimes asks a datacenter address to sign in.
- A health check runs every day against a known video and counts the run as healthy only when it returns at least one row. A run that succeeds with zero rows is treated as a failure and alerts us.
- The app client versions are constants in the source. When YouTube refuses an old version, the health check fails and the versions are raised in a new build.
- Rows are saved and charged per block of 20 videos, so a run that is stopped or hits your spending limit keeps what it has and charges only for that.

No tool can promise an uptime percentage against a source that changes without notice. What we promise is a daily check and a fix as soon as we know.

### Limits

- A transcript exists only when the video has captions. Videos without captions, private videos, age-restricted videos and live streams that are still running return nothing and cost nothing.
- Some videos require a sign-in when read from a datacenter address. The Actor retries those through a residential proxy. A video that still asks for a login is logged with the reason and costs nothing.
- Auto-generated captions contain recognition errors and have no punctuation. `is_auto_generated` tells you which kind you got.
- Translations that YouTube can generate on the fly are not included. You get the languages the video actually has, listed in `available_languages`.
- No channel URL, playlist or search input. List the video URLs or ids, one per line. No SRT or VTT export, use `segments`.
- No caching. Every run reads YouTube live and every returned transcript is charged, also when you ran the same video yesterday.
- Video details beyond title, channel, duration and views are out of scope.

### FAQ

#### Is it legal to scrape YouTube transcripts?

The Actor reads the caption tracks YouTube serves for any public video, with no login. The transcript is the creator's content, so what you may do with it depends on your use case and the copyright rules that apply to you. Respect YouTube's terms of service and, if you are unsure, ask a lawyer.

#### Do I need a YouTube API key or a Google account?

No. There is no API key, no quota and no login. Paste the video URL and run.

#### Why does the YouTube Transcript Scraper return nothing for some videos?

Because the video has no captions, is private, is age-restricted or is a live stream that is still running. The run log names the reason per video. Such videos cost nothing.

#### Which language does the YouTube Transcript Scraper pick?

The first language in `languages` the video has, with a caption track written by a person preferred over an auto-generated one in the same language. A code like `en` also matches `en-US` and `en-GB`. If none of your languages exist and `fallbackToAnyLanguage` is on, you get the video's own language and `language` tells you which.

#### How much do 10,000 YouTube transcripts cost?

$20.00. There is no start fee and nothing is charged for videos without captions.

#### Can I schedule it or feed it a whole channel?

You can schedule it in the Apify Console with a fixed list of videos. There is no channel URL input, so for a channel you collect the video ids first, for example from a channel scraper or your own list, and pass them in `videos`.

#### Can an AI agent (MCP) call the YouTube Transcript Scraper?

Yes. Add the Apify MCP server to Claude, ChatGPT or another agent and the Actor shows up as a tool. The agent passes a video URL and gets the transcript back as JSON, ready to summarise or quote with timestamps.

#### What happens when YouTube changes something and transcripts stop?

The daily health check fails on the first morning after the change and we get an alert. The fix is usually a new client version or a changed field in the player response, both of which live in one source file. Runs during the gap return zero rows and charge nothing.

### Integrations

- Apify API, including `run-sync-get-dataset-items` for one call that returns the rows.
- Schedules and webhooks from the Apify Console, for feeds and for triggering your own processing when a run finishes.
- Apify MCP server, so Claude, ChatGPT and other agents call this Actor as a tool.
- Make, Zapier, n8n and Google Sheets through the Apify integrations, or CSV and Excel export from the Dataset tab.

### Support

Use the Issues tab on this page, or email support@datasignalslab.com. You get an answer within one working day. Built and maintained by [DataSignals Lab](https://datasignalslab.com).

### Changelog

- 2026-10: README rewritten with a step-by-step guide, a Reliability section, honest limits and a FAQ. No change to the output fields or the price.
- 2026-10: First release. Transcripts per video through the mobile app player endpoints, language preference with manual over auto-generated, timestamps per line, three attempts per video with a residential fallback. Daily health check in place.

# Actor input Schema

## `videos` (type: `array`):

One per line: a YouTube video URL (watch, youtu.be or Shorts) or the 11 character video id.

## `languages` (type: `array`):

Language codes in order of preference, for example en, de, es. The first one the video has is used. Captions written by a person are preferred over auto-generated ones.

## `fallbackToAnyLanguage` (type: `boolean`):

When the video has none of the preferred languages, return the transcript in the language it does have. Switch off to skip such videos, which then cost nothing.

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

Adds the transcript per line with start time and duration. The full text is always included.

## Actor input object example

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": true,
  "includeTimestamps": true
}
```

# Actor output Schema

## `transcripts` (type: `string`):

All transcripts from this run as JSON, one object per video.

## `transcriptsCsv` (type: `string`):

The same transcripts as a CSV download, without the segments.

# 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 = {
    "videos": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "languages": [
        "en"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datasignalslab/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 = {
    "videos": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "languages": ["en"],
}

# Run the Actor and wait for it to finish
run = client.actor("datasignalslab/youtube-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 '{
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "languages": [
    "en"
  ]
}' |
apify call datasignalslab/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datasignalslab/youtube-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/Zs1ygXVHIqhNYg6xv/builds/njAvgNmhcA6eAaUQY/openapi.json
