# YouTube Transcript Scraper — Subtitles & Captions API (`anuarbakty/youtube-transcript-scraper`) Actor

Scrape YouTube transcripts, subtitles and captions from videos, Shorts, channels, playlists and search. Any language with fallback; text, timestamps, SRT, VTT or chunks for AI, plus title, views, likes, date and channel. Works with MCP, n8n and Make. No captions, no charge.

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

## Pricing

from $3.25 / 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.
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?

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

Scrape the transcript of any YouTube video, Short, channel, playlist or search, with the video's details in the same row. Paste links in any form, pick your languages, and get clean text, timestamped segments, paragraphs, chunks for AI, SRT, VTT or XML. You pay only for transcripts delivered: videos without captions, private or removed videos and blocked requests are free rows, and there is no start fee.

### What does YouTube Transcript Scraper do?

- **Takes every kind of YouTube link.** Videos (`watch?v=`, `youtu.be`, `/live/`, `/embed/`, mobile and music links, bare ids), Shorts, channels (`@handle`, `/channel/UC…`, `/c/`, `/user/`), channel tabs (`/shorts`, `/streams`), playlists, search pages and plain search words — all in one list.
- **Gets the captions you ask for.** Author captions or YouTube's auto-generated ones, in your languages in order of preference, with a fallback to the language spoken in the video. Each row says which language and kind it got and why.
- **Returns the formats you need.** Timestamped segments, one plain text string, readable paragraphs, chunks for AI with a link to their second of the video, `[1:23]`-style timestamped text, SRT, VTT and XML, with `[Music]`-style labels removed and `&#39;` turned back into characters. Word-level timestamps for auto-generated captions. Optional `.srt`, `.vtt` and `.txt` files with download links.
- **Adds the video details.** Title, channel, @handle, channel avatar, subscribers, exact publish time, duration, views, likes, comment count, category, tags, description, thumbnail, Shorts and live flags.
- **Reads 8 videos at a time** and moves on to a fresh address by itself whenever YouTube refuses one.
- **Explains every video it could not transcribe** in a free row with a code (`NO_CAPTIONS`, `LANGUAGE_NOT_FOUND`, `PRIVATE`, `AGE_RESTRICTED`…), a plain-English message, the languages the video does have, and whether running it again may help.
- **Runs inputs made for other transcript Actors.** Field names of the most used ones (`youtube_url`, `videoUrls`, `startUrls`, `channel_url`, `max_videos`, `transcript_type`, `output_formats`, `language`…) are read as they are, so a saved input or an n8n flow keeps working.

### What YouTube data can you extract?

| Group | Fields |
|---|---|
| Transcript | `transcript` (lines with `start`, `duration`, `end`, `text`, optional `words`), `text`, `paragraphs`, `chunks`, `timestampedText`, `srt`, `vtt`, `xml`, `fileUrls`, `segmentCount` |
| Language | `language`, `languageName`, `captionType` (manual / auto), `isAutoGenerated`, `languageMatch` (requested / fallback / original / all), `availableLanguages`, `requestedLanguages` |
| Video | `videoId`, `url`, `title`, `description`, `keywords`, `category`, `thumbnailUrl`, `durationSeconds`, `duration`, `publishedAt`, `publishDate`, `isShort`, `isLive`, `wasLive`, `isUnlisted`, `isFamilySafe` |
| Engagement | `viewCount`, `likeCount`, `commentCount` |
| Channel | `channelName`, `channelId`, `channelUrl`, `channelHandle`, `channelThumbnailUrl`, `subscriberCount` |
| Run | `status`, `errorCode`, `message`, `retryable`, `inputType`, `input`, `position`, `scrapedAt`, `runTag` |

### What can you use YouTube transcripts for?

- **AI and RAG.** Feed lectures, interviews and product videos to ChatGPT, Claude or a vector database; the timestamps let an answer link to the exact second.
- **Content research.** Read what a channel says across its last 50 videos without watching them: health channels, clinics, physical therapists, software tutorials, conference talks.
- **Subtitles for editing.** SRT and VTT files ready for Premiere, DaVinci Resolve, CapCut or a web player.
- **SEO and repurposing.** Turn videos into articles, show notes, summaries and quotes.
- **Monitoring.** Schedule a run on a channel with "published after: 1 day" to get each new video's transcript.
- **Accessibility and translation work.** See which languages a channel already offers, for free, before ordering captions.

### How to scrape YouTube transcripts

1. Paste one or more links or video ids into **YouTube links or video ids**, or type **Search words**.
2. Set **Languages** (default `en`; the original language is taken when none of yours exists).
3. Choose **Transcript formats** and, for channels and searches, **Videos per channel tab, playlist or search**.
4. Click **Start**. Each video becomes one row; download it as JSON, CSV, Excel or HTML, or read it through the API.

#### One video

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

#### Many videos at once, with SRT

```json
{
    "urls": ["https://youtu.be/arj7oStGLkU", "https://www.youtube.com/shorts/eW5Oi91m4SY", "jNQXAC9IVRw"],
    "outputFormats": ["segments", "text", "srt"]
}
```

#### Spanish first, then English, author captions only

```json
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "languages": ["es", "en"], "captionType": "manualOnly" }
```

#### The last 30 days of a channel, videos and Shorts

```json
{ "urls": ["https://www.youtube.com/@TED"], "channelTabs": ["videos", "shorts"], "publishedAfter": "30 days", "maxVideosPerSource": 0 }
```

#### A playlist

```json
{ "urls": ["https://www.youtube.com/playlist?list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo"], "maxVideosPerSource": 100 }
```

#### A search, this week only

```json
{ "searchTerms": ["physical therapy after knee replacement"], "publishedAfter": "7 days", "maxVideosPerSource": 20 }
```

#### Chunks for ChatGPT, Claude or a vector database

```json
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "outputFormats": ["chunks"], "chunkWords": 200 }
```

Each chunk comes with `start`, `end`, `wordCount` and a `url` that opens the video at that second, so an AI answer can cite the moment it came from.

#### Subtitle files to download

```json
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "saveFiles": true }
```

The row gets `fileUrls` with links to the `.srt`, `.vtt` and `.txt` files.

#### Which languages does a video have? (free)

```json
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "listLanguagesOnly": true }
```

#### Every language of a video

```json
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "allLanguages": true, "outputFormats": ["text"] }
```

### How much does it cost to scrape YouTube transcripts?

You pay per transcript delivered; see the **Pricing** tab for the price on your plan.

- **No start fee.** One video per run costs the same as one video in a batch, which matters for n8n, Make and API calls made video by video.
- **Free rows.** Videos without captions, without your language, private, removed, age-restricted, members-only, upcoming, or blocked after every retry cost nothing.
- **Video details are included** in the transcript price: date, likes, comment count and subscribers are not extra.
- **Free language lists.** `listLanguagesOnly` returns the details and languages of any number of videos without charge.
- **Spending limits that hold.** `maxItems` stops the run after that many transcripts, and the run's cost limit in Apify is respected to the cent.

### Input

| Field | What it does | Default |
|---|---|---|
| `urls` | Videos, Shorts, channels, channel tabs, playlists, search pages, video ids, `@handles` | — |
| `searchTerms` | Search words, one search per line | — |
| `languages` | Language codes or names in order of preference; `en` matches `en-US` and `en-GB` | `["en"]` |
| `fallbackToAnyLanguage` | Take the video's original language when none of yours exists | `true` |
| `captionType` | `manualFirst`, `autoFirst`, `manualOnly`, `autoOnly` | `manualFirst` |
| `allLanguages` | One row per caption language of the video | `false` |
| `listLanguagesOnly` | Only details and languages, no transcript, free | `false` |
| `outputFormats` | Any of `segments`, `text`, `paragraphs`, `chunks`, `timestampedText`, `srt`, `vtt`, `xml` | `["segments", "text"]` |
| `chunkWords` | Words per chunk in the `chunks` format | `150` |
| `saveFiles` | Also save `.srt`, `.vtt`, `.txt` files and put their links in `fileUrls` | `false` |
| `removeNonSpeech` | Remove `[Music]`, `[Applause]`, music notes and `[ __ ]` | `true` |
| `wordTimestamps` | Start and end of every word (auto-generated captions) | `false` |
| `includeDetails` | Exact publish time, likes, category, Shorts flag, @handle | `true` |
| `includeEngagement` | Comment count and channel subscribers | `true` |
| `maxVideosPerSource` | Videos per channel tab, playlist or search; 0 = all | `50` |
| `channelTabs` | `videos`, `shorts`, `streams` | `["videos"]` |
| `publishedAfter`, `publishedBefore` | `2026-09-01`, or `30 days`, `2 weeks`, `6 months` | — |
| `maxItems` | Most transcripts in the whole run; 0 = no limit | `0` |
| `includeErrorRows` | Free rows for videos without a transcript | `true` |
| `deduplicate` | Each video once per run | `true` |
| `failIfAllInputsFail` | End the run as failed when no transcript came, for alerts | `false` |
| `strictInput` | Stop before the first request on an unknown field name | `true` |
| `runTag` | Text copied into every row | — |
| `proxyConfiguration` | Leave as it is; the Actor picks addresses itself | Apify Proxy |

### Output

One row per transcript (and one free row per video without one). A shortened example:

```json
{
    "status": "ok",
    "videoId": "arj7oStGLkU",
    "url": "https://www.youtube.com/watch?v=arj7oStGLkU",
    "title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED",
    "channelName": "TED",
    "channelId": "UCAuUUnT6oDeKwE6v1NGQxug",
    "channelUrl": "https://www.youtube.com/channel/UCAuUUnT6oDeKwE6v1NGQxug",
    "channelHandle": "@TED",
    "channelThumbnailUrl": "https://yt3.ggpht.com/ytc/AIdro_koIFcCOrvh0KThLNOiazAIDu6hcs…",
    "subscriberCount": 27900000,
    "publishedAt": "2016-04-06T16:59:35.000Z",
    "publishDate": "2016-04-06",
    "durationSeconds": 844,
    "duration": "14:04",
    "viewCount": 62071153,
    "likeCount": 2055271,
    "commentCount": 79000,
    "category": "People & Blogs",
    "keywords": ["TED Talk", "TED Talks", "Tim Urban", "procrastination"],
    "description": "Tim Urban knows that procrastination doesn't make sense, but he's never been able to shake his habit of waiting until th…",
    "thumbnailUrl": "https://i.ytimg.com/vi/arj7oStGLkU/sddefault.jpg",
    "isShort": false,
    "isLive": false,
    "wasLive": false,
    "isUnlisted": false,
    "isFamilySafe": true,
    "language": "en",
    "languageName": "English",
    "captionType": "manual",
    "isAutoGenerated": false,
    "languageMatch": "requested",
    "availableLanguages": [
        { "code": "ar", "name": "Arabic", "type": "manual", "isDefault": false },
        { "code": "en", "name": "English", "type": "manual", "isDefault": true },
        { "code": "en", "name": "English (auto-generated)", "type": "auto", "isDefault": false }
    ],
    "segmentCount": 286,
    "transcript": [
        { "start": 12.645, "duration": 1.37, "end": 14.015, "text": "So in college," },
        { "start": 15.349, "duration": 1.564, "end": 16.913, "text": "I was a government major," },
        { "start": 16.937, "duration": 2.462, "end": 19.399, "text": "which means I had to write a lot of papers." }
    ],
    "text": "So in college, I was a government major, which means I had to write a lot of papers. Now, when a normal student writes a paper…",
    "paragraphs": null,
    "chunks": null,
    "timestampedText": null,
    "srt": null,
    "vtt": null,
    "xml": null,
    "fileUrls": null,
    "requestedLanguages": ["en"],
    "errorCode": null,
    "message": null,
    "retryable": null,
    "inputType": "video",
    "input": "https://www.youtube.com/watch?v=arj7oStGLkU",
    "position": null,
    "scrapedAt": "2026-10-17T20:10:00.000Z",
    "runTag": null
}
```

Every row has the same fields in the same order, so a spreadsheet or an n8n flow reads transcripts and free rows alike. A run summary by input is saved in the key-value store as `SUMMARY`.

#### Status and error codes

| `status` | `errorCode` | Meaning | Charged |
|---|---|---|---|
| `ok` | — | A transcript | yes |
| `listed` | — | Details and languages only (`listLanguagesOnly`) | no |
| `no_transcript` | `NO_CAPTIONS` | The video has no captions at all | no |
| `no_transcript` | `LANGUAGE_NOT_FOUND` | None of your languages; `availableLanguages` lists what exists | no |
| `no_transcript` | `NO_MANUAL_CAPTIONS`, `NO_AUTO_CAPTIONS` | Not the kind of captions asked for | no |
| `no_transcript` | `EMPTY_TRANSCRIPT` | The track holds only sound labels | no |
| `failed` | `PRIVATE`, `REMOVED`, `UNAVAILABLE`, `AGE_RESTRICTED`, `MEMBERS_ONLY`, `LOGIN_REQUIRED` | YouTube does not show the video to visitors | no |
| `failed` | `UPCOMING`, `LIVE_NOW`, `LIVE_RECORDING_UNAVAILABLE` | Live and scheduled videos | no |
| `failed` | `BLOCKED`, `REGION_BLOCKED`, `FETCH_FAILED` | YouTube refused every address tried; `retryable: true` | no |
| `failed` | `CHANNEL_NOT_FOUND`, `PLAYLIST_NOT_FOUND`, `NO_VIDEOS`, `INVALID_INPUT` | The input line points at nothing | no |

### Integrations and API

- **n8n and Make:** use the Apify node or module, Actor `anuarbakty/youtube-transcript-scraper`, input `{ "urls": ["{{ video link }}"] }`, then read `text` or `transcript` from the dataset items. One video per call costs no more than one video in a batch.
- **Python:**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("anuarbakty/youtube-transcript-scraper").call(run_input={"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"]})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["status"], row["language"], row["text"][:200] if row["text"] else row["message"])
```

- **JavaScript:**

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('anuarbakty/youtube-transcript-scraper').call({ urls: ['https://www.youtube.com/watch?v=arj7oStGLkU'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].text);
```

- **AI agents (MCP):** connect Apify's MCP server (`https://mcp.apify.com`) to Claude, Cursor, VS Code or ChatGPT and ask "get the transcript of this YouTube video"; the agent calls this Actor and reads the rows.

### Is it legal to scrape YouTube transcripts?

The Actor reads only what YouTube shows any visitor who is not signed in: public captions and public video details. It does not sign in, does not download video or audio, and does not touch private or members-only content. How you use the transcripts is up to you; check YouTube's terms and the copyright of the channels you work with, and ask a lawyer when in doubt.

### More from this developer

- **[Facebook Ads Library Scraper](https://apify.com/anuarbakty/facebook-ads-library-scraper)**: ads from the Meta Ad Library by keyword, brand, page or Instagram account, with creatives, days running and EU reach.
- **[Threads Scraper](https://apify.com/anuarbakty/threads-scraper)**: posts, all replies and profiles from Threads without login, keyword search and only-new monitoring.
- **[2GIS Places Scraper](https://apify.com/anuarbakty/2gis-places-scraper)**: businesses from 2GIS (Russia, Kazakhstan, Central Asia, UAE) with phones, WhatsApp, Telegram, emails and websites.
- **[2GIS Reviews Scraper](https://apify.com/anuarbakty/2gis-reviews-scraper)**: 2GIS reviews with star, topic and date filters and only-new monitoring.

### FAQ

**What if a video has no captions?** You get a free row with `status: "no_transcript"` and `errorCode: "NO_CAPTIONS"`, plus the video's details.

**What if my language is missing?** With `fallbackToAnyLanguage` on (the default), the original language comes and `languageMatch` says `fallback`. With it off, a free row lists `availableLanguages` so you can choose.

**Author or auto-generated captions?** Author captions come first by default; set `captionType` to `autoFirst`, `manualOnly` or `autoOnly` to change that. `captionType` in each row says which one came.

**Does it work for Shorts and live streams?** Yes: Shorts links, a channel's Shorts tab, and recordings of past streams. A stream that is still live gives a free `LIVE_NOW` row; run it again once it ends.

**How do I get only new videos of a channel?** Schedule the Actor with the channel link and `publishedAfter` set to the schedule's interval, for example `1 day`.

**Can I use inputs from another YouTube transcript Actor?** Yes. Field names of the most used transcript Actors are read as they are. An unknown field stops the run before any charge and says which field it was, so a limit never goes unnoticed.

**Is there a limit on videos per run?** No fixed one. Use `maxVideosPerSource` per channel, playlist or search, and `maxItems` for the whole run.

**Something does not work?** Open an issue on the Actor's **Issues** tab and paste the link to the run. A run linked in an issue opens to the developer automatically: its log, input and results, and nothing else in your account. To share every run of this Actor instead, turn on **Share run data with developers** in Apify Console under Settings → Login & Privacy.

# Actor input Schema

## `urls` (type: `array`):

One per line, in any form YouTube uses:<br>• a <b>video</b>: <code>youtube.com/watch?v=…</code>, <code>youtu.be/…</code>, <code>/live/…</code>, <code>/embed/…</code>, or the bare 11-character id<br>• a <b>Short</b>: <code>youtube.com/shorts/…</code><br>• a <b>channel</b>: <code>youtube.com/@handle</code>, <code>/channel/UC…</code>, <code>/c/name</code>, <code>/user/name</code>, or just <code>@handle</code> → its newest videos (add <code>/shorts</code> or <code>/streams</code> for those tabs)<br>• a <b>playlist</b>: <code>youtube.com/playlist?list=…</code><br>• a <b>search page</b>: <code>youtube.com/results?search_query=…</code><br>Also read under the names <code>startUrls</code>, <code>videoUrls</code>, <code>youtube_url</code>, <code>channel_url</code> and others, so inputs made for other transcript Actors work as they are.

## `searchTerms` (type: `array`):

Search YouTube for these words, one search per line, and transcribe the videos found (videos only, in YouTube's order). The limit per channel below applies to each search.

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

Language codes such as <code>en</code>, <code>es</code>, <code>pt-BR</code> or names such as <code>English</code>. The first one the video has is taken; <code>en</code> also matches <code>en-US</code> and <code>en-GB</code>. Leave empty for the language spoken in the video.

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

On: a video without captions in your languages gives its captions in the language spoken in it, and <code>languageMatch</code> says <code>fallback</code>. Off: such a video gives a free row with the code <code>LANGUAGE_NOT_FOUND</code> and the list of its languages.

## `captionType` (type: `string`):

Author captions are uploaded by the channel and are usually cleaner; auto-generated captions are YouTube's speech recognition. Each row says which one came in <code>captionType</code>.

## `allLanguages` (type: `boolean`):

One row per caption language of the video (each is a transcript and is charged as one). The languages above are not used then.

## `listLanguagesOnly` (type: `boolean`):

No transcripts: one free row per video with the video details and <code>availableLanguages</code>. Useful to see what a channel offers before transcribing it.

## `outputFormats` (type: `array`):

What each row holds: <b>segments</b> — the <code>transcript</code> array of lines with <code>start</code>, <code>duration</code>, <code>end</code> in seconds; <b>text</b> — one plain string; <b>paragraphs</b> — the text split at pauses into readable paragraphs with their times; <b>chunks for AI</b> — pieces of about 150 words with times and a link to that second of the video, for ChatGPT, Claude and RAG; <b>timestamped text</b> — lines like <code>\[1:23] …</code>; <b>SRT</b>, <b>VTT</b> and <b>XML</b> as strings.

## `chunkWords` (type: `integer`):

Size of each piece in the <b>chunks for AI</b> format. Pieces are cut between caption lines, so they hold about this many words.

## `saveFiles` (type: `boolean`):

Every transcript is also saved as three files in the run's key-value store, and the row gets their links in <code>fileUrls</code>. Handy for video editors and for sending a file to a client.

## `removeNonSpeech` (type: `boolean`):

Also removes music notes and YouTube's <code>\[ \_\_ ]</code> for bleeped words. HTML entities such as <code>\&#39;</code> are always turned into characters.

## `wordTimestamps` (type: `boolean`):

Every line of an auto-generated transcript gets a <code>words</code> list with the start and end of each word. Author captions have no word timings, so their lines get <code>words: null</code>.

## `includeDetails` (type: `boolean`):

One light extra request per video. Title, channel, views, duration, description, tags and thumbnail come in every row anyway.

## `includeEngagement` (type: `boolean`):

One more request per video. YouTube shows large numbers rounded (2.4M), and so do these fields.

## `maxVideosPerSource` (type: `integer`):

The newest videos of a channel come first. 0 means no limit. Single video links are not counted here.

## `channelTabs` (type: `array`):

Which lists of a channel to read when the link points at the channel itself. A link to <code>/shorts</code> or <code>/streams</code> reads only that tab.

## `publishedAfter` (type: `string`):

For channels, playlists and searches: <code>2026-09-01</code>, or a span back from today such as <code>30 days</code>, <code>2 weeks</code>, <code>6 months</code>. Videos outside the dates are skipped and not charged.

## `publishedBefore` (type: `string`):

Same forms as above.

## `maxItems` (type: `integer`):

The run stops after this many transcripts, whatever the inputs. 0 means no limit.

## `includeErrorRows` (type: `boolean`):

A free row with <code>status</code>, <code>errorCode</code> and <code>message</code> for every video that has no captions, is private, removed, age-restricted or blocked. Off: such videos only appear in the run summary.

## `deduplicate` (type: `boolean`):

A video found by several inputs (a channel and a search, say) is transcribed and charged once.

## `failIfAllInputsFail` (type: `boolean`):

For monitoring and automations that should alert on an empty result. By default such a run still succeeds and explains every video in a free row.

## `strictInput` (type: `boolean`):

A limit written under a name the Actor does not know would be ignored, so by default the run stops before the first request and says which field is unknown. Off: unknown fields are ignored.

## `runTag` (type: `string`):

Any text; it is copied into every row as <code>runTag</code>, to tell runs apart in one table.

## `proxyConfiguration` (type: `object`):

Leave as it is: the Actor uses Apify datacenter proxies and moves the caption request to residential ones when YouTube refuses an address. Set your own only if you need to.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=arj7oStGLkU"
  ],
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": true,
  "captionType": "manualFirst",
  "allLanguages": false,
  "listLanguagesOnly": false,
  "outputFormats": [
    "segments",
    "text"
  ],
  "chunkWords": 150,
  "saveFiles": false,
  "removeNonSpeech": true,
  "wordTimestamps": false,
  "includeDetails": true,
  "includeEngagement": true,
  "maxVideosPerSource": 50,
  "channelTabs": [
    "videos"
  ],
  "maxItems": 0,
  "includeErrorRows": true,
  "deduplicate": true,
  "failIfAllInputsFail": false,
  "strictInput": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "urls": [
        "https://www.youtube.com/watch?v=arj7oStGLkU"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("anuarbakty/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 = {
    "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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