# Wicked YouTube Transcript Scraper API (`myworkingmemory/wicked-youtube-transcript-scraper-api`) Actor

YouTube transcripts from the videos’ own captions. One video or 250 per run, nothing truncated. Plain text, timestamped segments, video facts and caption languages in every result; SRT/WebVTT on request. $0.70 per 1,000, no start fee, failed videos free.

- **URL**: https://apify.com/myworkingmemory/wicked-youtube-transcript-scraper-api.md
- **Developed by:** [Myworkingmemory LLC](https://apify.com/myworkingmemory) (community)
- **Categories:** Automation, Developer tools, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.70 / 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/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

## Wicked YouTube Transcript Scraper API

Timestamped transcripts of public YouTube videos, straight from their own caption tracks. One video or 250 in a run. Plain text, timestamped segments, video facts and the caption-language list in every result. **$0.70 per 1,000 transcripts**, one flat price per delivered transcript. Nothing else on the bill.

### What you get, every result

- **Plain-text transcript** (`text`), ready for an LLM.
- **Timestamped segments** (`data`): `start`, `dur`, `text`, seconds to three decimals.
- **Video facts**: title, channel, duration, view count, description, keywords, thumbnail.
- **Every caption language the video has**, manual and auto-generated, so you know what else you can ask for.
- **SRT and WebVTT** subtitle text when you ask for them.

### What you will not pay for here

- **No start fee.** No per-run fee. The bill is one flat price per delivered transcript: $0.0007, which is $0.70 per 1,000.
- **No cap of 100.** Up to **250 videos per run**, and every one is processed. A longer list is refused up front, never cut off quietly.
- **No charge for a video without captions.** It is reported, not billed.
- **No charge to list languages.** Ask for the caption languages only and the run is free.
- **No charge for video facts, SRT or WebVTT.** They ride along with the transcript.
- **No translation sold that does not work.** A language the video lacks fails at once, free, with the languages it does have listed.

### How it picks the captions

Give one language, or a priority list such as `["es", "en"]`; the first language the video has captions in wins. Manual captions come before auto-generated ones unless you choose `manual` only or `auto` only. The video must carry captions in that language: there is no audio transcription and no translation.

### Input

| Field | Type | Description |
|---|---|---|
| `videoUrl` | string | One YouTube video URL (watch, youtu.be, Shorts, embed, live) or 11-character ID. |
| `videoUrls` | array of strings | Up to **250** URLs or IDs in one run. Duplicates merged. Above 250: refused before any work, nothing charged. |
| `targetLanguage` | string, default `en` | ISO 639-1 code of the captions you want. |
| `languages` | array of strings | Priority list, e.g. `["es", "en"]`. Replaces `targetLanguage` when set. |
| `captionType` | `any` / `manual` / `auto`, default `any` | `any` = manual first, then auto-generated. |
| `outputFormats` | array: `srt`, `vtt` | Adds subtitle text to each result. Free. |
| `listOnly` | boolean, default `false` | Only list each video's caption languages and facts. Free. Answer is in the `OUTPUT` record. |
| `includeMetadata` | boolean, default `true` | Video facts on every result. Free. |

One video:

```json
{ "videoUrl": "https://www.youtube.com/watch?v=jNQXAC9IVRw", "targetLanguage": "en" }
```

A batch with a fallback language and subtitle files:

```json
{
  "videoUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw", "https://youtu.be/IELMSD2kdmk"],
  "languages": ["es", "en"],
  "outputFormats": ["srt", "vtt"]
}
```

Languages only, free:

```json
{ "videoUrls": ["jNQXAC9IVRw", "IELMSD2kdmk"], "listOnly": true }
```

### Output

One dataset item per delivered transcript, written the moment it is ready:

```json
{
  "videoId": "jNQXAC9IVRw",
  "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "title": "Me at the zoo",
  "channel": "jawed",
  "channelId": "UC4QobU6STFB0P71PMvOGN5A",
  "durationSeconds": 19,
  "viewCount": 353000000,
  "description": "…",
  "keywords": ["…"],
  "thumbnailUrl": "https://i.ytimg.com/vi/jNQXAC9IVRw/hqdefault.jpg",
  "language": "en",
  "languageName": "English",
  "captionType": "manual",
  "availableLanguages": [
    { "code": "en", "name": "English", "type": "manual" },
    { "code": "en", "name": "English (auto-generated)", "type": "auto" }
  ],
  "text": "All right, so here we are, in front of the elephants\nthe cool thing about these guys is that they have really, really, really long trunks",
  "data": [
    { "start": "1.200", "dur": "4.000", "text": "All right, so here we are, in front of the elephants" },
    { "start": "5.200", "dur": "5.600", "text": "the cool thing about these guys is that they have really, really, really long trunks" }
  ],
  "srt": "1\n00:00:01,200 --> 00:00:05,200\nAll right, so here we are, in front of the elephants\n…",
  "vtt": "WEBVTT\n\n00:00:01.200 --> 00:00:05.200\nAll right, so here we are, in front of the elephants\n…"
}
```

`srt` and `vtt` appear only when requested. With `includeMetadata: false` the facts are left out.

The run's key-value store holds an `OUTPUT` record: for one video, the same item; for a batch, `{ "requested", "delivered", "deliveredVideoIds", "failed": [ { "videoId", "error", "message", "availableLanguages" } ] }`; for `listOnly`, each video's facts and caption languages. A failed video is never written to the dataset, so it is never charged. Error codes: `INVALID_URL`, `VIDEO_UNAVAILABLE`, `PRIVATE_OR_RESTRICTED`, `AGE_RESTRICTED`, `NO_CAPTIONS`, `NO_CAPTIONS_IN_LANGUAGE`, `EMPTY_TRACK`, `BLOCKED`, `TIMEOUT`.

### Use it from code

**JavaScript**

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('myworkingmemory/wicked-youtube-transcript-scraper-api').call({
  videoUrls: ['https://www.youtube.com/watch?v=VIDEO_ID'],
  languages: ['en'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].title, items[0].text);
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("myworkingmemory/wicked-youtube-transcript-scraper-api").call(run_input={
    "videoUrls": ["https://www.youtube.com/watch?v=VIDEO_ID"],
    "languages": ["en"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["videoId"], item["title"], item["text"][:80])
```

**One HTTP call**, transcript in the response body:

```
POST https://api.apify.com/v2/acts/myworkingmemory~wicked-youtube-transcript-scraper-api/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>
{ "videoUrl": "https://www.youtube.com/watch?v=VIDEO_ID", "targetLanguage": "en" }
```

**Postman:** the collection and spec are published at https://documenter.getpostman.com/view/59146422/2sBYHVvJvA (public workspace "Myworkingmemory LLC APIs"); OpenAPI spec: https://www.myworkingmemory.ai/apis/wicked-youtube-transcript-scraper-api.openapi.json.

**AI agents and MCP:** add this Actor as a tool through the Apify MCP server (`https://mcp.apify.com`); any MCP client can then fetch a transcript on demand.

### In the Console

1. Paste one URL, or up to 250 in the batch list. Pick a language, or a priority list.
2. Start.
3. Read the Transcripts view (plain text) or the Segments view, download, or fetch through the API.

### Limits

- Public videos with captions only. Private, removed and age-restricted videos cannot be read.
- No audio transcription. No translation.
- 250 videos per run. Playlists and channels are not expanded; pass video URLs.

### Pricing

**$0.0007 per delivered transcript, $0.70 per 1,000.** No start fee, no per-run fee, nothing for a video without captions, nothing for a language listing, nothing for facts, SRT or WebVTT. A batch of 250 costs $0.175. The pricing card at the top of this page is the binding rate.

### Privacy

The Actor reads the public caption tracks and video facts you ask for. Results live in your own run's dataset and key-value store. Nothing is kept elsewhere and no user text is collected.

### FAQ

**Does it work on every YouTube video?** Only public videos that have captions.

**Can I get a language the video has no captions in?** No. The run fails for that video, free, and lists the languages it does have.

**How many videos per run?** Up to 250, all processed. A longer list is refused before any work.

**Is there a start fee or a per-run fee?** No. $0.0007 per delivered transcript, nothing else.

**Does listing languages cost anything?** No. `listOnly` runs are free.

**Can I use it with LangChain, an agent or a RAG pipeline?** Yes. Plain JSON, callable through the Apify API, the SDKs, or as an MCP tool.

# Actor input Schema

## `videoUrl` (type: `string`):

One public YouTube video URL (watch, youtu.be, Shorts, embed, live) or its 11-character ID. For many videos use the list below instead, or as well.

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

Up to 250 YouTube video URLs or IDs in one run. Nothing is truncated: a list above 250 is refused before any work and nothing is charged. One result, one charge, per delivered transcript; videos without captions cost nothing.

## `targetLanguage` (type: `string`):

ISO 639-1 code of the captions you want. Manual captions in that language first, then auto-generated. For a fallback order use the Language priority list below instead.

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

Several ISO 639-1 codes in order, e.g. \["es","en"]: the first language the video has captions in wins. When set, this replaces Language.

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

any = manual captions first, then auto-generated. manual = only captions a person uploaded. auto = only YouTube's auto-generated captions.

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

Add srt and/or vtt subtitle text to every result, at no extra charge. Plain text and timestamped segments are always included.

## `listOnly` (type: `boolean`):

Return each video's available caption languages and video facts without fetching a transcript. Nothing is written to the dataset and nothing is charged; read the OUTPUT record.

## `includeMetadata` (type: `boolean`):

Title, channel, duration, view count, description, keywords and thumbnail on every result. Free: they come with the same request that lists the captions.

## Actor input object example

```json
{
  "videoUrl": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "targetLanguage": "en",
  "captionType": "any",
  "outputFormats": [],
  "listOnly": false,
  "includeMetadata": true
}
```

# Actor output Schema

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

All delivered transcripts as JSON: videoId, url, title, channel, durationSeconds, viewCount, language, captionType, availableLanguages, text, data, and srt/vtt when requested.

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

No description

## `output` (type: `string`):

For one video: the transcript item. For a batch: requested, delivered, deliveredVideoIds, failed. For listOnly: each video's facts and caption languages.

# 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 = {
    "videoUrl": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
    "targetLanguage": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("myworkingmemory/wicked-youtube-transcript-scraper-api").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 = {
    "videoUrl": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
    "targetLanguage": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("myworkingmemory/wicked-youtube-transcript-scraper-api").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 '{
  "videoUrl": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "targetLanguage": "en"
}' |
apify call myworkingmemory/wicked-youtube-transcript-scraper-api --silent --output-dataset

```

## MCP server setup

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

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/ZE76LtNoQmus94Bg5/builds/nVb3UIwCCOaOAdR9B/openapi.json
