# YouTube Subtitles (`scrapewise/youtube-subtitles`) Actor

Download YouTube subtitles as ready-to-use SRT and VTT files, with a download link for each file, plus plain text. Pick the language, manual or auto-generated captions, and videos, playlists or channels. Videos without subtitles are free. Pay per video.

- **URL**: https://apify.com/scrapewise/youtube-subtitles.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Videos, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 subtitles delivereds

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

## YouTube Subtitles

Download YouTube subtitles as ready-to-use **SRT and VTT files**, with a download link for each file, plus the plain text. Pick the language and whether you want manual or auto-generated subtitles; paste single videos, a playlist or a channel.

### What you get

- **Real subtitle files.** Each video's subtitles are saved as `<videoId>-<language>.srt` and `.vtt` files you can download straight from the link in `srtFileUrl` and `vttFileUrl`, or from the run's key-value store.
- **The file content in the dataset too**, in the `srt` and `vtt` fields, plus the plain `text`, for workflows that do not download files.
- **Language of your choice**, in order of preference, with optional YouTube translation.
- **Manual or auto-generated:** `captionType` picks human-made subtitles only, auto-generated only, or the best available.
- **Videos without subtitles never fail the run.** They come back with an `errorCode` and are **not charged**.
- **Playlists and channels** expand into their videos, with a per-source limit.

### Use cases

- Download subtitles to edit in Premiere, DaVinci Resolve or Subtitle Edit, or to re-upload on another platform.
- Grab SRT files for a whole course playlist to translate or localize.
- Add subtitles to your own player or video site with WebVTT.

### Input

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/playlist?list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo"
  ],
  "subtitleFormats": ["srt", "vtt"],
  "saveSubtitleFiles": true,
  "languages": ["es", "en"],
  "captionType": "any",
  "maxVideosPerSource": 10,
  "maxItems": 50
}
```

| Field | What it does |
|---|---|
| `videoUrls` | Video URLs or IDs. Playlist, channel and search URLs also work. |
| `subtitleFormats` | `srt`, `vtt` or both (default both). |
| `saveSubtitleFiles` | Save each subtitle as a downloadable file and add the link to the item (default on). |
| `languages` | Subtitle languages in order of preference. |
| `translateTo` | Optional YouTube translation. |
| `captionType` | Advanced: `any`, `manual` or `auto`. |
| `maxVideosPerSource`, `publishedAfter`, `includeShorts`, `onlyNewVideos` | Advanced: for playlists and channels. |
| `maxItems` | Hard limit for the whole run (default 50). |

### Output

One item per video:

```json
{
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "language": "en",
  "languageName": "English",
  "isAutoGenerated": false,
  "availableLanguages": ["en", "de-DE", "ja", "pt-BR", "es-419"],
  "srt": "1\n00:00:01,360 --> 00:00:03,040\n[♪♪♪]\n...",
  "vtt": "WEBVTT\n\n00:00:01.360 --> 00:00:03.040\n[♪♪♪]\n...",
  "srtFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/dQw4w9WgXcQ-en.srt",
  "vttFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/dQw4w9WgXcQ-en.vtt",
  "text": "[♪♪♪] ♪ We're no strangers to love ♪ ...",
  "errorCode": null,
  "scrapedAt": "2026-09-13T01:30:00+00:00"
}
```

Items without subtitles have `error` and `errorCode` filled in and are not charged:

| errorCode | Meaning |
|---|---|
| `NO_CAPTIONS` | The video has no subtitles |
| `NO_CAPTIONS_IN_LANGUAGE` | No subtitles of the requested type |
| `VIDEO_UNAVAILABLE` / `VIDEO_UNPLAYABLE` | Private, removed or region-locked video |
| `AGE_RESTRICTED` | Age restricted video |
| `LIVE_NOT_ENDED` | Live stream still running or upcoming |
| `BLOCKED` | YouTube blocked every attempt; try again |

### Pricing

**From US$ 3.50 per 1,000 videos with subtitles delivered, no monthly fee.** US$ 5.00 on the Free plan, lower on paid Apify plans:

| Apify plan | Per 1,000 videos with subtitles |
|---|---|
| Free | US$ 5.00 |
| Starter (Bronze) | US$ 4.50 |
| Scale (Silver) | US$ 4.00 |
| Business (Gold) and above | US$ 3.50 |

One charge per video, whether you take SRT, VTT or both. Videos without subtitles, unavailable or blocked are free.

### How to use

- **Console:** paste the URLs, click Start, open the Storage tab to download the `.srt` and `.vtt` files, or export the dataset.
- **API:** `POST https://api.apify.com/v2/acts/scrapewise~youtube-subtitles/run-sync-get-dataset-items?token=YOUR_TOKEN` with the input as the body, then fetch `srtFileUrl`.
- **Integrations:** n8n, Make, Zapier and Google Drive through the Apify integrations.

### FAQ

**How long do the download links work?**
The files live in the run's default key-value store and follow your Apify data retention (unnamed storages are kept for the retention period of your plan). Copy them elsewhere if you need them longer.

**Can I get subtitles in a language the video does not have?**
Set `translateTo`. It uses YouTube's own translation, which YouTube refuses for many requests; when it does, the original language is delivered and `translationError` says why.

**Are auto-generated subtitles included?**
Yes, when there are no manual ones in your languages. Use `captionType: "manual"` to get human-made subtitles only.

**Does it create subtitles for videos that have none?**
No. It downloads the subtitles YouTube already has.

**Can I use it from an AI agent (MCP)?**
Yes, through the Apify MCP server, like any Apify Actor. The agent gets the subtitle text and the `srtFileUrl` / `vttFileUrl` links.

### Limitations

- Only videos with subtitles (manual or auto-generated) can be downloaded.
- Age-restricted videos and running live streams are not supported.
- YouTube blocks most datacenter IPs, so residential proxy is the default. Keep it on.
- Something broke? Open an issue on the Actor page. Issues are answered within 12 hours.

This Actor collects only public data and respects the site's terms.

### Changelog

- **2026-09-14:** lower price, from US$ 3.50 per 1,000 on paid plans (US$ 5.00 on Free).
- **2026-09-13, 0.1:** first release. SRT and VTT files with download links, language preference, manual or auto-generated subtitles, playlists and channels.

Keywords: youtube subtitles, youtube subtitles downloader, youtube srt, download youtube subtitles, youtube vtt.

# Actor input Schema

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

YouTube video URLs (watch, youtu.be, shorts, embed, live) or 11-character IDs. Playlist, channel and search URLs also work: their videos are expanded, limited by the advanced setting 'Max videos per channel, playlist or search'.

## `subtitleFormats` (type: `array`):

Subtitle file formats to deliver. Each one comes as a field with the full file and, with 'Save subtitle files' on, as a downloadable file. Same price for one or both.

## `saveSubtitleFiles` (type: `boolean`):

Saves each subtitle as a .srt or .vtt file in the run's key-value store (named <videoId>-<language>.srt) and adds 'srtFileUrl' / 'vttFileUrl' download links to the item.

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

Subtitle languages in order of preference (e.g. en, es, pt-BR). If none is available, the first manual subtitle is used, then the auto-generated one.

## `translateTo` (type: `string`):

Language code to translate with YouTube's own translation (e.g. es, pt). YouTube refuses most of these requests; when it does, the original language is delivered and the reason is recorded in translationError.

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

Which captions to use. Videos without the requested type come back with errorCode NO\_CAPTIONS\_IN\_LANGUAGE and are not charged.

## `includeSegments` (type: `boolean`):

Adds a 'segments' array with text, start and duration (seconds) for each caption line.

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

For playlist, channel and search URLs: how many videos to take from each one.

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

Skip videos published before this date (YYYY-MM-DD). Skipped videos produce no item and are not charged.

## `includeShorts` (type: `boolean`):

Include Shorts when listing a channel or a search. Off: regular videos and past live streams only.

## `onlyNewVideos` (type: `boolean`):

Remembers which videos of each channel, playlist or search already got delivered (in a named key-value store in your account, 'youtube-subtitles-only-new-videos') and skips them on the next runs. Ideal for a daily or weekly schedule. Videos without captions are tried again next time, free.

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

Hard limit for the whole run, across all inputs. Protects your budget.

## `tryDatacenterFirst` (type: `boolean`):

Each video is tried twice through datacenter proxy before falling back to the proxy below. Keeps runs fast and cheap.

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

YouTube blocks most datacenter IPs; residential proxy is the default and recommended.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "subtitleFormats": [
    "srt",
    "vtt"
  ],
  "saveSubtitleFiles": true,
  "languages": [
    "en",
    "pt",
    "pt-BR",
    "es"
  ],
  "captionType": "any",
  "includeSegments": false,
  "maxVideosPerSource": 10,
  "includeShorts": false,
  "onlyNewVideos": false,
  "maxItems": 50,
  "tryDatacenterFirst": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

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

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

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/youtube-subtitles").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 '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapewise/youtube-subtitles --silent --output-dataset

```

## MCP server setup

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

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/hmoJk2JcrUA28HMhK/builds/GvNk4fOs1evCoOfmZ/openapi.json
